赞
踩
之前我们采用软件的方法实现,对爆表的次数进行统计,以达到我们的延时要求。我们也可以采取中断的方法,让硬件直接实现中断。
观察中断结构图可以发现只有当EA闭合的时候,才会接受中断信号,之后可以按照我们的需求对其他的中断允许控制寄存器进行赋值。
对于时钟来说,中断允许控制位为ET0和EA,在对时钟进行中断时要:
1.ET0中断允许要置一 ET0=1
2.EA总中断要置一 EA=1
另外我们需要注册一个中断向量 void Timer0_Rountine(void) interrupt 1;
同样的需求我们可以利用中断来写代码,代码如下:
#include "reg52.h" sbit led = P3^6; sbit sounder = P2^5; int cnt = 0;//用来记录爆表的次数 void Time0Init() { //1.配置定时器0工作模式为16位计时 //TMOD = 0x01; TMOD &= 0xF0; //将低四位清零,且不改变高四位的值 TMOD |= 0x01; //将低四位修改为,且不改变高四位的值 //2.给初值,定一个10ms出来 TL0 = 0x00; TH0 = 0xDC; //3.开始计时 TR0 = 1; TF0 = 0; //4.打开定时器0中断 ET0 = 1; //5.打开总中断EA EA = 1; } void main() { Time0Init(); led = 1; sounder = 1; //4.爆表了,操作led吗,累计到1s再操作led,每次爆表变量+1,变量到100再操作led while(1){ } } void Time0Handler() interrupt 1 //爆表了就进入该中断服务程序 { cnt++; //重新给初值 TL0 = 0x00; TH0 = 0xDC; if(cnt == 50){ sounder = 0; } if(cnt == 100){ cnt = 0; sounder = 1; led = !led; //每经过1s翻转led的状态 } }
此时不需要再判定是否爆表,也不需要将TF0即爆表标志位软件清0硬件会自动清零
此外我们可以再while(1)中加入我们需要的操作,从而实现多线程的效果,例如:
#include "reg52.h" #include <intrins.h> sbit led = P3^6; sbit led1 = P3^7; sbit sounder = P2^5; int cnt = 0;//用来记录爆表的次数 void Time0Init() { //1.配置定时器0工作模式为16位计时 //TMOD = 0x01; TMOD &= 0xF0; //将低四位清零,且不改变高四位的值 TMOD |= 0x01; //将低四位修改为,且不改变高四位的值 //2.给初值,定一个10ms出来 TL0 = 0x00; TH0 = 0xDC; //3.开始计时 TR0 = 1; TF0 = 0; //4.打开定时器0中断 ET0 = 1; //5.打开总中断EA EA = 1; } void Delay300ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); i = 3; j = 26; k = 223; do { do { while (--k); } while (--j); } while (--i); } void main() { Time0Init(); led = 1; sounder = 1; //4.爆表了,操作led吗,累计到1s再操作led,每次爆表变量+1,变量到100再操作led while(1){ led1 = 0; Delay300ms(); led1 = 1; Delay300ms(); } } void Time0Handler() interrupt 1 //爆表了就进入该中断服务程序 { cnt++; //重新给初值 TL0 = 0x00; TH0 = 0xDC; if(cnt == 50){ sounder = 0; } if(cnt == 100){ cnt = 0; sounder = 1; led = !led; //每经过1s翻转led的状态 } }
如果像之前将两个代码都写在while1中会互相干扰,现在就实现了两盏灯的同时亮灭操作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。