51单片机轻松入门—基于STC15W4K系列(C语言版)
李友全 编著:http://www.51hei.com/bbs/dpj-37954-1.html
第8章 CCP/PCA/PWM模块(可用作DAC) 1 捕获模式(用于扩展外中断) 2 16位定时器模式 3 高速输出模式 4 脉宽调节模式
花开见佛
CCP/PCA/PWM模块其实是1个模块,通过不同的软件设置可实现4种不同的功
能:外中断(3个)、定时器(1个)、时钟输出(3个)、PWM脉宽调制输出 (3个)。
1 捕获模式(用于扩展外中断)
PCA模块工作于捕获模式的结构如图所示。 要使PCA 模块工作在捕获模式,寄存器CCAPMn的两位CAPPn和CAPNn中至少有一位必须置 1,PCA模块工作于捕获模式时,对外部输入CCPn引脚的跳变进行采样,当采样到有效跳变 时,置位CCON中的CCFn,如果CCAPMn中的ECCFn位为1,将产生中断,可在中断服务程序中 根据标志CCF2、CCF1、CCF0和CF判断是哪一个模块产生了中断或是定时器溢出中断,并注 意中断标志位的软件清0问题。
例8.1 利用PCA模块扩展3路外部中断。 说明:将P1.0(PCA模块1的外部输入)扩展为上升沿/下降沿都可触发的外部中断,当中 断产生时对P0.0取反,将P1.1(PCA模块0的外部输入)扩展为下降沿触发的外部中断,当 中断产生时对P0.1 取反,将P3.7(PCA模块2的外部输入)扩展为上升沿/下降沿都可触发 的外部中断,当中断产生时对P0.3 取反, P0.0 、P0.1和P0.2连接LED灯指示状态。 #include "STC15W4K.H" // 包含STC15W4K寄存器定义文件 sbit | LED_PCA0=P0^1; |
| // | PCA0对应P1.1脚 | sbit | LED_PCA1=P0^0; |
| // | PCA1对应P1.0脚 | sbit void | LED_PCA2=P0^2; main (void) |
| // | PCA2对应P3.7脚 | { |
|
|
|
|
port_mode(); | // | 所有IO口设为准双向弱上拉方式。 | CMOD=0x80; | // | 空闲模式下停止PCA 计数器工作 |
| // | PCA 时钟源为SYSclk /12,禁止PCA 计数器溢出时中断 | CCON=0; | // | 清0 PCA计数器溢出中断请求标志位CF |
// CR = 0, 不允许PCA计数器计数;PCA各模块中断请求标志位CCFn清0 CL=0; // PCA 计数器清0 CH=0; CCAPM0=0x11; // 设置PCA模块0下降沿触发捕捉功能 CCAPM1=0x31; // 设置PCA模块1上升/下降沿均可触发捕捉功能 CCAPM2=0x31; // 设置PCA模块2上升/下降沿均可触发捕捉功能 EA=1; // 开整个单片机所有中断共享的总中断控制位 CR=1; // 启动 PCA 计数器(CH,CL)计数 while(1); // 等待中断 } void PCA(void) interrupt 7 // PCA中断服务程序 { if(CCF0) // PCA模块0中断服务程序 { LED_PCA0=! LED_PCA0; // LED_PCA0取反,表示PCA模块0发生了中断 CCF0=0; // 清PCA模块0中断标志 } else if(CCF1) // PCA模块1中断服务程序 { LED_PCA1=!LED_PCA1; // LED_PCA1取反, 表示PCA模块1发生了中断 CCF1=0; // 清PCA模块1中断标志 } else if(CCF2) // PCA模块2中断服务程序 { LED_PCA2=!LED_PCA2; // LED_PCA2取反, 表示PCA模块2发生了中断 CCF2=0; // 清PCA模块2中断标志 } }
2 16位定时器模式 16位定时器模式的结构如图8-3所示,定时精度与16位自动重装的通用定时器相 同,但为了得到需要的输出频率,通常要在中断函数中修改CCAPnH、CCAPnL递 增步长值,并且必须让CPU反复中断,使用不如通用定时器方便。
通过置位寄存器CCAPMn的ECOMn和MATn位,可使PCA模块用作定时器,为了得到需要的输 出频率,通常要在中断函数中修改CCAPnH、CCAPnL递增步长值,因此需要置位ECCFn打开 中断。PCA计数器[CH,CL]每隔一定时间自动加1,时间间隔取决于选择的时钟源。例如, 当选择的时钟源为SYSclk/12时,每12个时钟周期[CH,CL]加1,当[CH,CL]增加到等于捕 捉/比较寄存器[CCAPnH,CCAPnL] 的值时,CCFn=1,产生中断请求,如果每次PCA模块中 断后,在中断服务程序中给[CCAPnH,CCAPnL]增加一个相同的数值,那么下一次中断来临 的间隔时间T也是相同的,从而实现了定时功能,PCA计数器计数值与定时时间的计算公 式如下: PCA计数器计数值(CCAPnH、CCAPnL设置值或递增步长值)= 定时时间/计数脉冲周期 = 定时时间*计数脉冲频率 假设,系统时钟频率SYSclk = 22.1184MHz,选择的时钟源为SYSclk/12,定时时间T为 5ms,则PCA计数器计数值为:T*(SYSclk/12)= 0.005*22118400/12=9216 = 2400H,也 就是说,PCA 计数器计数2400H次,定时时间就是5ms,这也就是每次给[CCAPnH,CCAPnL] 增加的数值(步长)。
3 高速输出模式 高速输出模式的结构如图8-5所示,原理与16位定时器模式几乎完全相同。 当PCA计数器CH、CL的值与模块捕捉/比较寄存器CCAPnH、CCAPnL的值相等时,PCA模块的输 出引脚CCPn将发生翻转,要激活高速输出模式,CCAPMn寄存器的ECOMn、MATn、TOGn位必须 都置位,为了得到需要的输出频率,需要在中断函数中修改CCAPnH、CCAPnL递增步长值, 因此需要置位ECCFn打开中断。 PCA计数器计数值(CCAPnH、CCAPnL设置值或递增步长值)= 定时时间/计数脉冲周期 = 定时时间×计数脉冲频率 = ((1/Fout)/2)×计数脉冲频率 = 计数脉冲频率/(2×Fout) 其中Fout表示PCA模块n输出时钟频率。比如系统时钟频率SYSclk = 22.1184MHz,选择的时 钟源是SYSclk/2时,要求在CCPn引脚输出100KHz的方波,CCAPnH_CCAPnL递增步长值 = (22118400/2)/(2×100000)=55.296,四舍五入取整得55,即十六进制37H。
4 脉宽调节模式
PWM意为脉冲宽度调制,可用于调整输出直流平均电压,对于矩形波而言,输出平均压等 于峰值电压×占空比,占空比是一个脉冲周期内高电平时间与周期的比值,例如,峰值电 压等于5V,占空比等于50%的方波信号平均电压等于2.5V,也就是万用表直流档测量得到 的电压值,8位PWM模式结构如图所示, PWM输出不需要使用中断。 定时器CL确定输出频率
要使能PWM模式,模块CCAPMn寄存器的ECOMn和PWMn位必须置位。 {0,CL[7:0]}与[EPCnL,CCAPnL[7:0]]进行比较,当{0,CL[7:0]}中的值小于 {EPCnL,CCAPnL[7:0]}时,输出为低,当{0,CL[7:0]}中的值等于或大于 {EPCnL,CCAPnL[7:0]}时,输出为高,当EPCnL=0且CCAPnL=00H时,PWM固定输出高,当 EPCnL=1且CCAPnL=FFH 时,PWM固定输出低。 PCA时钟输入源可以从以下8种中选择一种:SYSclk/12、SYSclk /8、SYSclk /6、 SYSclk /4、SYSclk /2、SYSclk、定时器0的溢出、ECI/P1.2输入。 PWM输出占空比由{EPCnL,CCAPnL[7:0]}确定。 8位PWM的周期 = 计数脉冲周期×256 8位PWM的频率 = 计数脉冲频率/256 8位PWM的脉宽时间(高电平时间)= 计数脉冲周期×(256-CCAPnL) 8位PWM的占空比 = 脉宽时间/PWM周期 = (1- CCAPnL/256) ×100% 如果要实现给定频率的PWM输出,可选择定时器0的溢出作为PCA的时钟输入源。当某个 I/O 口作为PWM使用时,该口自动切换到强推挽输出模式。
例8.5 利用PCA 模块实现占空比固定的PWM输出。 说明:利用PCA模块0实现在P1.1输出占空比固定的PWM信号,假设R/C时钟频率Fosc = 22.1184MHz。 #include "STC15W4K.H" // 包含STC15W4K寄存器定义文件 void initPWM() { CMOD=0x80; // #10000000B 空闲模式下停止PCA计数器工作 // 选择PCA时钟源为Fosc/12,禁止PCA计数器溢出时中断 CCAPM0=0x42; // 设置PCA模块为PWM输出方式。 CR=1; // PCA计数器开始运行 } void main() { initPWM(); CCAP0H=0x20; // 脉宽控制 while(1); // 让程序停在这里。 } 实验结果:用万用表测量P1.1输出频率为7.210KHz,占空比为87.5%。理论计算P1.1频率=计数脉冲 频率/256 = 22118400/12/256=7.2 KHz,占空比=(1- CCAPnL/256) ×100%=(1-32/256) ×100%=87.5%。可见理论计算与实际结果是一致的。
|