1.原理
LED只有完全亮和完全灭两种状态,怎么实现控制亮度大小呢?
通过PWM波形可以实现,让LED不断点亮、熄灭、点亮、熄灭,当点亮熄灭的频率足够大时,人眼看LED就不会闪烁了,而是呈现出一个中等亮度。当我们调控这个点亮和熄灭的时间比例时,就能让LED呈现出不同的亮度级别。
对于电机调速,我们以一个很快的频率,给电机通电、断电、通电、断电,那么电机的速度就能维持在一个中等速度。
PWM适用于惯性系统。使用PWM波形,就可以在数字系统等效输出模拟量,实现LED控制亮度、电机控速等功能了。
红线为CCR,黄线为ARR,PSC为预分频器的值。
2.应用
- PWM驱动LED呼吸灯
第一步:RCC开启时钟,打开TIM外设和GPIO外设时钟。
第二步:配置时基单元。
第三步:配置输出比较单元,TIM_OC1Init()包括CCR的值、输出比较模式、极性选择、输出使能等参数。
第四步:配置GPIO,把PWM对应的GPIO口,初始化为复用推挽输出。
第五步:运行控制,启动计数器。
在while()中不断改变CCR的值,使PWM的占空比不断变化,实现呼吸灯的功能。
- PWM驱动舵机
使用的端口是PA1口的通道2,GPIO初始化改下,TIM_OC1Init()变成TIM_OC2Init(),使用TIM_SetCompare2()。对于同一个定时器的不同通道输出的PWM,频率相等,因为不同通道是共用一个计数器,占空比由各自的CCR决定,相位同步。
CCR的值,即PWM的占空比决定了舵机的角度。
- PWM驱动直流电机
使用的端口是PA2口的通道3,GPIO初始化改下,TIM_OC3Init(),使用TIM_SetCompare3()。 除此之外,还加了控制电机方向的两个引脚PA4,PA5。如果电机噪声大,可以加大PWM的频率(超过人耳听到的范围)。这里的电机转速还是与CCR有关。
3.补充知识
- 输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。
- 每个高级定时器和通用定时器都拥有4个输出比较通道。
- 高级定时器的前3个通道额外拥有死区生成和互补输出的功能。
PWM模式1 | 向上计数:CNT<CCR时,REF置有效电平,CNT≥CCR时,REF置无效电平 向下计数:CNT>CCR时,REF置无效电平,CNT≤CCR时,REF置有效电平 |
PWM模式2 | 向上计数:CNT<CCR时,REF置无效电平,CNT≥CCR时,REF置有效电平 向下计数:CNT>CCR时,REF置有效电平,CNT≤CCR时,REF置无效电平 |
OC(Output Compare)输出比较,IC(Input Capture)输入捕获,CC(Capture Compare)输入捕获和输出比较的单元
互补输出端口切换上下管导通状态时,上管关断的瞬间,下管立即就打开,可能因为器件的不理想,上管还没完全关断,下管已经导通,出现了短暂的上下管同时导通情况,这会导致功率损耗,引起器件发热。死区生成电路可以防止这种情况,它会在上管关闭的时候,延迟一小段时间,再导通下管,下管关闭的时候,延迟一小段时间,再导通上管。
PWM输出为什么要用复用推挽输出呢?因为对于普通的开漏/推挽输出,引脚的控制权来自于输出数据寄存器。如果使用定时器控制引脚,需要使用复用开漏/推挽输出模式,在这里输出数据寄存器被断开,输出控制权转移给片上外设,这里片上外设引脚连接的是TIM2的CH1通道。
引脚重映射
TIM2的CH1可以从PA0挪到PA15引脚,需要使用AFIO。要使用AFIO,需要开启AFIO的时钟,用到GPIO_PinRemapConfig(),引脚重映射配置,可选择部分重映射或者完全重映射。在C8T6中,PA15默认是JTDI端口,所以如果想让它作为普通的GPIO或者复用定时器的通道,那还需要先关闭调试端口的复用,使用GPIO_PinRemapConfig()。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//开启AFIO的时钟,重映射必须先开启AFIO的时钟
GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
//将TIM2的引脚部分重映射,具体的映射方案需查看参考手册
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);