硬件环境:STC12C5608AD
该单片机的两个自带的定时器T0和T1均已经被使用,所以打算利用其自带的PCA模块做软仿定时器的波特率。说白了,就是利用PCA0模块实现一个软件定时功能。
根据datasheet的说明当CH、CL的值与CCAP0H、CCAP0L相等时,即可产生一个中断,实现定时。因此实现的办法有两种:
1、每进入一次PCA中断,将CCAP0H、CCAP0L增加一个固定值t;而CH、CL的值不变。这样定时时间由t来确定;
2、每进入一次PCA中断,将CH、CL值清零;而CCAP0H、CCAP0L的保持初值。这样定时时间由CCAP0H、CCAP0L的初值来确定;
但是遇到一个很奇怪的现象,即方法2不能实现5ms定时
话不多说,贴上程序
按照方法1,程序如下:
void PCAtimer_init()
{
CCON=CF_0+CR_0+CCF3_0+CCF2_0+CCF1_0+CCF0_0;//关PCA timer,清除CF flag, all interrupt flag
CL=0;
CH=0; //reset PCA base timer
CMOD=CIDL_0+CPS_0+ECF_0;//时钟源=Sysclk/12,空闲模式下PCA计数器继续工作,禁止CF位的中断
//CIDL_0=CPS_0=ECF_0=0x00
CCAP0L=time_L; //time_L=0x00
CCAP0H=time_H; //initial PCA0,time_H=0x12,定时5ms
CCAPM0=ECOM0_1+MAT0_1+ECCF0_1; //PCA0比较模式,打开PCA0比较功能,使能ECCF0中断
//ECOM0_1=0x40,MAT0_1=0x08,ECCF0_1=0x01
CCON |=CR_1; //PCA timer开始工作
EA=1; //开总中断
EPCA_LVD=1; //IE中断允许寄存器第六位,=1时,允许PCA模块和低压检测中断
}
void PCAtimer() interrupt 6 using 1 //5ms
{
CR=0;
CCF0=0;
CCAP0L+=time_L;
CCAP0H+=time_H; //每次都从0开始增加,这样每次定时时间相同;
i+=1;
if(10==i) //5ms*10=50s
{
i=0;
PCAFlag=1;
}
CR=1;
}
按照方法2.程序如下:
void PCAtimer_init()
{
CCON=0; //关PCA timer,清除CF flag, all interrupt flag
CL=0;
CH=0; //reset PCA base timer
CMOD=CIDL_0+CPS_0+ECF_0; //时钟源=Sysclk/12,空闲模式下PCA计数器继续工作,禁止CF位的中断
CCAP0L=t; //time_L=0x00
CCAP0H=t>>8; //initial PCA0,time_H=0x12,定时5ms
CCAPM0=ECOM0_1+MAT0_1+ECCF0_1; //PCA0比较模式,打开PCA0比较功能,使能ECCF0中断
//ECOM0_1=0x40,MAT0_1=0x08,ECCF0_1=0x01
CR=1; //PCA timer开始工作
EA=1; //开总中断
EPCA_LVD=1; //IE中断允许寄存器第六位,=1时,允许PCA模块和低压检测中断
}
void PCAtimer() interrupt 6 using 1 //5ms
{
CR=0;
if(CCF0)
{
CCF0=0;
CL=0;
CH=0; //reset PCA base timer
i=i+1;
if(10==i)
{
i=0;
PCAFlag=1;
}
}
CR=1;
}
那么问题来了:
1、按照方法1能够实现5ms定时;
2、但是按照方法2不能够实现5ms定时,时序很混乱。但是如果在方法2的中断程序中,将CL的值赋值为1,则又能实现5ms定时,很奇怪的现象。是这个方法不对吗?因为STC的规格书上并没有这种方法,只有方法1.
希望有遇到同样问题的朋友,留下一些你们的看法,谢谢!! |