stm32PWM驱动应用

1.原理

       LED只有完全亮和完全灭两种状态,怎么实现控制亮度大小呢?

       通过PWM波形可以实现,让LED不断点亮、熄灭、点亮、熄灭,当点亮熄灭的频率足够大时,人眼看LED就不会闪烁了,而是呈现出一个中等亮度。当我们调控这个点亮和熄灭的时间比例时,就能让LED呈现出不同的亮度级别。

       对于电机调速,我们以一个很快的频率,给电机通电、断电、通电、断电,那么电机的速度就能维持在一个中等速度。

       PWM适用于惯性系统。使用PWM波形,就可以在数字系统等效输出模拟量,实现LED控制亮度、电机控速等功能了。

 红线为CCR,黄线为ARR,PSC为预分频器的值。

PWM 频率:   Freq = CK_PSC / (PSC + 1) / (ARR + 1)
PWM 占空比:   Duty = CCR / (ARR + 1)
PWM 分辨率:  Reso = 1 / (ARR + 1)

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.补充知识

  • 输出比较可以通过比较CNTCCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。
  • 每个高级定时器和通用定时器都拥有4个输出比较通道。
  • 高级定时器的前3个通道额外拥有死区生成和互补输出的功能。

PWM模式1

向上计数:CNT<CCR时,REF置有效电平,CNTCCR时,REF置无效电平

向下计数:CNT>CCR时,REF置无效电平,CNTCCR时,REF置有效电平

PWM模式2

向上计数:CNT<CCR时,REF置无效电平,CNTCCR时,REF置有效电平

向下计数:CNT>CCR时,REF置有效电平,CNTCCR时,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);

  • 25
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
nrf51822并没有PWM模块,但是如果巧妙的结合PPI模块,并加上一个定时器中断就可以轻松的实现了PWM,思路是这样的: 定时器使用三个比较器 cc0、cc1和cc2,当三个比较器任何一产生比较事件的时候都会通过PPI去翻转GPIO的引脚,在初始化的时候这样设置这三个比较器: NRF_TIMER2->CC[0] = MAX_SAMPLE_LEVELS + next_sample_get(); NRF_TIMER2->CC[1] = MAX_SAMPLE_LEVELS; // CC2 will be set on the first CC1 interrupt. NRF_TIMER2->CC[2] = 0; 这是初始化的配置,到这里会有一个思考,这样的话计数器技术到cc0的时候依然会继续的往下计数,那这样的话他的再溢出的值就将回到cc2的时候也就是归零的时候,那这样的波形就分为了三段了,这不是我们所需要的,那这样要实现PWM就要把cc2的比较值往后挪,让他超过cc0,并且cc2到之前的一个比较值是固定的,这样就需要从新设置cc2的值,还有一个办法就是当计数器到cc0的时候请求中断重置计数器,但是这样做有一个问题就是进入中断是需要时间的,而当计数器到达cc0的时候就需要重置,同时计数器的下一个值就是cc2,这样就会造成冲突,所以我们使用了第一种方案。 具体实现是这样的,使能cc1比较中断,在第一次中断中重新设置cc1,让他的值变成了两倍,同时从新设置cc2,让他的值变成了cc1+N,N就是占空比参数,在第二次中断中,也是从新设置cc1,但是和上一次中断不同的是这时候设置的是cc0,而不是cc2 这样造成的计数器溢出值是这样的:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值