STC15F2K60S2芯片PWM的应用
1.目的
脉宽调制(PWM,Pulse Width Modulation)是一种使用程序来控制波形占空比、周期、相位波形的技术,在三相电机驱动、D/A转换等场合有广泛的应用。
STC15系列单片机的PCA模块可以通过设定各自的寄存器PCA_PWMn(n=0,1,2.下同)中的位EBSn_1/PCA_PWMn.7及EBSn_0/PCA_PWMn.6,使其工作于8位PWM或7位PWM或6位PWM模式。
2.与CCP/PWM/PCA应用有关的特殊功能寄存器
符号 |
描述 |
位地址及其符号 |
复位值 |
||||||||
地址 |
B7 |
B6 |
B5 |
B4 |
B3 |
B2 |
B1 |
B0 |
|
||
CCON |
PCA Control Register |
D8H |
CF |
CR |
- |
- |
- |
CCF2 |
CCF1 |
CCF0 |
00xx xx00 |
CMOD |
PCA Mode Register |
D9H |
CIDL |
- |
- |
- |
CPS2 |
CPS1 |
CPS0 |
ECF |
0xxx 0000 |
CCAPM0 |
PCA Module 0 Mode Register |
DAH |
- |
ECOM0 |
CAPP0 |
CAPN0 |
MAY0 |
TOG0 |
PWM0 |
ECCF0 |
x000 000 |
CCAPM1 |
PCA Module 1 Mode Register |
DBH |
- |
ECOM1 |
CAPP1 |
CAPN1 |
MAY1 |
TOG1 |
PWM1 |
ECCF1 |
x000 0000 |
CCAPM2 |
PCA Module 2 Mode Register |
DCH |
- |
ECOM2 |
CAPP2 |
CAPN2 |
MAY2 |
TOG2 |
PWM2 |
ECCF2 |
x000 0000 |
CL |
PCA Base Timer Low |
E9H |
|
|
|
|
|
|
|
|
0000 0000 |
CH |
PCA Base Timer High |
F9H |
|
|
|
|
|
|
|
|
0000 0000 |
CCAP0L |
PCA Module-0 Capture Register Low |
EAH |
|
|
|
|
|
|
|
|
0000 0000 |
CCAP0H |
PCA Module-0 Capture Register High |
FAH |
|
|
|
|
|
|
|
|
0000 0000 |
CCAP1L |
PCA Module-1 Capture Register Low |
EBH |
|
|
|
|
|
|
|
|
0000 0000 |
CCAP1H |
PCA Module-1 Capture Register High |
FBH |
|
|
|
|
|
|
|
|
0000 0000 |
CCAP2L |
PCA Module-2 Capture Register Low |
ECH |
|
|
|
|
|
|
|
|
0000 0000 |
CCAP2H |
PCA Module-2Capture Register High |
FCH |
|
|
|
|
|
|
|
|
0000 0000 |
PCA_PWM0 |
PCA PWM Mode Auxiliary Register 0 |
F2H |
EBS0_1 |
EBS0_0 |
- |
- |
- |
- |
EPC0H |
EPC0L |
00xx xx00 |
PCA_PWM1 |
PCA PWM Mode Auxiliary Register 1 |
F3H |
EBS1_1 |
EBS1_0 |
- |
- |
- |
- |
EPC1H |
EPC1L |
00xx xx00 |
PCA_PWM2 |
PCA PWM Mode Auxiliary Register 2 |
F4H |
EBS2_1 |
EBS2_0 |
- |
- |
- |
- |
EPC2H |
EPC2L |
00xx xx00 |
AUXRI P_SW1 |
Auxiliary Register 1 |
A2H |
S1_S1 |
S1_S0 |
CCP_S1 |
CCP_S0 |
SP1_S1 |
SP1_S0 |
- |
DPS |
0100 0000 |
2.1.PCA工作模式寄存器CMOD
PCA工作模式寄存器的格式如下:
CMOD:PCA工作模式寄存器
SFR name |
Address |
bit |
B7 |
B6 |
B5 |
B4 |
B3 |
B2 |
B1 |
B0 |
CCON |
D9H |
name |
CIDL |
- |
- |
- |
CPS2 |
CPS1 |
CPS0 |
ECF |
CIDL:空闲模式下是否停止PCA计数的控制位。
当CIDL = 0时,空闲模式下PCA计数器继续工作;
当CIDL = 1时,空闲模式下PCA计数器停止工作;
CPS2、CPS1、CPS0:PCA计数脉冲源选择控制位。
PCA计数脉冲选择如下表所示。
CPS2 |
CPS1 |
CPS0 |
选择PCA/PWM时钟源输入 |
0 |
0 |
0 |
0,系统时钟,SYSclk/12 |
0 |
0 |
1 |
1,系统时钟,SYSclk/2 |
0 |
1 |
0 |
2,定时器0的溢出脉冲。由于定时器0可以工作在T1模式,所以可以达到记一个时钟就溢出,从而达到最高频率CPU工作时钟SYSclk,通过改变定时器0的溢出率,可以实现可调频率的PWM输出 |
0 |
1 |
1 |
3,ECI/P1.2(或P4.1)脚输入的外部时钟(最大速率=SYSclk/2) |
1 |
0 |
0 |
4,系统时钟,SYSclk |
1 |
0 |
1 |
5,系统时钟/4,SYSclk/4 |
1 |
1 |
0 |
6,系统时钟/6,SYSclk/6 |
1 |
1 |
1 |
7,系统时钟/8,SYSclk/8 |
例如,CPS2/CPS1/CPS0 = 1/0/0时,CCP/PCA/PWM的时钟源是SYSclk,不用定时器0,PWM的频率为SYSclk/256.
如果要用系统时钟/3来作为PCA的时钟源,应选择T0的溢出作为CCP/PCA/PWM的时钟源,此时应让T0工作在1T模式,计数3个脉冲即产生溢出。用T0的溢出可对系统时钟进行1~65536级分频(T0工作在16为重装载模式)。
ECF:PCA计数溢出中断使能位。
当ECF = 0时,禁止寄存器CCON中CF位的中断;
当ECF = 1时,允许寄存器CCON中CF位的中断。
2.2.PCA控制寄存器CCON
PCA控制寄存器的格式如下:
CCON:PCA控制寄存器
SFR name |
Address |
bit |
B7 |
B6 |
B5 |
B4 |
B3 |
B2 |
B1 |
B0 |
CCON |
D8H |
name |
CF |
CR |
- |
- |
- |
- |
CCF1 |
CCF0 |
CF:PCA计数器阵列溢出标志位。当PCA计数器溢出时,CF由硬件置位。如果CMOD寄存器的ECF位置位,则CF标志可用来产生中断。CF位可通过硬件或软件置位,但只能通过软件清零。
CR:PCA计数器阵列运行控制位。该位通过软件置位,用来启动计数器阵列计数。该位通过软件清零,用来 关闭PCA计数器。
CCF2:PCA模块2中断标志。当出现匹配或捕捉时该位由硬件置位。该位必须通过软件清零。
CCF1:PCA模块1中断标志。当出现匹配或捕捉时该位由硬件置位。该位必须通过软件清零。
CCF0:PCA模块0中断标志。当出现匹配或捕捉时该位由硬件置位。该位必须通过软件清零。
2.3.PCA比较/捕获寄存器CCAPM0、CCAPM1和CCAPM2
PCA模块0的比较/捕获寄存器的格式如下:
CCAPM0:PCA模块0的比较/捕获寄存器
SFR name |
Address |
Bit |
B7 |
B6 |
B5 |
B4 |
B3 |
B2 |
B1 |
B0 |
CCAPM0 |
DAH |
name |
- |
ECOM0 |
CAPP0 |
CAPN0 |
MAT0 |
TOG0 |
PWM0 |
ECCF0 |
B7:保留为将来之用。
ECOM0:允许比较器功能控制位。
当ECOM0 = 1时,允许比较器功能。
CAPP0: 正捕获控制位。
当CAPP0 = 1时,允许上升沿捕获。
CAPN0: 负捕获控制位。
当CAPN0 = 1时,允许下降沿捕获。
MAT0: 匹配控制位。
当MAT0 = 1时,PCA计数值与模块的比较/捕获寄存器的值的匹配将置位CCON寄存器的中断标志位CCF0。
TOG0:翻转控制位。
当TOG0 = 1时,工作在PCA高速脉冲输出模式,PCA计数器的值与模块的比较/捕获寄存器的值的匹配将使CCP0脚翻转。
PWM0: 脉宽调制模式。
当PWM0 = 1时,允许CCP0脚用作脉宽调节输出。
ECCF0:使能CCF0中断。使能寄存器CCON的比较/捕获标志CCF0,用来产生中断。
PCA模块1的比较/捕获寄存器的格式如下:
CCAPM1:PCA模块1的比较/捕获寄存器
SFR name |
Address |
Bit |
B7 |
B6 |
B5 |
B4 |
B3 |
B2 |
B1 |
B0 |
CCAPM1 |
DBH |
name |
- |
ECOM1 |
CAPP1 |
CAPN1 |
MAT1 |
TOG1 |
PWM1 |
ECCF1 |
B7:保留为将来之用。
ECOM1:允许比较器功能控制位。
当ECOM1 = 1时,允许比较器功能。
CAPP1: 正捕获控制位。
当CAPP1 = 1时,允许上升沿捕获。
CAPN1:负捕获控制位。
当CAPN1 = 1时,允许下降沿捕获。
MAT1:匹配控制位。
当MAT1 = 1时,PCA计数值与模块的比较/捕获寄存器的值的匹配将置位CCON寄存器的中断标志位CCF1。
TOG1:翻转控制位。
当TOG1 = 1时,工作在PCA高速脉冲输出模式,PCA计数器的值与模块的比较/捕获寄存器的值的匹配将使CCP1脚翻转。
PWM1: 脉宽调制模式。
当PWM1 = 1时,允许CCP1脚用作脉宽调节输出。
ECCF1:使能CCF1中断。使能寄存器CCON的比较/捕获标志CCF1,用来产生中断。
PCA模块2的比较/捕获寄存器的格式如下:
CCAPM2:PCA模块2的比较/捕获寄存器
SFR name |
Address |
Bit |
B7 |
B6 |
B5 |
B4 |
B3 |
B2 |
B1 |
B0 |
CCAPM2 |
DCH |
name |
- |
ECOM2 |
CAPP2 |
CAPN2 |
MAT2 |
TOG2 |
PWM2 |
ECCF2 |
B7:保留为将来之用。
ECOM2:允许比较器功能控制位。
当ECOM2 = 1时,允许比较器功能。
CAPP2: 正捕获控制位。
当CAPP2 = 1时,允许上升沿捕获。
CAPN2:负捕获控制位。
当CAPN2 = 1时,允许下降沿捕获。
MAT2:匹配控制位。
当MAT2 = 1时,PCA计数值与模块的比较/捕获寄存器的值的匹配将置位CCON寄存器的中断标志位CCF2。
TOG2:翻转控制位。
当TOG2 = 1时,工作在PCA高速脉冲输出模式,PCA计数器的值与模块的比较/捕获寄存器的值的匹配将使CCP2脚翻转。
PWM2:脉宽调制模式。
当PWM2 = 1时,允许CCP2脚用作脉宽调节输出。
ECCF2:使能CCF2中断。使能寄存器CCON的比较/捕获标志CCF2,用来产生中断。
2.4.PCA的16位计时器 — 低8位CL和高8位CH
CL和CH地址分别为E9H和F9H,复位值均为00H,用于保存PCA的装载值。2.5.PCA捕捉/比较寄存器 — CCAPnL(低位字节)和CCAPnH(高位字节)
当PCA模块用于捕获或比较时,它们用于保存各个模块的16位捕捉计数值;当PCA模块用于PWM模式时,它们用来控制输出的占空比。其中,n = 0、1、2,分别对应模块0、模式1和模块2。复位值均为00H。它们对应的地址分别为:
CCAP0L — EAH、CCAP0H — FAH:模块0的捕捉/比较寄存器。
CCAP1L — EBH、CCAP1H — FBH:模块1的捕捉/比较寄存器。
CCAP2L — ECH、CCAP2H — FCH:模块2的捕捉/比较寄存器。
2.6.PCA模块PWM寄存器PCA_PWM0、PCA_PWM1和PCA_PWM2
PCA模块0的PWM寄存器的格式如下:
PCA_PWM0:PCA模块0的PWM寄存器
SFR name |
Address |
Bit |
B7 |
B6 |
B5 |
B4 |
B3 |
B2 |
B1 |
B0 |
PCA_PWM0 |
F2H |
name |
EBS0_1 |
EBS0_0 |
- |
- |
- |
- |
EPC0H |
EPC0L |
EBS0_1,EBS0_0:当PCA模块0工作于PWM模式时的功能选择位。
0,0:PCA模块0工作于8位PWM功能;
0,1:PCA模块0工作于7位PWM功能;
1,0:PCA模块0工作于6位PWM功能;
1,1:无效,PCA模块0工作于8位PWM模式。
EPC0H:在PWM模式下,与CCAP0H组成9位数。
EPC0L:在PWM模式下,与CCAP0L组成9位数。
PCA模块1的PWM寄存器的格式如下:
PCA_PWM1:PCA模块1的PWM寄存器
SFR name |
Address |
Bit |
B7 |
B6 |
B5 |
B4 |
B3 |
B2 |
B1 |
B0 |
PCA_PWM1 |
F3H |
name |
EBS2_1 |
EBS2_0 |
- |
- |
- |
- |
EPC1H |
EPC1L |
EBS1_1,EBS1_0:当PCA模块1工作于PWM模式时的功能选择位。
0,0:PCA模块1工作于8位PWM功能;
0,1:PCA模块1工作于7位PWM功能;
1,0:PCA模块1工作于6位PWM功能;
1,1:无效,PCA模块1工作于8位PWM模式。
EPC1H:在PWM模式下,与CCAP1H组成9位数。
EPC1L:在PWM模式下,与CCAP1L组成9位数。
PCA模块2的PWM寄存器的格式如下:
PCA_PWM2:PCA模块2的PWM寄存器
SFR name |
Address |
Bit |
B7 |
B6 |
B5 |
B4 |
B3 |
B2 |
B1 |
B0 |
PCA_PWM2 |
F4H |
name |
EBS2_1 |
EBS2_0 |
- |
- |
- |
- |
EPC2H |
EPC2L |
EBS2_1,EBS2_0:当PCA模块2工作于PWM模式时的功能选择位。
0,0:PCA模块2工作于8位PWM功能;
0,1:PCA模块2工作于7位PWM功能;
1,0:PCA模块2工作于6位PWM功能;
1,1:无效,PCA模块2工作于8位PWM模式。
EPC2H:在PWM模式下,与CCAP2H组成9位数。
EPC2L:在PWM模式下,与CCAP2L组成9位数。
PCA模块的工作模式设定表如下表所列:
ECOMn |
CAPPn |
CAPNn |
MATn |
TOGn |
PWMn |
ECCFn |
模块功能 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
无此操作 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
8位PWM,无中断 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
8位PWM输出,由低变高产生中断 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
8位PWM输出,由高变低产生中断 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
8位PWM输出,由高变低或由低到高 |
X |
1 |
0 |
0 |
0 |
0 |
X |
16位捕获模式,由CEXn/PCAn的上升沿触发 |
X |
0 |
1 |
0 |
0 |
0 |
X |
16位捕获模式,由CEXn/PCAn的下降沿触发 |
X |
1 |
1 |
0 |
0 |
0 |
X |
16位捕获模式,由CEXn/PCAn的跳变触发 |
1 |
0 |
0 |
1 |
0 |
0 |
X |
16位软件定时器 |
1 |
0 |
0 |
1 |
1 |
0 |
X |
16位高速输出 |
PCA模块工作模式设定(CCAPMn寄存器,n = 0、1、2)
3.原理图
3.1 8位脉宽调节模式(PWM)
当[EBSn_1,EBSn_0]=[0,0]或[1,1]时,PCA模块n工作8位PWM模式,此时将{0,CL[7:0]}与捕获寄存器[EPCnL,CCAPnL[7:0]]进行比较。
PWM模式的结构如下图所示。
PCA PWM mode/可调制脉冲宽度输出模式结构图(PCA模块工作于8位PWM模式)
当PCA模块工作于8位PWM模式时,由于所有模块共用仅有的PCA定时器,所有它们的输出频率相同。各个模块的输出占空比是独立变化的,与使用的捕获寄存器{EPCnL,CCAPnL[7:0]}有关。当{0,CL[7:0]}的值小于{EPCnL,CCAPnL[7:0]}时,输出为低;当{0,CL[7:0]}的值等于或大于{EPCnL,CCAPnL[7:0]}时,输出为高。当CL的值由FF变为00溢出时,{EPCnH,CCAPnH[7:0]}的内容装载到{EPCnL,CCAPnL[7:0]}中。这样就实现无干扰地更新PWM。要使能PWM模式,模块CCAPMn寄存器的PWMn和ECOMn位必须置位。
PCA时钟输入源频率
当PWM是8位的时:PWM的频率=
256
PCA时钟输入源可以从以下8中中选择一种:SYSclk,SYSclk/2,SYSclk/4,SYSclk/6,
SYSclk/8,SYSclk/12,定时器0的溢出,ECI/P1.2输入。
如果要实现可调频率的PWM输出,可选择定时器0的溢出率或者ECI脚的输入作为PCA/PWM的时钟输入源
当EPCnL = 0及CCAPnL = 00H时,PWM固定输出高
当EPCnL = 1及CCAPnL = 0FFH时,PWM固定输出低
当某个I/O作为PWM使用时,该口的状态:
PWM之前口的状态 |
PWM输出时的状态 |
弱上拉/准双向 |
强推挽输出/强上拉输出,要加输出限流电阻1K~10K |
强推挽输出/强上拉输出 |
强推挽输出/强上拉输出,要加输出限流电阻1K~10K |
仅为输入/高阻 |
PWM无效 |
开漏 |
开漏 |
3.2 7位脉宽调节模式(PWM)
当[EBSn_1,EBSn_0]=[0,1]时,PCA模块n工作7位PWM模式,此时将{0,CL[6:0]}与捕获寄存器[EPCnL,CCAPnL[6:0]]进行比较。PWM模式的结构如下图所示。
PCA PWM mode/可调制脉冲宽度输出模式结构图(PCA模块工作于7位PWM模式)
当PCA模块工作于7位PWM模式时,由于所有模块共用仅有的PCA定时器,所有它们的输出频率相同。各个模块的输出占空比是独立变化的,与使用的捕获寄存器{EPCnL,CCAPnL[6:0]}有关。当{0,CL[6:0]}的值小于{EPCnL,CCAPnL[6:0]}时,输出为低;当{0,CL[6:0]}的值等于或大于{EPCnL,CCAPnL[6:0]}时,输出为高。当CL的值由7F变为00溢出时,{EPCnH,CCAPnH[6:0]}的内容装载到{EPCnL,CCAPnL[6:0]}中。这样就实现无干扰地更新PWM。要使能PWM模式,模块CCAPMn寄存器的PWMn和ECOMn位必须置位。
PCA时钟输入源频率
当PWM是7位的时:PWM的频率=
128
PCA时钟输入源可以从以下8中中选择一种:SYSclk,SYSclk/2,SYSclk/4,SYSclk/6,
SYSclk/8,SYSclk/12,定时器0的溢出,ECI/P1.2输入。
如果要实现可调频率的PWM输出,可选择定时器0的溢出率或者ECI脚的输入作为PCA/PWM的时钟输入源
当EPCnL = 0及CCAPnL = 80H时,PWM固定输出高
当EPCnL = 1及CCAPnL = 0FFH时,PWM固定输出低
3.2 6位脉宽调节模式(PWM)
当[EBSn_1,EBSn_0]=[1,0]时,PCA模块n工作6位PWM模式,此时将{0,CL[5:0]}与捕获寄存器[EPCnL,CCAPnL[5:0]]进行比较。PWM模式的结构如下图所示。
PCA PWM mode/可调制脉冲宽度输出模式结构图(PCA模块工作于6位PWM模式)
当PCA模块工作于6位PWM模式时,由于所有模块共用仅有的PCA定时器,所有它们的输出频率相同。各个模块的输出占空比是独立变化的,与使用的捕获寄存器{EPCnL,CCAPnL[5:0]}有关。当{0,CL[5:0]}的值小于{EPCnL,CCAPnL[5:0]}时,输出为低;当{0,CL[5:0]}的值等于或大于{EPCnL,CCAPnL[5:0]}时,输出为高。当CL的值由3F变为00溢出时,{EPCnH,CCAPnH[5:0]}的内容装载到{EPCnL,CCAPnL[5:0]}中。这样就实现无干扰地更新PWM。要使能PWM模式,模块CCAPMn寄存器的PWMn和ECOMn位必须置位。
PCA时钟输入源频率
当PWM是6位的时:PWM的频率=64
PCA时钟输入源可以从以下8中中选择一种:SYSclk,SYSclk/2,SYSclk/4,SYSclk/6,
SYSclk/8,SYSclk/12,定时器0的溢出,ECI/P1.2输入。
如果要实现可调频率的PWM输出,可选择定时器0的溢出率或者ECI脚的输入作为PCA/PWM的时钟输入源
当EPCnL = 0及CCAPnL = 0C0H时,PWM固定输出高
当EPCnL = 1及CCAPnL = 0FFH时,PWM固定输出低
4.程序
//P3.7输出PWM波形
#include
sfr CCON = 0xd8;
sfr CMOD = 0xd9;
sfr CCAPM2 = 0xdc;
sfr CL = 0xe9;
sfr CH = 0xf9;
sfr CCAP2L = 0xec;
sfr CCAP2H = 0xfc;
sfr PCA_PMW2 = 0xf4;
code unsigned char seven_seg[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char cp1,cp2 = 255;
unsigned int cp0;
sbit P3_4 = P3^4;
sbit P3_5 = P3^5;
sbit P3_6 = P3^6;
void timer0_isr(void) interrupt 1
{
TH0= (65536 - 1000) / 256; //重装初值
TL0= (65536 - 1000) % 256; //重装初值
cp0++; //中断1次,变量加1
if(cp0>= 100) //1秒到了
{
cp0= 0;
cp2--; //cp2为脉宽控制变量
if(cp2<= 1)
cp2= 255;
}
P2= 0xff;
P3= 0xff;
switch(cp1)
{
case0: P2 = seven_seg[cp2 % 100 % 10]; P3_6 = 0;break;
case1: P2 = seven_seg[cp2 % 100 / 10]; P3_5 = 0;;break;
case2: P2 = seven_seg[cp2 / 100]; P3_4 = 0;break;
}
cp1++;
if(cp1>=3)cp1 = 0;
}
/*********************Timer0初始化函数***********************/
void timer0_init(void)
{
TMOD= 0x01; //T0工作方式1
TH0= (65536 - 1000) / 256; //对机器脉冲计数1000个计满溢出引发中断
TL0= (65536 - 1000) % 256;
EA= 1; //开总中断
ET0= 1; //开T0中断
TR0= 1; //启动定时器T0
}
void pwm0_init(void)
{
CCON= 0x00;
CL= 0x00;
CH= 0x00;
PCA_PMW2= 0x00; //8位PMW,占空比的第九位EPC0L为0
CCAPM2= 0x42; //允许比较,P3.7输出
CCON= 0x40; //允许PAC计数
}
void main(void)
{
timer0_init();
pwm0_init();
while(1)
{
if(CL== 0xff)
{
CCAP2L = cp2;
CCAP2H= cp2;
}
}
}