【问题标题】:control led brightness of microcontroller rtos/bios控制微控制器 rtos/bios 的 LED 亮度
【发布时间】:2017-06-06 07:18:18
【问题描述】:

我正在尝试将我的 LED 控制在 256 (0-255) 不同的亮度级别。我的控制器设置为 80mhz 并在 rtos 上运行。我将时钟模块设置为每 5 微秒和亮度中断一次,例如到 150。LED 正在变暗,但我不确定是否真的有 256 个不同的级别是否正确

int counter = 1;
int brightness = 0;


void SetUp(void)
{

SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
GPIOPinTypeGPIOOutput(PORT_4, PIN_1);

Clock_Params clockParams;
Clock_Handle myClock;
Error_Block eb;
Error_init(&eb);
Clock_Params_init(&clockParams);
clockParams.period = 400; // every 5 microseconds
clockParams.startFlag = TRUE;
myClock = Clock_create(myHandler1, 400, &clockParams, &eb);
if (myClock == NULL) {
    System_abort("Clock create failed");
}

}


void myHandler1 (){

brightness = 150;


while(1){
    counter = (++counter) % 256;
    if (counter < brightness){
        GPIOPinWrite(PORT_4, PIN_1, PIN_1);
    }else{
        GPIOPinWrite(PORT_4, PIN_1, 0);
    }
}
}

【问题讨论】:

  • 您不确定它是否正确?你试过了吗?具有无限循环的中断处理程序根本不可能工作!如果计数器是 uint8_t,那么您也不需要 % 256

标签: embedded rtos pwm


【解决方案1】:

5 微秒的中断对于 80 MHz 处理器来说是一个很高的要求,并且几乎没有时间用于其他工作,如果您不做其他工作,则根本不需要使用中断 - 您可以简单地轮询时钟计数器;那么它仍然需要大量的处理器来完成一项相当微不足道的任务 - 而且 RTOS 也太过分了。

执行任务的更好方法是使用定时器的 PWM(脉冲宽度调制)功能。然后,您将能够以零软件开销准确控制亮度;让你的处理器去做更有趣的事情。

如果只用 LED 控制,您可以使用性能低得多的处理器来管理 PWM。

如果您必须使用中断/GPIO(例如,您的定时器不支持 PWM 生成或 LED 未连接到支持 PWM 的引脚),那么增量设置定时器会更有效。例如,对于 150:105 的 mark:space,您可以将定时器设置为 150*5us (9.6ms),在中断切换 GPIO 时,将定时器设置为 105*5us (6.72ms)。

您的解决方案的一个主要问题是中断处理程序不返回 - 中断必须运行完成并且尽可能短,并且最好是确定的执行时间。

在不使用硬件 PWM 的情况下,基于您的代码片段的以下内容可能更接近您的需要:

#define PWM_QUANTA = 400 ; // 5us
static volatile uint8_t brightness = 150 ;
static Clock_Handle myClock ;


void setBrightness( uint8_t br )
{
  brightness = br ;
}

void SetUp(void)
{
  SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
  GPIOPinTypeGPIOOutput(PORT_4, PIN_1);

  Clock_Params clockParams;
  Error_Block eb;
  Error_init(&eb);
  Clock_Params_init(&clockParams);

  clockParams.period = brightness * PWM_QUANTA ;

  clockParams.startFlag = TRUE;
  myClock = Clock_create(myHandler1, 400, &clockParams, &eb);
  if (myClock == NULL)
  {
    System_abort("Clock create failed");
  }
}

void myHandler1(void)
{
  static int pin_state = 1 ;

  // Toggle pin state and timer period
  if( pin_state == 0 )
  {
    pin_sate = 1 ;
    Clock_setPeriod( myClock, brightness * PWM_QUANTA ) ;
  }
  else
  {
    pin_sate = 0 ;
    Clock_setPeriod( myClock, (255 - brightness) * PWM_QUANTA ) ;
  }

  // Set pin state
  GPIOPinWrite(PORT_4, PIN_1, pin_state) ;
}

【讨论】:

  • 如果硬件碰巧缺少合适的 PWM 通道,一个简单的替代方法是使用 delta-sigma 调制,并在保持分辨率的同时降低频率。这归结为增加模块化累加器的亮度,并在发生溢出的中断周期点亮 LED。缺点是可能需要对产生的接近零/全亮度值进行钳位以避免低频切换。
  • @doynax :这应该作为对问题的评论的答案发布;我不确定它是否与此答案的评论相关。
  • 耸耸肩。如果设计的硬件证明不兼容,这是答案中指出的问题的替代策略。可能存在其他问题,因为如果在降低频率且占用 CPU 的情况下,原始解决方案仍应执行调光。此外,发布完整的答案是更多的工作;)
  • @doynax :我很欣赏这一点,但如果您有替代解决方案,您就有替代答案。我的观点是,您的评论与我的回答没有直接关系。此外,我不确定我是否理解您的解决方案;发布答案将允许您详细说明,这将有助于 OP 和社区。​​span>
  • 谢谢你们!真的帮助我更好地理解了整个主题!我是微控制器编程的新手
【解决方案2】:

在 Clifford 的敦促下,我正在详细说明一种替代策略,以减少软件调光的负载,因为每 400 个时钟周期处理一次中断可能会很困难。首选的解决方案当然应该是尽可能使用硬件脉宽调制。

一种选择是仅在 PWM 边沿设置中断。不幸的是,随着时间的推移,这种策略往往会引入比赛和漂移,同时进行调整并且很难扩展到多个渠道。

或者,我们可以从脉冲宽度切换到 delta-sigma 调制。这个概念背后有相当多的理论,但在这种情况下,它归结为尽快打开和关闭引脚,同时保持与调光水平成比例的平均开启时间。因此,中断频率可能会降低,而不会将整体开关频率降至可见水平。

下面是一个示例实现:

// Brightness to display. More than 8-bits are required to handle full 257-step range.
// The resolution also course be increased if desired.
volatile unsigned int brightness = 150;

void Interrupt(void) {
 // Increment the accumulator with the desired brightness
 static uint8_t accum;
 unsigned int addend = brightness;
 accum += addend;
 // Light the LED pin on overflow, relying on native integer wraparound.
 // Consequently higher brightness values translate to keeping the LED lit more often
 GPIOPinWrite(PORT_4, PIN_1, accum < addend);
}

一个限制是开关频率随着距离 50% 亮度的距离而降低。因此,可能需要将最后的 N 步限制为 0 或 256 以防止可见的闪烁。

哦,请注意开关损耗是否是您的应用中的一个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-16
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多