- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
PWM介面技術
「脉冲宽度调变(Pulse Width Modulation;PWM)」允许处理器的数字输出信号可以控制或驱动模拟电路,可应用于测量、通信、功率控制、信号转换等。
模拟电路
一个模拟信号具有连续变化的值,它的最小时间和最小振幅是无限的(亦即,解析度是无限小的)。一个9伏特的电池是一种模拟装置,它的输出电压不一定都是9V,而是会随着时间变化的,它的值可能是任何的实数值。同理,从电池中流出的电流量不是限定在一定范围里的可能值。模拟信号与数字信号的区别是很清楚的,因为数字信号总是从「预先决定的(predetermined)」有限的可能值之集合中选出一个值来,例如:{0V, 5V}集合。
模拟电压和电流可以直接用来控制装置,譬如:汽车音响的声音。在一台简单的模拟收音机中,频率选择钮是连接到一个可变电阻上。当旋转选择钮时,电阻值会上升或下降,因此电阻电流也会增加或降低,而驱动扬声器的电流量也会改变,最后使它的声音增加或降低。一个模拟电路就像收音机一样,它的输出值和它的输入值是呈线性的正比关系。
直觉上,我们知道模拟控制并不经济,有时也不实用。模拟电路的电压或电流常会随着时间飘移,所以很难微调。可以解决这种问题的精准的模拟电路之体积可能非常大、非常重,而且很贵—旧型的立体音响就是属于这一类型。模拟电路也很耗电,很容易发热。模拟电路对噪音效应也很敏感。由于它具有无限小的解析度,所以在模拟电路中的任何扰动或噪音必然会改变它的电流值。
数字控制
以数字信号来控制模拟电路,可以使系统成本和功率损耗大幅地减少。而且,由于多数的微控制器和DSP已经内建了PWM控制器,因此很容易实现。简言之,PWM是一种能将模拟信号准位编成数字码的技术。透过高解析度的计数器,将一个方波的工作周期调变,藉此,将特定的模拟信号准位编码。PWM信号仍然是数字的,因为在任何时候,直流供电不是开启的就是关闭的。藉由连续的开启和关闭脉冲,将电压或电流供应给类比负载。在负载上有直流供电时称为「开启时间(on-time)」,没有时称为「关闭时间(off-time)」。假设频宽足够,任何一个类比值都可以利用PWM来编码。
图一是3个不同的PWM信号。它们分别在10%、50%和90%的工作周期上输出。这3种PWM信号可以分别对3种不同的模拟号值编码,这些模拟信号值分别是该信号最大值的10%、50%和90%。例如:假设供电压是9V,则输出工作周期为10%的PWM信号就代表0.9V的模拟信号值。
图一:不同工作周期的PWM信号
图二是一个简单的电路,可以被PWM信号驱动。在此图中,9V的电池供电给白热灯泡使用。如果将开关接合50 ms,在此时间内,灯泡将会得到9V的电压。如果在下一个50 ms,将开关分离,灯泡将会得到0V。如果在一秒钟内,重复这样的步骤10次,灯泡将会像连接到4.5V(9V的1/2)的电池一样发光。因此,PWM讯号的输出工作周期是50%,调变频率是10Hz。
图二:一个简单的PWM电路
大多数的负载、电感和电容需要比10Hz还要高很多的调变频率。如果增加开关开启和关闭的时间各成为5秒,则工作周期仍然是50%,但是在灯泡开启时,它的亮度会增加。为了让灯泡只能得到4.5V,工作週期时间必须小于负载对开关切换的反应时间。为了得到微光(dimmer)的效果,必须增加调变的频率大小。上述原理也适用于其它的PWM应用。一般的调变频率范围是从1 kHz至200 kHz。
硬件控制器
许多种微控制器和处理器都内建有PWM单元。例如:PIC16C67、LPC2000……等。PIC16C67内部具有两个PWM单元,每一个单元都可以选择开启时间和一个周期时间(period)的长度。工作週期是开启时间和一个周期时间的比率。调频频率是一个周期时间的倒数。要开启一个PWM作业,韧体必须执行下列的工作:
• 设定位于晶片内部的计时器或计数器的周期时间,它们可以提供调变的方波。
• 设定PWM控制暂存器的开启时间。
• 设定PWM输出的方向,此输出接脚可能是GPIO的一个脚位。
• 开启计时器。
• 启动PWM控制器。
虽然不同的PWM控制器具有不同的编程功能和技术细节,但是大体而言,它们的基本原理是相同的。
通信和控制
PWM的一个优点是:从处理器到控制器的信号都是数位的;因此,不需要数字模拟转换(DAC)。由于信号都是数字的,所以噪音效应可以降低。噪音只有在唯一一种情况下才会影响数字信号:噪音强度大到足以将逻辑1改变成逻辑0,反之亦然。 利用PWM信号来控制模拟电路的另一个好处是它可以增加抗噪音的能力,这也是为何有时可以使用PWM来通信的主要原因。从一个模拟信号切换至PWM可以大幅增加通信通道的长度。一个适当的RC或LC网路能移除调变的高频方波,并将信号还原成类比形式。
PWM的应用非常多。一个具体的例子是:利用PWM来控制剎车器(brake)。简言之,剎车器就是将车轴仅仅夹住。在许多剎车器中,抓力或制动力的大小是由一个类比输入信号控制。施加在剎车器上的电压或电流越大,抓力就越大。
PWM控制器的输出可以连接至一个开关,此开关位于电源和剎车器之间。为了产生更多的制动力,软件只需要增加PWM输出的工作周期。如果需要特定的剎车力量,就必须求出工作周期和剎车力量之间的数学关系。求得的公式或查看表(lookup table)需要依照工作温度、剎车器的磨损情况…等因素做微调。若要将压力施加在剎车器上,譬如:100 psi,软件必须反向求出工作週期。然后,据此改变PWM信号的工作週期,剎车器就会依此做出反应。如果此系统有一个感测器,则还可以藉由封闭回路控制电路来微调工作週期,直到获得期望的正确动力。
SoC处理器的PWM
一般的SoC处理器也可以内建PWM控制器,这是利用SoC内部的标准计时器来产生PWM信号。透过符合暂存器(match register)可以选择特定的应用项目。例如:7个符合暂存器支援6个单边控制或3个双边控制或两者混合的PWM输出信号。符合暂存器也支援下列功能:
˙特定的中断产生时,继续计时。
˙特定的中断产生时,停止计时。
˙特定的中断产生时,重置计时器。
每个符合暂存器的外部输出信号具有下列的功能:
˙符合时,输出低值。
˙符合时,输出高值。
˙符合时,切换输出值(原是低值变高值,原是高值变低值)。
˙符合时,不做任何事。
PWM控制器具有下列的功能:
˙脉冲周期和宽度(工作週期)是由计时器的计时数目设定。因此,解析度和重复率之间的取舍可以很有弹性。所有的PWM输出信号的重复率是相同的。
˙双边控制的PWM输出可以被设定为正的脉冲波缘,或负的脉冲波缘。
˙符合暂存器的更新是跟随脉冲输出讯号同步完成的,以避免产生错误的脉冲。软件必须先释出(release)新的符合值,之后它们才会生效。
˙如果PWM模式不有启动,它可以当成一个标准的计时器。
˙32-bit的计时器/计数器具有一个可程式化的32-bit预分频器(prescaler)。
˙具有数个32-bit的撷取通道,当一个输入信号做瞬间转换时,这些通道能够撷取计时值。一个撷取事件也会产生一个中断。
PWM建立在标准的计时器区块上,并继承了计时器的所有特性。计时器是用来计算週边时脉的週期数,并可以产生中断;当达到指定的时间值时(藉由符合暂存器组的协助),系统会执行特殊的工作。PWM控制器的功能和计时器类似,并且以符合暂存器的事件为基础。两个符合暂存器能够用来提供一个单边控制的PWM输出。其中,一个符合暂存器控制PWM周期率,当符合时,将计数器重置;另一个符合暂存器控制PWM的边缘位置。额外的单边控制的PWM输出只需要一个符合暂存器即可,因为所有的PWM输出信号的重复率(周期率)都是相同的。多个单边控制的PWM输出在每一个PWM周期的起始位置(当符合暂存器符合时),都具有一个上升缘。
三个符合暂存器能够用来提供一个双边控制的PWM输出。其中,一个符合暂存器控制PWM周期率。其它符合暂存器控制PWM的两个边缘位置。额外的双边控制的PWM输出只需要两个符合暂存器即可,因为所有的PWM输出信号的重复率都是相同的。
图三:PWM内部的部份架构
附图三中的PWMSELn位元可以用来决定使用单边或双边控制的PWM输出。附图四是一个PWM週期和三个PWM输出波形的关系范例。附表一是相对于不同的PWM输出,不同符合暂存器之选择。附图四的构成条件如下:
˙将计时器设定为PWM模式。
˙当符合事件发生时(计数值等于100),符合暂存器0会将计时器/计数器重置。
˙将控制位元PWMSEL2和PWMSEL4设为1。亦即,PWM2输出和PWM4输出是选择双边控制的。
˙每个符合暂存器的值如下:
MR0=100(PWM的周期率)
MR1= 41,MR2= 78(PWM2的输出)
MR3= 53,MR4= 27(PWM4的输出)
MR5= 65(PWM5的输出)
将每个符合暂存器的值一一验证PWM的输出波形,可以发现:除了PWM5的输出以外,PWM2和PWM4的输出是属于双边控制的。从附表一可知:双边控制的PWM2输出信号的上升缘(建立)必须选择符合暂存器1,且其下降缘(重置)必须选择符合暂存器2。因此,MR1的值小于MR2的值。而双边控制的PWM4的输出信号的上升缘(建立)必须选择符合暂存器3,且其下降缘(重置)必须选择符合暂存器4。但是因为PWM4的输出信号的初始值是正值,所以它必须先从高值降至低值(重置),再从低值升至高值(建立),于是MR3的值大于MR4的值。这正是PWM2和PWM4波形的最大差别。
图四:PWM周期和PWM输出波形的关系
表一:相对于不同的PWM输出,不同符合暂存器之选择。
PWM输出的规则
对单边控制的PWM输出而言,具有下列两项规则:
1. 在PWM周期开始时,所有的单边控制的PWM输出都是上升的,除非它们的符合值等于0(例如:MR5= 0)。
2. 当达到符合值时,每一个PWM输出会降为低值。如果没有符合----亦即,符合值大于PWM週期率,则PWM输出会持续保持高值。
对双边控制的PWM输出而言,当一个新周期快要开始时,下列五项规则可以用来决定下一个PWM输出值:
1. 下一个PWM週期的符合值可以在一个PWM週期的结束地方使用。但是,第3项例外。
2. 一个符合值等于0或等于目前的PWM周期率(符合暂存器的值),它们都具有相同的效果。但是,第3项例外。例如:在PWM周期的开始处请求一个下降缘,是等同于在PWM周期的结束处请求一个下降缘。
3. 当符合值正在改变时,如果一个旧的符合值等于PWM周期率,并且新的符合值不等于0,也不等于PWM週期率,则此旧的符合值将会被再次使用,而且旧的符合值不等于0。
4. 如果同时要求建立和清除(重置)PWM输出,则清除优先。当建立和清除的符合值相同;或建立、清除之一的符合值等于0,而另一个的符合值等于PWM周期率,这时就会发生这种情况。
5. 如果符合值比PWM周期率还要大,则不会有符合事件发生,而且,此符合通道(符合暂存器)对PWM输出毫无作用。这表示PWM输出将一直保持原来的状态,允许PWM输出一直保持低值、高值或不变。
PWM暂存器组
下列是PWM的暂存器:
1. 中断暂存器(PWMIR):写入此暂存器可以清除中断。读取此暂存器可以判定中断来源。
2. 计时器控制暂存器(PWMTCR):可以控制计时器/计数器的功能。它可以使计时器/计数器关闭或重置。
3. 计时器/计数器(PWMTC):周边时脉(pclk)的每预先分频暂存器的值+1(= PR+1)个週期,32位元的TC暂存器会递增。TC是透过TCR控制。
4. 预先分频暂存器(PWMPR):储存一个预先设定的值。其余同PWMTC的说明。
5. 预先分频计数器(PWMPC):32位元的PC是一个计数器,它的值会递增,直到等于储存于PR中的值。当PC的值等于PR的值时,TC会递增。
6. 符合控制暂存器(PWMMCR):当有一个符合暂存器的值等于TC的值时,由此暂存器决定要执行何种行动,譬如:产生中断、使TC重置、或使TC和PC停止。
7. 符合暂存器0(PWMMR0):透过MCR可以控制MR0。当MR0的值等于TC时,MCR可以使TC重置,或使TC和PC停止,或产生一个中断。此外,当MR0的值等于TC时,所有单边控制的PWM输出信号会上升(被建立);如果PWM1输出是双边控制的,则此信号波形也会上升。
8. 符合暂存器n(PWMMRn;n > 0):透过MCR可以控制MRn。当MRn的值等于TC时,MCR可以使TC重置,或使TC和PC停止,或产生一个中断。此外,当MRn的值等于TC的值时,PWMn输出讯号会下降(被清除),而且,不管PWMn是属于单边控制的或双边控制的信号;如果PWMn+1输出是双边控制的,则此信号波形会上升。
9. PWM控制暂存器(PWMPCR):启动PWM输出,并选择PWM的通道(信号)类型----是属于单边控制的或双边控制的。
10. PWM锁定暂存器(PWMLER):用来控制符合暂存器的更新。当计时器处于PWM模式,软体将数值写入符合暂存器内时,此值是位于一个遮蔽(shadow)暂存器中。当MR0事件发生时(MR0的值等于TC的值),遮蔽暂存器的内容会被传送至真正的符合暂存器中,如果锁定暂存器的相对应位元有被设为1的话。此时,新写入的值才会生效,并决定下一个PWM週期的方向。一旦新的数值开始被传送,锁定暂存器的所有位元值将会被自动清除。直到锁定暂存器的相对应位元被设为1,而且有一个MR0事件发生,此时任何写入符合暂存器的值对PWM作业而言是无效的。例如:假设PWM2输出是双边控制的信号,并且正在输出中,则能够改变时序的典型的事件序列如下所示:
i. 写入新值至MR1中。
ii. 写入新值至MR2中。
iii. 设定锁定暂存器的位元1和2为1。
iv. 当计时器下次重置时(有一个MR0事件发生),上述的新值才会生效。
MR1和MR2的写入顺序并不重要,因为在设定锁定暂存器之前,这些值是没有用的。锁定暂存器的位元1和2之设定,可以使这两个值同时生效。若只更改一个符合暂存器的值,其方法与前述者相同。锁定暂存器的位元0和1的功能如附表二的说明。其余位元的功能也和它们一样。
表二:PWM锁定暂存器的位元0和1的功能
韧体实例
下面是一个PWM韧体程式范例。它使用PWM2输出,周边时脉是5MHz。
在开启PWM之前,设定各个相关的脚位:
REG(PINSEL0)=0x800A8005; /* 设定p0.7, p0.8, p0.9分别为PWM2, PWM4, PWM6*/
REG(IO0DIR)|=0x00000380; // 设定 PWM2, PWM4,PWM6 为输出
现在开启PWM:
REG(PWMPR)=0x0000; /*不使用预先分频,一个CPU时脉就是一个PWM时脉*/
REG(PWMMCR)=0x0002; /*重置MR0的TC */
REG(PWMPCR)= 0x5400; /* 启动PWM2,4,6, 单边控制 */
REG(PWMMR0)=0x0400; // 建立PWM周期
REG(PWMTCR)=0x000A; // 重置TC计数器
REG(PWMMR2) = 0x0050; // 建立初始的PWM工作周期
REG(PWMLER) |= 0x04; // 使用位元2的锁定功能
REG(PWMMR4) = 0x0100; // 建立初始的PWM工作周期
REG(PWMLER) |= 0x10; // 使用位元4的锁定功能
REG(PWMMR6) = 0x0150; // 建立初始的PWM工作周期
REG(PWMLER) |= 0x40; // 使用位元6的锁定功能
REG(PWMTCR) = 0x00000009; // 启动TC
上述程式看似没问题,可是p0.7 (PWM2)却一直保持高值。到底哪边出错了呢?
这是因为TC的初始值没有设为0。必须在REG(PWMTCR) = 0x00000009后面加上REG(PWMTC) = 0x0。
PWM经济、节省空间和抗噪音,只要有通信或控制用途的好点子,几乎都可以利用它来实现。