单片机定时器中断实现LED灯闪烁程序

来源:本站
导读:目前正在解读《单片机定时器中断实现LED灯闪烁程序》的相关信息,《单片机定时器中断实现LED灯闪烁程序》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《单片机定时器中断实现LED灯闪烁程序》的详细说明。
简介:运用定时器0工作在方式1(16位计数器)实现LED灯的闪烁。先来看看定时器0工作在方式1的逻辑结构图。 从上图可以看到,GATE先经过非门,再和INT0引脚作为或门的输入。这里简单提一下数字电路中的与门、或门和非门。顾名思义,与门当且仅当所有输入都位高电平......

运用定时器0工作在方式1(16位计数器)实现LED灯的闪烁。先来看看定时器0工作在方式1的逻辑结构图。

单片机定时器中断实现LED灯闪烁程序

从上图可以看到,GATE先经过非门,再和INT0引脚作为或门的输入。这里简单提一下数字电路中的与门、或门和非门。顾名思义,与门当且仅当所有输入都位高电平时输出才是高电平,或门只要有其中之一输入是高电平则输出就是高电平,非门的输出电平状态刚好和输入电平状态相反。因此从定时器0方式1的逻辑结构图中,当GATE=0,且TR0=1时,TL0低8位寄存器便在机器周期的作用下开始加1计数。当TL0计满之后向TH0进位,直到TH0也计满,此时再来一个计数,计数器便溢出TF0置1,发出定时器0中断申请。

在清楚定时器的工作方式之后,重点就是如何让定时器定时我们想要的时间呢?这就涉及到定时器的初值问题。定时器一旦启动,便在TL0和TH0原来的基础上开始每隔一个机器周期加1操作直到溢出。假设在程序开始执行时TL0和TH0的初值都是0,单片机的晶振是12MHz,那么该单片机的机器周期就是1us,计满TL0和TH0一共需要(2的16次方减1=65535)个数,再来一个加1就溢出。也就是说定时器最多可以定时的时间是65536us(65.536ms),可想而知如果我们需要定时器能够定时50ms的话,那么TL0和TH0必须有一定的初值。通俗的理解就是定时器的16位计数器是个水桶,这个水桶最多能够倒满65.536斤水,而我们只需要往水桶里到50斤水就把水桶倒满,这个时候水桶里必须要有15.536斤水,这就是初值。

好,这里我们就正式开始如何确定定时器的初值,我们要让定时器定时50ms就产生一次中断,这个时候TL0和TH0装入的总数就是65536-50000=15536,把15536对256取模:15536/256=60装入TH0中,把15536对256求余:15536%256=176装入TL0中。这样就得到我们想要的初值了。

那么为什么这样算呢?之前已经说过定时器0工作在方式1时是16位的计数器,其中TH0是高8位,TL0是低8位,单片机复位时TL0和TH0初值如下图所示,每一位的值都是二进制(要么是0要么是1),当TL0计满之后向TH0进位,TH0计满后再加1就申请定时器中断。

单片机定时器中断实现LED灯闪烁程序

TL0计满一次时8位值都是1,也就是255(2的8次方减1),再来一个加1时TL0全部清零向TH0进位,也就是说此时TL0中的值是0000 0000,而TH0中的值是0000 0001,这个时候是计数256次;同样的等到TL0第二次计满时8位值都是1,再来一个加1时TL0全部清零向TH0进位,也就是说此时TL0中的值是0000 0000,而TH0中的值是0000 0010,这个时候是计数2*256次,依次类推,当计满256*256次时溢出。大家看出规律了吗?

好,我们继续讲任何一种情况,假设TL0中的初值是十进制L,TH0中的初值是十进制H,那么经过(256-L)次计数后TH0中的值加1变成H+1,TL0中的值变成0;再经过256次计数后TH0中的值变成H+2,TL0中的值变成0。依次类推,当TH0加了(256-H)次1时发生溢出,定时器请求中断。

因此一共经过了【(256-H-1)*256+256-L】=(65536-256H-L)次计数定时器请求中断。也就是说定时器中的16位寄存器的初值C=256H+L。

很明显TH0中的初值H=C/256,而TL0中的初值L=C%256,这就推导出来了。

搞定了定时器初值的问题,接下来我们就可以写定时器中断的代码了。

中断服务程序的写法

C51的中断函数格式如下:

void 函数名() interrupt 中断号 using 工作组

{

中断服务程序具体内容

}

中断函数没有返回值和参数,函数名只要符合C语言标准就可以,中断号是指单片机中的中断源序号,是编译器识别不同中断源的唯一凭证,using工作组是指这个中断服务程序使用单片机内存中4组工作寄存器的哪一组,由编译器自动分配,通常我们可以忽略不写。

讲了这么多,终于可以写程序了,是不是有点小激动呢?

#include //包含头文件

sbit led = P0^0;

unsigned char count = 0; //定时累计变量,我们需要1000ms定时,50 * 20 = 1000

//count是全局变量,通俗地说就是程序每次重新执行时值保持住最近一次的值

//后续会专门讲讲C语言的一些基础知识

void main()

{

TMOD = 0x01; //设置定时器0工作方式1,16位计数

TH0 = (65536 - 45872) / 256; //晶振11.0592MHz,定时50ms时TH0初值

TL0 = (65536 - 45872) % 256; //晶振11.0592MHz,定时50ms时TL0初值

EA = 1; //开启总中断

ET0 = 1; //开启定时器0中断

TR0 = 1; //启动定时器0

while(1); //程序停止,等待定时器0中断发生

}

void T0_INT() interrupt 1 //大家对照着上述格式看看

{

TH0 = (65536 - 45872) / 256; //晶振11.0592MHz,定时50ms时TH0初值

TL0 = (65536 - 45872) % 256; //晶振11.0592MHz,定时50ms时TL0初值

//重装初值,这个很好理解,我们需要每次定时的时间相同

count++; //每进入一次中断,也就是说50ms时间到了,count变量进行累计

if(20 == count) //1000ms定时时间到

{

count = 0; //清零,使得可以再次定时1000ms

led = ~led; //P0.0电平取反,也就实现LED灯的熄灭或者点亮

}

}

单片机定时器中断实现LED灯闪烁程序

好了,到这里定时器中断实现LED灯间隔1s闪烁就实现了

提醒:《单片机定时器中断实现LED灯闪烁程序》最后刷新时间 2024-03-14 00:54:13,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《单片机定时器中断实现LED灯闪烁程序》该内容的真实性请自行鉴别。