大家好,欢迎来到IT知识分享网。
定时器中断
定时器中断我们使用定时器0来做,定时器0中断用到的寄存器为TF0和TR0 。TF0是溢出中断标志,我们默认给0就好了,TR0是定时器运行位,置1时启动计时。
TR0 = 1; TF0 = 0;
除此之外,我们还要配置TMOD寄存器。
因为我们采用的是定时器0,然后要配成16位TL0、TH0全用的模式,直接给0x01就好了。
TMOD = 0x01;
定时10ms
定时器0用时间定时的话,我们需要使用到TL0和TH0这两个寄存器。因为,我们TMOD配置的是16位全用的模式。所以,定时器0可以计数2^16次,也就是65536次。根据我这块51单片机的晶振来计算,定时器计数1次所要花费的时间为1.085us。溢出一次花的时间为65536 * 1.085,大约是71ms。
TL0和TH0这两个寄存器默认是从0开始计数的,我们可以配置他从61ms开始计数,这样我们就能够定义出10ms了。
TH0 = 0xDC; TL0 = 0x00;
0xDC00转换为10进制是56320,65536 – 56320 = 9216,9216 * 1.085大约为10ms。
开启中断寄存器
我们使用的是定时器0,需要用到的中断寄存器为ET0和EA。由图可知,ET0是定时器0的中断寄存器,EA是总的中断寄存器。我们全部置1即可。
ET0 = 1; EA = 1;
中断处理函数
这里一共有8个中断函数,函数名其实都无所谓,主要还是需要主要函数名后面的interrupt 这个关键字。我们使用的是定时器0,所以用的是interrupt 1。
int cnt = 0; //定义一个变量来计数 void Time0Handler() interrupt 1 { cnt++; TL0 = 0x00; //每次爆表都初始化为10ms TH0 = 0xDC; if(cnt == 100) //当爆表100次时,为1秒 { cnt = 0; //清空计数 led2 = !led2; //led2状态自动变化 } }
中断函数我们不需要在main函数内进行调用,硬件会自动调用。这里的逻辑是,led2每一秒翻转一次状态,由亮到灭,或者由灭到亮。
总的函数实现
#include "reg52.h" sbit led1 = P3^7; sbit led2 = P3^6; int cnt = 0; void Delay300ms() //@11.0592MHz { unsigned char i, j, k; //_nop_(); //_nop_(); i = 13; j = 156; k = 83; do { do { while (--k); } while (--j); } while (--i); } void Time0Init() { TMOD = 0x01; TL0 = 0x00; TH0 = 0xDC; TR0 = 1; TF0 = 0; ET0 = 1; EA = 1; } void main() { led2 = 1; led1 = 1; Time0Init(); while(1) { led1 = !led1; Delay300ms(); } } void Time0Handler() interrupt 1 { cnt++; TL0 = 0x00; TH0 = 0xDC; if(cnt == 100) { cnt = 0; led2 = !led2; } }
在mian函数内,我又设计了一个led1,把它放在while里每个300ms翻转一次状态。通常来说,当主函数执行while里面的代码时,他不会进行其他操作,然而中断的作用就是能够去打断你while的代码,先去执行中断函数的代码,执行以后再来执行while里面的代码。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/128438.html