STC单片机16位寄存器CCAP高低位的写入顺序问题!
本帖最后由 czlss 于 2016-12-6 14:41 编辑最近用stc12c5a60s2写了个小的测试程序,利用PCA模块的软件定时功能,实现在P1.6输出脉冲宽度为 1 秒钟的方波(晶振频率fosc = 12MHz)。选择PCA模块0实现定时功能。通过置位CCAPM0寄存器的ECOM位和MAT位,使PCA模块0工作于软件定时器模式,选择PCA模块的时钟源为FOSC/12,基本定时时间单位T为5ms,对5ms计数200次以后,即可实现1s的定时。在中断服务程序中,将新的匹配值值赋给。
但是当我把中断里面CCAP0L=num%256;CCAP0H=num/256; 这两行代码换了个顺序后,先给高八位,后给低八位后,发现结果就不能正常工作,求解!
#include "STC12C5A60S2.h" //包含头文件
sbit LED_1s=P1^6;
unsigned char cnt; //中断计数变量
void main (void)
{
cnt=200; //设置COUNTER计数器初值
CMOD=0x80; //#10000000B 空闲模式下停止PCA计数器工作
//选择PCA时钟源为FOSC/12,禁止PCA计数器溢出时中断
CCON=0; //清零PCA计数器溢出中断请求标志位CF
//CR = 0, 不允许 PCA 计数器计数;清零PCA 各模块中断请求标志位CCFn
CL=0; //清零PCA 计数器
CH=0;
CCAP0L=0X88; //给PCA模块0的CCAP0L置初值
CCAP0H=0x13; //给PCA模块0的CCAP0H 置初值
CCAPM0=0x49; //设置PCA模块0为16位软件定时器
//ECCF0=1允许PCA模块0中断
//当=时,CCF0=1,产生中断请求
EA=1; //开整个单片机所有中断共享的总中断控制位
CR=1; //启动PCA计数器(CH,CL)计数
while(1); //等待中断
}
void PCA_ISR(void) interrupt 7 //PCA中断服务程序
{
unsigned int num;
num=CCAP0H*256+CCAP0L+0x1388;
CCAP0L=num%256; //取计算结果的低8位
CCAP0H=num/256; //取计算结果的高8位
CCF0=0; //清 PCA 模块0 中断标志
cnt--; //修改中断计数
if (cnt==0)
{
cnt=200; //恢复中断计数初值
LED_1s =!LED_1s; //在P1.6输出脉冲宽度为1秒钟的方波
}
} 楼主标题有问题啊,赶快改标题,不然ID不保。 赶快改标题,不然ID不保 本来就要求先低8位后高8位,设计就要求如此。这个其实是16位的寄存器,写入顺序有要求的。
小李非刀 发表于 2016-12-6 13:56
本来就要求先低8位后高8位,设计就要求如此。这个其实是16位的寄存器,写入顺序有要求的。
...
ok,了解! lcw_swust 发表于 2016-12-6 10:59
ok,了解! 经常用STC单片机的坛友,说说STC单片机有哪些优势。 上次美仔细看资料,直到后来打电话,才知道201居然没有T1 czlss 发表于 2016-12-6 14:45
ok,了解!
其实就跟这个贴子一样:
在中断程序内 变量的加加,这种情况是否会出现BUG!
cpu是八位,定时器16位。为防止定时器见到写了一半的值,高级一点的设计必须有个隐藏的锁存器,你写低一半的时候锁住,等你写高一半的时候才一起写入定时时器。
标准51的定时器读的时候没有隐藏锁存器之类,所以书上教的读定时器得读三次:先读高,后读低,再读一次高。如果两次高不同表示你碰上进位了,重新读! redroof 发表于 2016-12-7 08:53
其实就跟这个贴子一样:
在中断程序内 变量的加加,这种情况是否会出现BUG!
cpu是八位,定时器16位。为 ...
终于看到有朋友有次认识。
在90年代初用51做测频时,比如测量32768HZ时,(不停止计数器)读计数器偶尔会出现读数突变256的情况,但是没有网络电话啊。。。
后来才知道,8位处理16位或32位的数据,必须保证其完整性。
实际中经常看到好多新手犯各种错误,举个栗子,比如还是用STC:
定时器1ms中断,做cnt++。主程序判断 if(cnt == 500)就执行某项操作。
发现很难执行这项操作,于是就说,单片机有问题,STC烂。
其实,主程序执行其他程序时cnt 了500, 但是回来判断时却已经超过500了。
这个,还真不能怨单片机,怨自己吧。
页:
[1]