矩阵键盘学习过了,该轮到定时器和中断程序设计了
首先我来说一下51单片机的定时器的工作原理
TMOD : 控制定时器的工作方式。8个bit,高四位 bit 控制 T1,、低四位 bit 控制 T0。因为定时器有4种工作方式;TMOD = 0x00(工作方式0),TMOD = 0x01(工作方式0),TMOD = 0x02(工作方式2),TMOD = 0x03(工作方式3)。以上是控制低4位的,所以是对应着T0。
TR0:T0定时器 使能开关,TR0 = 1,开始工作; =0停止工作。
ET0:T0定时器中断开关,定时时间一到,就会跑去中断程序。ET0=1,中断使能,=0失能。
EA : 中断总开关,你可以想象成电路的总电闸,EA=1,中断使能; =0,中断失能。
TH0,TL0 : T0定时器计数寄存器,组成16位的计数,0x0000–0xFFFF(0–65535),只要TH0TL0=0xFFFF(65535),程序就会跑去中断程序,在中断程序中,我们要重新给TH0,TL0重新赋值的。
以上是蓝桥杯官网单片机组有资料包里面的内容,了解以上内容我们才能编写程序实现定时器
总结要点是 TMOD 8位是定时器的工作方式 前四位是T1 后四位是T0 四位的不同状态有不一样的方式
EA是总开关,TR0是定时器的开关,TH0,TL0是计数的储存器,16位,也就是0-65535,溢出就是归零并发生一次中断,所以可以利用这个实现中断,也就是设置TH0,TL0的值
中断不是直接程序停止,而是停下目前的指令,去处理另一个指令,然后返回来接着执行
假如说,我们定时50毫秒,TH0,TL0对应着什么值呢? 上面我们说了,TH0,TL0,组成的16位计数器计数范围是 0—65535 。50ms = 50 000us,我们只要让 TH0 TL0 从(65535 - 50000)开始计数,TH0,TL0就会不停的+1,直到TH0,TL0=65535,就是计数了50000次,时间就是过了50ms。我们只要在中断程序里面,重新赋值给TH0,TL0=(65535 - 50000),定时器就会不停得每50ms中断一次了。
所以,TH0=(65535-50000)/256; TL0 = (65535-50000)%256 ;
也就是下面的程序
void to_init(){
TMOD = 0x01 ;//定时器1,工作方式1,16bit
TH0 = (65535-20000)/256;//设置成20ms
TL0 = (65535-20000)%256;//前四位后四位,可以换算一下
//当然以上都可以写成十六进制的,你也可以试试
ET0 = 1;//T0中断的开关
EA = 1;//中断总开关
TR0 = 1;//T0开始工作
}
void T0_ISR() interrupt 1
{
//T0的中断函数,函数名可以随便起,但是后面的interrupt 1 不能省略
static unsigned int cp =0 ;//设置变量计数
TH0 = (65535-20000)/256;//定时20ms
TL0 = (65535-20000)%256;//重新赋值
//程序每隔20ms来到这里
cp=(cp+1)%50;//每次中断都来到这里,cp+1,为什么要加%50,这样是因为让cp在0-49之间变化
//等到cp归零就是下面的操作
//20*50ms=1s 芜湖,咱们不就是一个秒表么
if(cp==0){
//程序功能实现在这里
}
}
说完了TO,T1该怎么办? 我开始的时候说了,TO,T1是一对双胞胎。大家把上面T0例子程序:
(TMOD = 0x01, ET0 ,TR0,TH0,TL0 ,interrput 1) 改为
(TMOD = 0x10, ET1 ,TR1,TH1,TL1 ,interrput 3) 这样就变成了T1,定时器的程序。
但是这样设计,是不是太费脑子了?(本人是个懒人)
可以看到我们的STC-ISP的之中有定时器设置,里面可以让人家设计,利用你导入的芯片的晶振(其实定时器的原理也就是晶振的实现)
如图:
然后初始化函数就实现了,但是,可以发现他缺少了总开关EA=1还有定时器开关ET0 = 1的声明所以我们要在之后加上去,这才是正确的。
好了我对定时器和中断程序设计的笔记到这了,希望大家都有所收获