对于您的应用程序所需的分辨率和整体占空比可能会有所不同。 简单的显示需要很少的精度控制(和有时一点点闪烁的是不是世界的尽头),更先进的显示的控制能力的亮度可能是至关重要的的(认为使用一个RGB混合颜色的问题,例如LED )。 权衡是简单的,更多的控制和精度要求越来越多的微控制器资源。 在这篇文章中,我们将重点放在一个例子提供了一个超过20000微秒,占空比(或50HZ与步骤5%给我们20个级别的亮度)1000微秒的决议。 此级别的控制和准确性,适用于多种用途。
定时中断 执行PWM使用中断,我们必须调用一次,1000微秒的中断,并决定如果LED应打开或关闭。 要做到这一点,我们必须建立一个计时器上的微控制器,它调用当它到期的中断。
在这个例子中,我们将采取Microchip的PIC18F4550单片机作为例子,运行在48MHz的。 48MHz的单片机的时钟每秒4800万次一个“剔”号。 这被称为“FOSC”(振荡频率)。 一个PIC18F4550需要4个时钟的刻度来处理一个单一的指令。 这意味着我们可以使用微控制器处理的时间的最小金额是一季度的时钟速率,即4800万/ 4 = 1200万(这也是为FOSC / 4),如果有在第二个百万微秒,这意味着我们大约每隔0.0834微秒(12 MIPS(每秒百万指令))执行的命令。 虽然这不是十分正确的,因为在PWM计算产生一个脉冲,我们需要两个命令(打开和关闭),这意味着最低的0.167微秒的周期时间(这有效地限制了我们可以生产的软件到6MHz频率最高的,虽然这是不是一个很现实的的最大值)。
如果FOSC / 4率是1200万,这意味着每12个处理器周期为1微秒的时间传递。 这意味着,1000微秒相当于12,000个处理器周期。 这是很重要的,因为1:1的预分PIC的定时器更新一次处理器周期(虽然这被称为1:1的预分频,它的真正含义没有在所有的预分频)。 定时器的预分频器减慢率在计时器的计数器更新,用1:2的预分频更新一次,每2个处理器周期与预分频比为1:4,它更新一次,每4处理器周期等。
要使用一个8位定时器(如果你喜欢,你也可以使用一个16位定时器)定时器可以衡量的最长期限是256“罪状”(0-255)。 因此,我们必须选择一个预分频值,这使我们能够在小于256的计时器滴答12,000个处理器周期。 如果我们用1:64的预分频器,我们需要187.5计时器刻度来衡量千微秒:
12每微秒的处理器周期,所以12 * 1000 = 12000每1,000微秒的处理器周期:12,000次/ 64(预分频)= 187.5计时器“蜱”
既然我们不能指望一个“一半”我们只是一轮数字下降到最接近的整数(这意味着导致PWM不会完全准确,但LED的亮度控制的目的,这是非常关键的)。 更高的分频值,我们使用,不准确的时机变得。 这可以通过使用一个16位定时器,让我们来算蜱得多,因此,使用较低的预分频值予以纠正。
对于一个PIC18F4550,这将导致类似以下摘录其中Timer0模块的配置,启用和设置生成一个低优先级中断的代码:
/ /使能中断优先 IPEN = 1 / /设置定时器 TMR0IP = 0;
/ /设置定时器0中断为低优先级 TMR0IF = 0;
/ /清除定时器中断标志 TMR0L = 255 - 187;
/ /复位定时器计数器 T0CON = 0b11000101;
/ /定时器,8位和1:64预分频器 TMR0IE = 1
/ /允许Timer0中断/ /使能中断 GIEH位= 1;
/ /全局使能所有高优先级中断GIEL = 1;
/ /全局使所有低优先级中断
一旦定时器配置和运行,我们需要一些中断的代码,以决定如果LED,应中断或关闭。 既然我们有20个可能的亮度水平(因此20号决议的步骤,在我们的PWM生成),我们可以简单地用一个计数器计数从0-19更新一次中断。 如果用一个数字从0-19表示LED的亮度是我们根本检查,如果PWM计数器是高于或低于低亮度数量,如果LED应打开或关闭。
/ /全局为PWM 无符号字符 pwmCounter = 0; 无符号字符 ledBrightness = 0; / /低优先级中断程序 无效中断LOW_PRIORITY lpHandler( 无效 ) { / /这个定时器中断? 如果 (TMR0IF) { (ledBrightness> pwmCounter) LED0 = 1; 其他 LED0 = 0; pwmCounter + +; (pwmCounter> 19) pwmCounter = 0; / /准备下一次中断 TMR0L = 255 - 187; / /复位定时器计数器 TMR0IF = 0; / /清除定时器中断标志 } }
褪色的LED 既然我们知道的TIMER0定时器周期的持续时间,我们也可以用它来提供对LED的淡入淡出效果。 要做到这一点,我们必须存储两个LED的亮度,一个变量的值存储实际的显示亮度和其他存储目标亮度的LED。 由于我们只希望褪色关闭(你可以适应这一点很容易,同时支持淡入和淡出关闭),如果目标的亮度比实际亮度高,我们立即将实际亮度相同的水平。
然而,对于衰落过,我们要减一次,直到它的实际亮度水平一步等于目标的亮度。 只有20的亮度巨大,我们不能简单减去每个中断通话的水平以来的中断调用是过快的到是的观者(20调用将只消耗20000微秒过快看到)认为褪色。
相反,我们保持另一个计数器计数中断调用应该发生在递减实际褪色水平之间的。 因为我们知道中断被称为每千微秒,这是非常直截了当的工作,我们应该算,以获得所需的的衰落率多少中断。 例如,如果我们想要从亮度级别为19 0的淡出,以0.5秒,我们简单地除以1000微秒的中断时间,然后由若干层次所需的时间(微秒)。 因此0.5秒(或50万微秒)= 500,000 / 1,000 = 500 / 20 = 25。 这表现在以下代码摘录:
/ /全局 低优先级中断程序 无效中断LOW_PRIORITY lpHandler( 无效 ){
/ /这是Timer0的中断?(TMR0IF){
/ /执行PWM亮度 执行衰落 准备下一次中断 TMR0L = 255 - 187;
/ /复位定时器计数器 TMR0IF = 0;
/ /清除定时器中断标志 }
结论 虽然这是完全可能得到PWM控制工作的LED使用纯粹的猜测工作,计算所需的最佳值,可以更有效地使用可用的处理器资源,让您做更多与微控制器和/或控制更多的LED同时从同一芯片上。 用于LED显示的相同的技术也可以用来控制电机,模拟仪表显示,白炽灯泡,等
(, 下载次数: 70)