热度 27
2013-11-17 00:02
2476 次阅读|
5 个评论
虽然网上关于PWM的文章很多,我也看了很多,但是看完之后总感觉似懂非懂,也都不是我想要的。特别是在用msOS做测温仪校准台的时候,我需要用到通过调节PWM的占空比来控制功率输出。因为开始没有用过PWM,于是就在网上和书本上找了一些资料学习,并且根据学习的理解开始控制功率输出。虽然能够控制了,但是精度却达不到我想要的。于是我开始根据印象和测试实验的经验来调节arr和psc的值,来达到我的要求。虽然结果是达到了,但是当时我对PWM的认识还比较浅,整个感觉是比较飘的。 后来另一个同事在用PWM的时候通过实时改变待装入捕获比较寄存器的脉冲值来改变占空比,出现了波形失真。针对这一情况,凤舞天让我们在团队内部讨论,并且解决这一问题。这个时候,我忽然意识到,在做一个产品时,对相关知识点不能完全明白的掌握,是很麻烦也是很危险的。幸运的是,这个同事是在测试中出现了问题,那么问题就会在产品出去之前把问题解决,这样就不会让问题出现在产品的应用当中,也不会对产品的质量和公司的产品品牌造成影响。而我的PWM一直都没有出现过波形失真,那以后会不会在应用中也出现波形失真,这个是个未知数。为了解决同事的这个问题,同时确定我的PWM没有问题,我再一次沉下心来学习研究PWM。 现在来分享一下我的学习理解: 首先是计数器寄存器(TIMx_CR1):计数器寄存器是一个16位的寄存器,其中: 1.ARPE位是自动重装载允许位。 2.DIR位是控制计数方式位。 3.URS位是控制事件更新请求源。 4.UDIS位禁止事件更新。 5.CEN使能计数器。 其次是预分频器(TIMx_PSC):预分频器可以将计数器的时钟频率按1到65536之间的任意值分频。在预分频寄存器对主频率分频后,提供给计数器,作为计数器的时钟。它是基于一个在TIMx_PSC寄存器中的16位寄存器控制的16位计数器。因为这个控制寄存器带有缓冲器,它能够在工作时被改变。但是预分频器的新参数会在下一次更新事件到来时被调用。例如,预分频器的参数从1变到2时,计数器的时序图应该是: 再次是自动重装载寄存器(TIMx_ARR):自动重装载寄存器也是一个16位的寄存器。实际上自动重装载寄存器实际上对应着2个寄存器。一个是程序员可以直接操作的寄存器,一个是程序员看不到的影子寄存器。实际上真正起作用的开始影子寄存器。而这两个寄存器是如何配合工作的,则需要TIMx_CR1寄存器的APRE位设置: 当APRE=0时,预装载寄存器的参数实时的传送给到影子寄存器,并没有实现预装载的功能; 当APRE=1时,在每一次事件更新时,预装载寄存器的参数才会被传送到影子寄存器。 而PWM的频率是通过预分频参数和自动重装载寄存器的参数确定的。预分频的参数确定了计数器的时钟,自动重装载寄存器的参数确定了在这个时钟频率下的计数次数,即周期。举个例子:如果系统主频率是72M,psc=8,那么,计数器的时钟就是72M/(8+1)=8M;arr=2000,那么PWM会在8M的频率下每次计数2000次之后会进入到下一个计数循环。而PWM的占空比精度于预分频参数有关,预分频参数越小,精度越高;反之就越低。 我们从下面的定时器时钟框图可以看出,事件U更新是在预分频后,捕获比较之前,而CC4I是中断和DMA输出。所以PWM在每一个周期之后会有一个中断,在来了中断之后,才会更新事件,这样就保证了PWM的每个周期都能够正常完成,而不会导致波形失真。(这个也是为什么我的PWM没有出现过失真,而我同事的PWM出现了失真的原因。因为我用到了中断更新事件,而他没有使用中断。) 那么怎么调节PWM的占空比呢? 通过捕获/比较寄存器(TIMx_ CCRx),在TIMx_CR1的APRE位没有选择预装载特性时,写入的值会立即被传送到捕获/比较寄存器中。当TIMx_CR1的APRE位选择了预装载功能特性,只有当更新事件发生时,预装载之才会被传送到捕获/比较寄存器。然后捕获/比较寄存器会拿当前值与计数器TIMx_CNT进行比较,当达到捕获/比较寄存器的值时,PWM的电平会发生一次跳变。 关于PWM的其他基本配置,主要也就是一下几点: 1.计数模式:向上计数(计数器从0计数到自动加载值TIMx_ARR计数器的值);向下计数(计数器从自动装入值TIMx_ARR的值开始向下计数到0);中央对其(计数器从0开始计数到自动加载值TIMx_ARR寄存器-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器下溢事件,然后再从0开始重新计数)。 2.PWM模式: PWM模式1(OCxM=110,在向上计数时,如果TIMx_CNT TIMx_CCR1时为高电平,否则为低电平);PWM模式2(OCxM=111,在向上计数时,如果TIMx_CNT TIMx_CCR1时为低电平,否则为高电平)。 3.要使用PWM必须要开启其相对应的时钟线。