【51单片机学习过程记录】8 中断 之定时计数器0的使用

来源:互联网 发布:ubuntu php模块 编辑:程序博客网 时间:2024/04/30 06:24

声明:【51单片机学习过程记录】全是我自己学习、实践所记录的过程,我只是菜鸟,所有论点和观点仅代表我个人,不能确定是这个技术的真理。我的目的是学习和有可能成为可以向别人分享的经验,因此有错误我会虚心接受,并认真改正。



1 定时计数器0的实现代码

/******************************
这是由reg52.h头文件内定义的IP,可以看到interrupt 0是 外部中断0,interrupt 1时 定时计数器0  
sbit PT2   = IP^5;
sbit PS    = IP^4;
sbit PT1   = IP^3;
sbit PX1   = IP^2;
sbit PT0   = IP^1;
sbit PX0   = IP^0;
******************************/

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int


void delay(uint x)
{
uint i,y;
for(i=x;i>0;i--)
for(y=210;y>0;y--);
}


void main()
{


//IE寄存器

P1=0xff;

EA=1; //全部中断使能

ET0=1; //定时计数器0使能


//TMOD寄存器

TMOD=0x01;  //16位计时器


//TCON寄存器

       TR0=0;            //关闭计数器


//TH0和TL0寄存器


/***************

单片机所用频率12M(11.0592M) ;

频率倒数为 时钟周期 1/12M;

51单片机的机器周期是 12*(1/12M),即12/12000000s 就是51单片机的机器周期,为1us(1微妙)。

计时器加1,用时 1us。

也就是说,16位计时器,可以设定最长为 2^16 * 1us 的中断时间(16位计时器加1是以二进制数方式存放),

而要设定 2^16 *1us 这个时间(65.536ms),则需要将TH0 和TL0 都清空,使这个16位计时器从0开始加1,

直到溢出,从而产生定时中断。

那么,假设要设定时时间为50ms,也就是说计数器要加x次,使得 x*1us =50ms,得x=50000 。

即当设定定时时间为50ms,计数器要加 50000 次,然后到溢出(满载的2^16),从而产生定时中断。

所以,TH0 TL0的初始值应该设置为 2^16-50000=15536。

然后,将设定的值,分配到TH0和TL0,其中高八位分给TH0,低八位分给TL0。

TH0=15536/(2^8)

TL0=15536%(2^8)

***************/


TH0=15536/256;  //设定定时初值,定时50ms

TL0=15536%256;

TR0=1;                     //开启计数器

while(1);        //while(1)的作用是等待中断  

}


void time0() interrupt 1                    //中断函数,因为定时计数器0中断时中断1
{

uchar i;

i++;


TH0=15536/256;           //中断一次之后,重新给计数器装载初始值 

TL0=15536%256;


if(i==20)                                   //中断20次,也就是1s后,led灯变化

{

i=0;

P1=~P1;;

}


}


2 代码解释

为代码中的注释


3 定时计数器0的使用 小结

这篇文章是接着上一篇的,可以发现,这里多出现了TH0 和 TL0 这两个寄存器。

也就是说除了

IE

TMOD

TCON

IP

还有 TH0  TL0这两个寄存器需要配置,而且很重要,因为它们是为了设置定时时间。


上面的程序例子,求出定时时间要赋的值是15536 ,但是如何将其赋予  TH0 和TL0 ?


这里再唠叨一下,说下自己的理解:

因为在TMOD设置的是16位的计数器,它包括高8位和低8位,其中高8位 即TH0,  低8位即  TL0 ,定时所设初始值就是存放在这个由TH0和TL0组成的16位计数器里面。

相信初学者或者如我般菜鸟刚开始很难理解为什么  

赋值于 高8位TH0 是     15536/2^8

赋值于低8位TL0是       15536%2^8


其实,原理就是是我们当初学习如何将10进制数 转变成  2进制数。

只是编程这里有的几个概念让我们思考模糊和不确定,像赋值、高8位、低8位、TH0、TL0。

粗暴简单来说,就是将一个你设定定时时间的 10进制数(15536)  转化成  一个2进制数(11 1100 1011 0000),然后将这个2进制数放在你在TMOD选择设定的16位也好8位也好的计数器里面,然后这个16位的计数器高8位是一个寄存器叫做TH0,低8位也是一个寄存器叫做TL0,

它们就是用来填放那个转化出来的2进制数(11 1100 1011 0000)的。

所以,完全可以先把15536变成 2进制数 11 1100 1011 0000 ,然后将11 1100 =60 赋值给TH0 , 1011 0000 =176 赋值给TL0。

再清晰点,其实如果专门有一个不分高8位TH0和 低8位TH0,而是直接给出一个 16位计数器寄存器 TXX0,那么直接就是TXX0=15536 就可以了。


因此对于 / 取整  %取余,原因是因为16位的二进制数是由两个8位的寄存器去 分开存放,所要进行的操作。

 

再有,为什么可以直接用15536/256  15536%256 赋值给TH0和TL0,不用转换成二进制,是的,这里的操作不用我们手动去转换,这里的转换操作是单片机自动操作的。



0 0
原创粉丝点击