C8051F MCU 应 用 笔 记
AN007 — 用 PCA 实现 16 位 PWM
相关器件
本应用笔记适用于下列器件:
C8051F000、C8051F001、C8051F002、C8051F005、C8051F006、C8051F010、C8051F011和
C8051F012。
引言
脉冲宽度调制(PWM)波形常用于闭环反馈和控制应用,例如:控制加热单元的开关状态以
调节DWDM(波分复用)系统中激光器的温度。在某些应用中,可编程计数器阵列(PCA)的内
建8位PWM方式不能提供任务所需的足够的分辨率。本应用笔记介绍如何用PCA的‘高速输出’方
式和最小的软件开销来产生一个16位分辨率的PWM波形。
背景
图1给出了PWM波形的一个例子。用于闭环控制应用的PWM信号的频率并不重要,只要波形
‘足够快’就可以了,象控制系统的阶跃响应时间就应远远小于PWM信号的周期。信号所携带的
的信息用波形的占空度来编码,占空度是波形为高电平的时间与PWM信号的周期之比。对于一个
PWM实现来说,其输入是一个数值,通常为整数,该数值与所要求的输出波形的占空度成正比。
t H
tP
图1. PWM波形示例
占空比
tH
-----=
tP
实现
在一个基于8051的设计中,有很多方法用于产生PWM波形:软件循环、查询或中断驱动的定
时器等等。本应用笔记中的例子使用可编程计数器阵列(PCA)。相对于任何查询机制(基于软件
或定时器)而言,使用PCA产生PWM可以大大降低所需要的CPU带宽,并可以消除在中断驱动的
基于定时器的设计中因中断延迟不一致而产生的时序抖动。
Silicon Laboratories Inc.
4635 Boston Lane
Austin, TX 78735
Email: mcuinfo@silabs.com
Internet: www.silabs.com
(版权所有)
新华龙电子有限公司
深圳市福田区华强北路现代之窗大厦 A 座 13F C 室(518013)
电话:
电邮:shenzhen@xhl.com.cn
网址:www.xhl.com.cn
0755-83645240 83645242 83645244 83645251
AN007 — 用 PCA 实现 16 位 PWM
PCA 简介
PCA包含一个16位的计数器/定时器和5个捕捉/比较模块,如图2所示。计数器/定时器有一个16
位的计数器/定时器寄存器(PCA0H:PCA0L)、一个用于选择时间基准的方式寄存器(PCA0MD)
和一个包含计数器/定时器运行控制及各模块捕捉/比较标志的控制寄存器(PCA0CN)。每个捕捉/
比较模块有一个用于选择模块工作方式(边沿触发捕捉、软件定时器、高速输出或PWM)的配置
寄存器(PCA0CPMx)和一个16位的捕捉/比较寄存器(PCA0CPHn:PCA0CPLn)。
由于所有的捕捉/比较模块共享一个时间基准,因此它们同步工作,例如在电机控制应用中可
以提供锁相激励波形。另外,由于每个模块有其自己的控制和捕捉/比较寄存器,因此每一个模块
工作上又独立于其它模块,只要任何一个模块的服务程序都不影响共享的时间基准(停止或重新设
置计数器/定时器、改变计数器/定时器的时钟源)。
本应用笔记中的例子将PCA配置为独立工作;每个模块的服务程序只影响该模块的配置寄存器
和 捕 捉 / 比 较 寄 存 器 。 PCA 方 式 寄 存 器 只 设 置 一 次 , 不 再 改 变 , 让 计 数 器 / 定 时 器 寄 存 器
(PCA0H:PCA0L)自由运行。
系统时钟
T0溢出
00
01
/12
/4
10
CPS=11
16位计数器/定时器
捕捉/比较模块 0
捕捉/比较模块 1 捕捉/比较模块 2
捕捉/比较模块 4
捕捉/比较模块 5
交叉开关
端口I/O
图2. PCA原理框图
2
AN007-1.0 DEC00
AN007 — 用 PCA 实现 16 位 PWM
选择 PCA 的时基信号
PCA的时基信号可以是下述四个时钟源之一:SYSCLK/12、SYSCLK/4、定时器0溢出、或出
现在一个外部引脚ECI上的下降沿。图3给出了PCA计数器/定时器的方框图。
在下面的几节中我们将看到,PCA时基信号的选择决定PWM波形的频率。如前所述,PWM波
形的频率通常并不重要,只要‘足够快’就可以了。
一个不很明显的时序选择是:PCA可以按SYSCLK的时钟频率工作。这可以通过选择定时器0
溢出作为PCA时钟源,将定时器0设置为8位自动重装载方式并设重载值为‘0xFF’来实现。
本应用笔记中的所有例子都将PCA配置为用SYSCLK/4作为时钟源。
IDLE
C
F
PCA0MD
C
C
P
P
S
S
0
1
E
C
F
C
I
D
L
SYSCLK/12
SYSCLK/4
定时器0溢出
ECI
00
01
10
11
PCA0CN
C
C
C
C
C
R
F
F
1
2
C
C
F
4
C
C
F
3
C
C
F
0
读PCA0L
瞬象寄存器
去SFR总线
0
1
PCA0H
PCA0L
溢出
去PCA中断系统
图3. PCA计数器/定时器原理框图
CF
去PCA模块
用PCA 实现8 位PWM
我们首先介绍一个能产生8位精度PWM波形的方法。为了叙述的完整性,先介绍PCA的PWM
方式。
在该方式中,捕捉/比较模块被配置为图4所示的PWM方式。出现在CEXn的波形的周期等于256
个PCA时钟周期。该信号的低电平时间等于在模块的捕捉/比较寄存器(PCA0CPLn)的低字节中
所存储的8位数值。这种关系如图5所示。
在主PCA计数器(PCA0L)的低字节发生溢出时,模块的比较寄存器的高字节被拷贝到模块的
比较寄存器的低字节(PCA0CPLn=PCA0CPHn)。通过更新PCA0CPHn就能改变占空度。拷贝过程
保证在输出端不产生毛刺。
输出波形的占空度(用%表示)由下式给出:
AN007-1.0 DEC00 3
AN007 — 用 PCA 实现 16 位 PWM
占空度=
256
−
PCA
CPHn
0
256
×
100
因 为PCA0CPHn 可 以 含 有 一 个0~255 的 数 值 , 所 以 可 编 程 的 最 大 和 最 小 占 空 度 为0.38%
(PCA0CP0H=0xFF)到100% (PCA0CP0H=0x00)。占空度选择的分辨率为:
分辨率
=
1
256
×
100
=
38.0
8位PWM方式的最大优点是不需要CPU的干预就可以输出一个固定占空度的波形。事实上,如
果CIDL位(PCA0MD.7)被设置为‘0’(复位状态),即使CPU处于休眠状态,输出波形也将保持。
改变占空度是通过向PCA0CPHn写入一个8位数来完成。
在本应用笔记最后包含的文件‘PWM8_1.C’提供了一个8位PWM方式的例子。
8位PWM方式的其它注意事项:
1. 可以通过将模块配置寄存器中的ECOMn位(PCA0CPMn.6)清0使CEXn输出保持为低电平。这
样就可以产生一个0%占空度的波形。可以通过向该位写‘1’或向PCA0CPHn写入一个任意值
来恢复正常的PWM输出。
2. 将MATn和ECCFn位(分别为PCA0CPMn.3 和 PCA0CPMn.0)设置为‘1’会导致在CEXn的下
降沿产生个中断。
M
A
T
n
T
O
G
n
PCA0CPMn
P
E
W
C
M
O
M
n
n
C
A
P
P
n
0 0 x 0
C
A
P
N
n
PCA0CPHn
PCA0CPLn
E
C
C
F
n
x
允许
8位比较器
匹配
S
QSET
CEXn
交叉开关
端口I/O
R
CLR
Q
PCA时基
PCA0L
溢出
图4. PCA被配置为8位PWM方式
4
AN007-1.0 DEC00
AN007 — 用 PCA 实现 16 位 PWM
CEXn
PCA0CPHn
256
图5. 8位PWM方式的输出波形
用PCA 产生16 位PWM
为了产生一个具有16位精度的PWM波形,我们将PCA模块配置为高速输出方式,如图6所示。
在该方式下,每当主定时器/计数器的寄存器(PCA0H:PCA0L)与模块的捕捉/比较寄存器
(PCA0CPHn:PCA0CPLn)相匹配时,CEXn引脚发生电平转换,并可以选择产生中断。
在示例代码中,PCA模块的中断服务程序用两个状态中实现:上升沿状态和下降沿状态,取决
于CEXn引脚上哪一个边沿触发中断。注意,现在所说的的CEXn引脚被看作状态变量。
在上升沿状态,模块的捕捉/比较寄存器被下一个下降沿的比较值更新(该值在示例代码中被
称为PWM)。在下降沿状态,下一个上升沿的比较值被装入模块的捕捉/比较寄存器,该值为0
(0x0000)。这一过程如图7所示。注意,PWM波形的周期为65536个PCA时钟周期。
占空度(用%表示)由下式给出:
占空度
=
PWM
65536
×
100
写到
PCA0CPLn
写到
PCA0CPHn
0
ENB
ENB
1
E
C
O
M
n
T
O
G
n
M
A
T
n
PCA0CPMn
C
C
E
A
A
C
P
P
C
N
P
F
n
n
n
0 0
0 x
P
W
M
n
PCA0CPLn
PCA0CPHn
C
F
PCA中断
PCA0CN
C
C
C
C
C
R
F
F
2
1
C
C
F
4
C
C
F
3
C
C
F
0
允许
16位比较器
匹配
电平切换
0
1
TOGn
PCA时基
PCA0L
PCA0H
图6. PCA配置为高速输出方式
CEXn
0
1
交叉开关
端口I/O
AN007-1.0 DEC00 5
AN007 — 用 PCA 实现 16 位 PWM
CEXn
PCA0CPn
PWM
0x0000
匹配发生;
中断已调用
比较寄存
器已更新
匹配发生;
中断已调用
PWM
比较寄存
器已更新
图7. 16位PWM的捕捉/比较寄存器装载过程
所允许的最大和最小占空度由CEXn发生变化(它触发过程中断)后更新比较值所需要的最大
时间决定。在‘C’示例代码和汇编示例代码中(分别为‘pwm16_1.c’和‘pwm16_1.asm’),PWM
的最小值7个PCA时钟(对于本例为28个SYSCLK周期)。在这种情况下最小和最大占空度的值分别
为0.01%和99.99%。占空度的分辨率(用%表示)为:
分辨率
=
1
65536
×
100
=
.0
0015
或大约15个ppm(1ppm=百万分之一)。
处理该中断的CPU开销是最小的。在汇编示例代码中处理两个边沿共需要41个SYSCLK周期,
这不包括中断调用和中断返回所需的时间。两个边沿都必须每隔65536个PCA时钟被处理一次,或
65536*4=262144个SYSCLK周期(如果PCA时钟等于SYSCLK/4)。所消耗的CPU带宽(用%表示)
等于(41/262144*100)=0.015%。
还应注意到CPU可以在保留在等待方式,如示例中所做的那样,这是因为PCA模块中断在需要
处理时将‘唤醒’CPU内核。
在示例中,占空度是通过向变量PWM写入一个16位的值来改变的。
用PCA 实现n 位PWM
作为16位PWM的推广,我们介绍在一些应用中所需要的高于8位精度但低于16位精度的n位
PWM。采用n位PWM方案的动机之一是为了获得比16位实现方式更高的PWM输出频率。
在该例中(‘PWMn_1.c’)用到两个16位变量:PWM_HIGH(保持用于使输出波形处于高电
平所需要的PCA时钟数),PWM_LOW(保持用于使输出波形处于低电平所需要的PCA时钟数)。
输出波形的周期为这两个变量的和:
周期=PWM_HIGH+PWM_LOW
占空度(用%表示)由下式给出:
==
占空度
PWMHIGH
PWMHIGH
+
PWMLOW
100×
6
AN007-1.0 DEC00
AN007 — 用 PCA 实现 16 位 PWM
占空度的分辨率(用%表示)为:
分辨率
==
PWMHIGH
1
+
PWMLOW
×
100
与16位PWM的情况类似,中断处理过程在两个状态中实现:一个用于上升沿状态,另一个用
于下降沿状态。主要区别是在16位的情况下被装入到PCA模块比较寄存器的数值是一个常数(PWM
或0)。在n位的情况下,常数(PWM_HIGH或PWM_LOW)被加到模块的比较寄存器的当前值。这
一加法操作比装载一个常数需要多花几个时钟周期,这就导致了输出波形的高电平或低电平的最小
时间略大于相应的16位解决方案。
注:通过向PWM_HIGH和PWM_LOW写入合适的高电平和低电平值,n位PWM方案可以用于产
生一个任意频率的波形。
AN007-1.0 DEC00 7
AN007 — 用 PCA 实现 16 位 PWM
软件示例
PWM8_1.c
KEIL C51
PCA被配置为8位PWM方式,使用SYSCLK/4作为时基信号。
中保持着每256个计数周期内输出波形为低电平的PCA周期数。
由于该8位PWM完全受硬件控制,不需要额外的CPU周期来维持固定的
占空度。在本例中,改变占空度只需要向模块的比较寄存器PCA0CP0H
的高字节写一个8位数。
实现8位PWM的示例代码。
波形为高电平的时间占(256 - PWM)个周期。
输出波形的占空度=(256 - PWM)/256。
//--------------------------------------------------------------------
// PWM8_1.c
//--------------------------------------------------------------------
//
// AUTH: BW
//
// 目标器件: C8051F000、F001、F002、F005、F006、F010、F011或F012
// 工具链:
//
// 说明:
//
//
//
//
//
//
//
//
//
//
//
//
//
//--------------------------------------------------------------------
// 包含文件
//--------------------------------------------------------------------
#include
//--------------------------------------------------------------------
// 全局常量
//--------------------------------------------------------------------
#define PWM
可以达到的占空度范围是0.38%(PCA0CP0H = 0xff)
到100%(PCA0CP0H = 0x00)。
// 波形为低电平的PCA周期数
// 占空度 = (256 - PWM) / 256
// 注:这是一个8位数
0x80
// SFR 声明
8
AN007-1.0 DEC00