分享

51单片机T0做精确时钟

 shenlx 2012-08-20
2010-12-03 11:02

51单片机T0做精确时钟

       用T0做精确时钟,为了做到尽量精确,必须减少中断的次数,所以选择使用方式1,它最多可以计数65536次。但是,方式1中断后需要重新给定时器赋初值,这样就要耽误几个机器周期,很难保证时钟的精确。

有两个方法可以解决这个问题。

       第一个方法:你可以计算出中断处理时重新给定时器赋初值所用的机器周期数,在你计算出的初值里除去这几个机器周期,作为补偿。这个方法,只是在每次定时器中断后,都可以按时得到执行时很精确,但事实上中断什么时候执行谁都说不准,所以这个方法,只能做到尽量精确。

      第二个方法:计算出一个凑巧的初值,使TL0正好等于0x00,这样每次中断溢出后,TL0都从0x00开始计数,即使中断没有得到执行,TL0也会继续计数。利用这一点,在中断处理函数中,只需要对TH0重新赋值,不需要管TL0。以下是示例程序:

//定时器T0时钟参数

unsigned char T0_S = 0;                   //秒

unsigned char T0_M = 0;                 //分

unsigned char T0_H = 0;                  //时

unsigned char T0_Cycle = 0;           //循环次数

//本程序所用晶振22.1184MHz,每次定时25ms,循环40次正好1s。

//22.1184/12*1000*25=46080
void Timer0_Init(void)           //T0初始化函数

{

TMOD = 0x01;                     //设置T0工作方式1

TH0 = 0x4c;                       //(65536-46080)/256,设置初值46080,晶振22.1184MHz,

                                                        //每个机器周期0.5425微秒,定时25ms

TL0 = 0x00;                        //(65536-46080)%256 ,TL0恰好=0x00

IE   |= 0x82;                        //开中断

TR0 = 1 ;                                     //T0开始定时

}

//

void Timer0(void) interrupt 1

{

TH0 = 0x4c;                       //重新给TH0赋值

//TL0 = 0x00;                       //不对TL0赋值,让其继续计数

TF0 = 0 ;                                      //定时溢出清0  

T0_Cycle ++ ;


if(T0_Cycle == 40)                        //循环40次,每次25ms,定时1s

{

           T0_Cycle = 0 ;            

           T0_S++ ;

           if(T0_S == 60)

           {

                    T0_S = 0;  

                    T0_M++;

                    if(T0_M == 60)

                    {

                             T0_M = 0;

                             T0_H++;

                                      

                             if(T0_H == 24)

                             {

                                       T0_H = 0;

                             }

                    }

           }                         

}

}

         以上程序即使T0中断赋初值会耽误几个机器周期,中断没有得到及时执行也没有关系,因为TL0的计数不受影响。但有一种情况必须要注意,虽然这种情况发生的可能性不大。如果T0中断长时间没有得到响应,TL0再一次溢出了,这时这种方法的误差就大了。

经过测试,第二种方法还是比较精确的,时钟跑了一天快了10s,这个误差应该是晶振本身的问题,如果是定时器的问题,应该是慢了,不会快了。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kulung/archive/2010/11/08/5995161.aspx


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多