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

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

问题

今天,在用12的时候,定时器无意之间debug竟然发现,定时不准?
查查查,,,一直没有头绪,还好没有放弃一直在苦苦挣扎。

过程再现

#include <stc12.h>
#include <intrins.h>

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~~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值