第11章STC15F2K60S2单片机CCP/PCA/PWM模块
例题
例11.3 利用PCA模块扩展外部中断。将PCA0(P1.1)引脚扩展为下降沿触发的外部中断,将PCA1(Pl.0)引脚扩展为上升沿/下降沿都可触发的外部中断。当Pl.1出现下降沿产生中断时,对P1.5取反;当Pl.0出现下降沿或上升沿时都会产生中断,对P1.6取反。P1.7输出驱动工作指示灯。
解:与定时器的使用方法类似,PCA模块的应用编程主要有两点:一是正确初始化,包括写入控制字、捕捉常数的设置等;二是中断服务程序的编写,在中断服务程序中编写需要完成的任务的程序代码。PCA模块的初始化部分大致如下:
①设置PCA模块的工作方式,将控制字写入CMOD、CCON和CCAPMn寄存器。
②设置捕捉寄存器CCAPnL(低位字节)和CCAPnH(高位字节)初值。
③根据需要,开放PCA中断,包括PCA定时器溢出中断(ECF)、PCA模块0中断(ECCF0)和PCA模块1中断(ECCF1),并将EA置l。
④置位CR,启动PCA定时器计数(CH,CL)计数。
汇编语言参考程序如下:
∶定义单片机管脚
$INCLUDE (STC15F2K60S2.INC) ;包含STC15F2K60S2寄存器定义文件
LED_ START EQU P1.7 ;定义输出引脚
LED_PCA0_INT0 EQU Pl.6
LED_PCA1_INT1 EQU Pl.5
ORG 0000H
LJMP MAIN
ORG 003BH ;PCA中断的中断矢量地址
LJMP PCA_ISR
ORG 0050H
MAIN∶
MOV SP,#7FH
CLR LED_ START ;点亮开始工作指示灯
LCALL PCA_INITIATE ;调PCA模块初始化程序
SJMP $ ;原地踏步
PCA_INITIATE∶
MOV CMOD,#80H ;设置PCA在空闲模式下停止PCA计数器工作
;PCA模块的计数器时钟源源为f SYS/10
;禁止PCA计数器溢出中断
MOV CCON, #00H ;停止PCA计数器计数
MOV CL,#00H ;清0 PCA计数器
MOV CH,#00H
MOV CCAPM0,#11H ;设置PCA模块0下降沿触发捕捉功能,
;开放PCA 模块0中断
MOV CCAPM1,#31H ;设置PCA模块1下降沿和上升沿触发捕捉功能
;开放PCA 模块1中断
SETB EA
SETB CR
RET
PCA_ISR∶
PUSH ACC
PUSH PSW
JNB CCF0,NOT_PCA0 ;如果CCF0为1,执行PCA模块0中断服务程序
;如果CCF0为0,转执行PCA模块1中断标志判断CPL LED_PCA0_INT0 ;Pl.6 LED变化一次,表示PCA模块0发生了一次中断
CLR CCF0 ;清0 PCA模块0中断请求标志
NOT_PCA0∶
JNB CCF1,PCA_ISR_EXIT ;如果CCF1为0,则不是PCA模块1中断,立即推出
;如果CCF1为1,执行PCA模块1中断服务程序CPL LED_PCA1_INT1 ;Pl.5 LED变化一次,表示PCA模块1发生了一次中断
CLR CCF1 ;清0 PCA模块1中断请求标志
PCA_ISR_ EXIT∶
POP PSW
POP ACC
RETI
END
C51参考程序如下
#include“STC15F2K60S2.h”//包含STC15F2K60S2寄存器定义文件
sbit LED_PCA0_INT0=Pl^5;
sbit LED_PCA1_INT1=Pl^6;
sbit LED_START=Pl^7;
void main(void)
{
LED_START=0;
CMOD=0x80;//空闲模式下停止PCA模块计数,时钟源为f SYS/10,
//禁止PCA计数器溢出中断
CCON=0;//禁止PCA计数器计数
CL=0;
CH=0;
CCAPM0=0xll;//设置PCA模块0 下降沿触发捕捉功能,并开放中断
CCAPM1=0x31;//设置PCA模块0下降沿和上升沿触发捕捉功能,并开放中断
EA=1;//开放总中断
CR=1;//启动PCA模块计数器计数
while(1);
}
void PCA_ISR(void)interrupt 7 //PCA中断服务程序
{
if(CCF0)
{ //PCA模块0中断服务程序
LED_PCA0_INT0=!LED_PCA0_INT0;
//LED_PCA0取反输出,表示PCA模块0发生了中断CCF0=0;//清0 PCA模块0中断标志}
else if(CCF1)
{ //PCA模块0中断服务程序
LED_PCA1_INT1=!LED_PCA1_INT1;
//LED_PCA1取反输出,表示PCA模块1发生了中断CCF1=0;//清0 PCA模块1中断标志}
}
例11.4 利用PCA模块的软件定时功能,在P1.5引脚输出周期为2S的方波。设晶振频率为18.432MH Z.。
解:通过置位CCAPM0寄存器的ECOM0位和MAT0位,使PCA模块0工作于软件定时器模式。定时时间的长短取决于PCA模块捕获寄存器(CCAPnH、CCAPnL)的值与PCA 计数器的时钟源。本例中,系统频率不分频,即系统时钟频率等于晶振频率,所以f SYS=18.432 MHz,可以选择PCA模块的时钟源为f SYS/12,基本定时时间单位T为5 mS。对5 mS计数200次,即可实现1S的定时,1S时间到,对P1.5输出取反,即可实现在P1.5引脚输出周期为2S的方波。通过计算,5 mS对应的PCA计数器计数值为1E00H,在初始化时,CH、CL 从0000H开始计数,将1E00H直接传送给PCA模块捕获寄存器(CCAPnH、CCAPnL),每次5 mS时间到的中断服务程序中将该值加给(CCAPnH、CCAPnL)。
P1.7连接开始工作指示灯,P1.6连接5 mS闪烁指示灯,P1.5连接1S闪烁指示灯,所有LED灯都是低电平驱动。
汇编语言参考程序如下:
$INCLUDE (STC10C5A.INC) ;包含STC15F2K60S2寄存器定义文件
;定义单片机管脚
LED_MCU_START EQU Pl. 7
LED_ 5mS_Flashing EQU Pl.6
LED_1S_Flashing EQU P1.5
;定义常量
Channe0_5mS_H EQU 1EH ;模块0 5mS定时时间常数的高8位
Channe0_5mS_L EQU 00H ;模块0 5mS定时时间常数的低8位
;定义变量
Counter EQU 30H ;定义一个计数器,用来计数模块0 5mS中断的次数ORG 0000H
LJMP MAIN
ORG 003BH
LJMP PCA_interrupt
ORG 0050H
MAIN: CLR LED_MCU_START ;点亮MCU开始工作指示灯
MOV SP,#7FH
MOV Counter,#0 ;清0Counter计数器
LCALL PCA_Initiate ;调PCA模块初始化程序
SJMP $
PCA_Initiate:
MOV CMOD, #80H ;设置PCA在空闲模式下停止PCA计数器工作
;PCA模块的计数器时钟源源为f SYS/12
;禁止PCA计数器溢出中断
MOV CL,#00H ;设置PCA定时器计数的初始值
MOV CH,#00H
MOV CCAP0L,#Channe0_5mS_L ;给PCA模块0的CCAP0L赋定时初值
MOV CCAP0H,#Channe0_5mS_H ;给PCA模块0的CCAP0L赋定时初值
MOV CCAPM0,#49H ;设置PCA模块0为16位软件定时器
;开放PCA模块0中断
SETB EA ;开放总中断
SETB CR ;启动PCA计数器(CH,CL)计数
RET
PCA_interrupt∶
PUSH ACC
PUSH PSW
CPL LED_5mS_Flashing ;5mS中断一次,每次进中断将该灯状态取反
MOV A,#Channe0_5mS_L ;给[CCAP0H,CCAP0L]增加5mS所需计数值
ADD A,CCAP0L
MOV CCAP0L,A
MOV A,#Channe0_5mS_H
ADDC A,CCAP0H
MOV CCAP0H,A
CLR CCF0 ;清0PCA模块0的中断请求标志
INC Counter ;中断次数计数器+1
MOV A,Counter
CLR C
SUBB A,#200 ;检测过什中断了200次(1秒)
JC PCA_Interrupt_Exit ;检测是否中断了200次(1秒),若还没到立即跳转退出
MOV Counter,#00H
CPL LED_1S_Flashing
PCA_Interrupt_Exit:
POP PSW
POP ACC
RETI
END
C51参考程序如下:
#include“stc15f2k60s2.h”//包含STC15F2K60S2寄存器定义文件
sbit LED_MCU_START=Pl^7;
sbit LED_ 5mS_Flashing=Pl^6;
sbit LED_1S_Flashing=Pl^5;
unsigned char cnt;
void main(void)
{
LED_MCU_START=0;
cnt=200;//设置5mS计数器的初始值
CMOD=0x80;//设置PCA在空闲模式下停止PCA计数器工作
//PCA模块的计数器时钟源源为f SYS/12
//禁止PCA计数器溢出中断
CCON=0;//清零PCA各模块中断请求标志位CCFn
CL=0;//PCA计数器从0000H开始计数
CH=0;
CCAP0L=0;//给PCA模块0的CCAP0L置初值
CCAP0H=0xle;
CCAPM0=0x49;//设置PCA模块0为16位软件定时器