请教,谁能够形象的告诉我定时器的工作原理?

2020-02-04 09:11发布

兄弟我学习单片机有点闹着玩的意思,没有下多少苦功夫去研究。只是在睡觉之前,或者是有空的时候去看看书。

半路出家,现在对一个定时器的工作原理给搞蒙了,其他的都还理解,唯独这个实在不懂,看了很多书,很多介绍都于事无补。

大家伙在嘲笑我之余,能否形象的告诉我定时器工作原理吗?

本来想绕过这一段,回头来看看也许会懂,可是居然搞懂了串口原理之后都还不懂定时器。妈的,用上定时器的都懂了居然还不懂定时器,搞笑。

我看了一下,用定时器的地方特别多,看来必须搞懂这个之后才能进行下一步了,万望大伙儿赐教。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
20条回答
wctmdgcd
2020-02-04 14:53
本帖最后由 wctmdgcd 于 2012-4-15 08:36 编辑

看过LZ玩锅头接收星星信号看电视的帖子,甚是拜服,还以为LZ也懂得单片机的呢。。。

我试着去描述一下,还望拙劣的表达能力能奏效。。。

就拿51的定时器0来作例子:定时器0的本质是一个16位计数器,当这个计数器输入系统的时钟信号对他进行加1时,由于时钟的频率是预知的,那么就可以利用这一点进行定时,
所以这样就实现了定时器的功能。由于2的16次方为65536,所以当计数器从0的初值开始进行输入时钟信号,当输入了65536个时钟信号之后这个16位的计数器的值又归为零了。
还是拿生活的一个例子进行比喻吧:就好像有一个能装得下65536碗水的一个锅,当你以固定的1秒钟装一碗的频率往这个锅里面装水,那么你就可以算得出来你从空锅开始到装满这个锅就是要65536秒了。当然,这个锅的水不会在装满了65536碗水就会自动清掉这里面的水,这里只是拿来作比喻罢了。
下面再说明一下,是以定时器0工作模式1来写的
在单片机应用编程时,定时器0往往与中断结合在一起用的,当你设定系统时钟为计数器0(定时器0)的输入源的的话,如果你开启了定时器0的中断(ET0=1)和总中断(EA=1),
那么,当计数器0(定时器0)在计满65536个脉冲归零的一个过程,单片机就会为计数器0(定时器0)专门产生一个中断,单片机就会跳到这个中断服务的入口地址执行
中断服务程序(这个中断服务程序是由程序员编写的)。。

C语言的例子
#include<reg452.h> //设置外部晶振为12M
void main(void)
{
       TMOD=0x01;   //设置定时器0工作在工作模式1
       TH0=0;
       TL0=0;         //计数器0(定时器0)的初值为0
       ET0=1;          //开计数器0(定时器0)的中断
       EA=1;        //开总中断
       TR0=1;       //打开计数0(定时器0)输入脉冲的开关
       while(1);      //主程序一直在此空循环了
}

void ISRTimer0(void) interrupt 1     // 综合算起来,这样就了约每65.536毫秒就执行一次这个中断服务函数,达到定时的效果了
{
        TH0=0;
       TL0=0;         //计数器0(定时器0)的初值为0     
      //在这里可以写你的中断需要执行的语句  
}


当然,计数器0(定时器0)由初值为0时,输入65536个脉冲可以产生65.536毫秒的定时,那么当我预先向这个计数器装了15536(65536-50000),那么这个计数器0(定时器0)再输入50000
个脉冲也就会归零接着就产生中断了,这中断是每50毫秒产生一次,这样就可以通过装不同的初值来达到定时不同时长的效果了,据此举例如下:

#include<reg452.h> //设置外部晶振为12M
void main(void)
{
       TMOD=0x01;   //设置定时器0工作在工作模式1
       TH0=15536/256;            //只取高八位
       TL0=15536%256;         //只取低八位
       ET0=1;          //开计数器0(定时器0)的中断
       EA=1;        //开总中断
       TR0=1;       //打开计数0(定时器0)输入脉冲的开关
       while(1);      //主程序一直在此空循环了
}

void ISRTimer0(void) interrupt 1     // 综合算起来,这样就了约每50毫秒就执行一次这个中断服务函数,达到定时的效果了
{
       TH0=15536/256;            //只取高八位
       TL0=15536%256;         //只取低八位
      //在这里可以写你的中断需要执行的语句   
}

一周热门 更多>