×
嵌入式 > 技术百科 > 详情

关于解决12单片机定时竟然不准的问题

发布时间:2022-04-12 发布时间:
|

自己不断的折腾确实挺浪费时间的,但是真的收获颇丰。


问题


今天,在用12的时候,定时器无意之间debug竟然发现,定时不准? 

查查查,,,一直没有头绪,还好没有放弃一直在苦苦挣扎。


过程再现


#include

#include


unsigned char T0RH;

unsigned char T0RL;


/* 配置并启动T0,ms-T0定时时间 */

void ConfigTimer0(unsigned int ms)

{

    unsigned long tmp;  //临时变量


    AUXR &= 0x7F;       //定时器时钟12T模式 

    tmp = 12000000 / 12;      //定时器计数频率

    tmp = (tmp * ms) / 1000;  //计算所需的计数值

    tmp = 65536 - tmp;        //计算定时器重载值

    //tmp = tmp + 12;            //补偿中断响应延时造成的误差

    T0RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节

    T0RL = (unsigned char)tmp;

    TMOD &= 0xF0;   //清零T0的控制位

    TMOD |= 0x01;   //配置T0为模式1

    TH0 = T0RH;     //加载T0重载值

    TL0 = T0RL;

    ET0 = 1;        //使能T0中断

    TR0 = 1;        //启动T0

}


void main()

{


    ConfigTimer0(1);


    EA = 1;

    while(1);

}


void InterruptTimer0() interrupt 1

{

    TH0 = T0RH;

    TL0 = T0RL;

}


设置型号以及晶振值 


  


计算两次中断的时间间隔 



第一次sec = 0.000453



第二次sec = 0.000704 


相差251us非1ms。


不科学对不对?


专门还查了手册,手册上写12就是IT单片机。T0上电部分默认为12T模式,用户也可通过AUXR寄存器来更改是IT还是12T!


这里先来了解一个东西,什么叫IT单片机,所谓的IT单片机就是一个机器周期就是一个时钟周期 


也就是一个nop()就是一个机器周期,也就是晶振频率分之1。 


实测如下: 



sec = 0.00045375 



sec = 0.00045383 


12M下一个机器周期为 1/12000000 = 8.3333333*10^8 


两者相差刚好就是一个机器周期,说明一个nop就是一个机器周期就是一个时钟周期,就是IT。 


但是,前面到底错在了哪里呢? 


keil跑的内核为intel公司制造的,所以选择intel旗下的80/87C52来代替即可! 


一切over,演示如下:



sec = 0.00234300 



sec = 0.00334900 


1ms多几个机器周期,补偿回来即可!


over~~~~

 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
NS推出采用第二代PowerWise技术的能源管理单元及先进电源控制器