我试图以256(0-255)个不同的亮度控制我的LED。我的控制器设置为80mhz并在rtos上运行。我将时钟模块设置为每隔5微秒中断一次,例如亮度。领导是暗淡的,但我不确定它是否正确完成了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);
}
}
}
答案 0 :(得分:3)
对于80 MHz处理器来说,5微秒的中断是一个很高的要求,并且几乎没有时间用于其他工作,如果你没有做其他工作,你根本不需要使用中断 - 你可以简单地轮询时钟计数器;然后,仍然会有很多处理器抛出一个相当简单的任务 - 而RTOS也是过度杀伤。
执行任务的更好方法是使用定时器的PWM(脉冲宽度调制)功能。然后,您将能够以零软件开销精确控制亮度;让处理器做更多有趣的事情。
使用PWM,如果LED控制完全可以,则可以使用性能更低的处理器进行管理。
如果必须使用中断/ GPIO(例如,您的定时器不支持PWM生成或LED未连接到具有PWM功能的引脚),那么以递增方式设置定时器会更有效。因此,例如对于标记:空间为150:105,您可以将定时器设置为150 * 5us(9.6ms),在中断时切换GPIO,然后将定时器设置为105 * 5us(6.72ms)。
您的解决方案的一个主要问题是中断处理程序没有返回 - 中断必须运行完成并且尽可能短,并且最好在执行时间内确定。
不使用硬件PWM,基于代码片段的以下内容可能更接近您的需求:
{{1}}
答案 1 :(得分:0)
在克利福德的敦促下,我正在详细阐述减少软件调光负载的替代策略,因为每400个时钟周期的服务中断可能会很困难。当然,首选的解决方案是使用硬件脉冲宽度调制。
一种选择是仅在PWM侧面设置中断。不幸的是,这种策略往往会随着时间的推移引入种族和漂移,同时进行调整并且很难扩展到多个渠道。
替代方案我们可以从脉冲宽度切换到Δ-Σ调制。这个概念背后有一些理论,但在这种情况下,它可以归结为尽可能快地切换引脚和引脚,同时保持与调光水平成比例的平均导通时间。因此,可以降低中断频率,而不会将整体开关频率降低到可见水平。
以下是一个示例实现:
// 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以防止可见的闪烁。
哦,如果在您的申请中担心转换损失,请注意。