精确定时是用单片机内的定时器好还是时钟芯片好

2020-02-05 08:53发布

刚看了一个帖子http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4056474&bbs_page_no=1&search_mode=1&search_text=定时&bbs_id=9999
好像用单片机内的定时器定时会有误差,是这样吗?误差来源是什么呢?定时器不是1微妙加一计时的吗? 怎么会有误差呢?我用过方式2,就是那种自动重装载的方式,用protues仿真运行一个小时,好像也看不到误差啊?
    要是用时钟芯片,会不会降低系统的稳定性呢?毕竟多了一部分电路,且在单片机外部,在工控场合会不会容易受到干扰而计时不准呢?
帖子内容如下:
/********定时器T0中断函数**********/
void t0(void) interrupt 1  
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;//这样的定时数据,是不是正好是50000*1微秒=50毫秒?
aa++;
if(aa==18)//这里的意思是中断18次,需要1秒的时间(晶振12MHz),我怎么感觉应该是中断20次用时1秒?
  {
    aa=0;
    miao++;
    if(miao==60)
    {
      miao=0;
      fen++;
       if(fen==60)
        {
           fen=0;
           shi++;
          if(shi==24)
             shi=0;
        }
    }
  }

----------------问题附在注释里面,请指点一下,看看这个18是怎么算的吧!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
76条回答
millwood0
1楼-- · 2020-02-11 01:26
"使用自动重载"

even if you don't use auto reload, you can still make the timing incredibly accurate, if you code carefully.

see the example I posted earlier. Its long-term accuracy depends only on the crystal.
banyai
2楼-- · 2020-02-11 04:49
我想,对于单片机,只要有一个定时器,可以赋初值,无论它可不可以重载,做RTC都只取决于晶振的精度,与其它无关,因为指令的执行时间和中断时间都是可测的,采用汇编就可以精确的控制定时器的时间。
XA144F
3楼-- · 2020-02-11 05:32
回复【49楼】telefunken  德律MM
老子.......
各种放屁啊....
呃..我错了...粗口了....
单片机自己的内部的时钟究竟有多精密,诸君看过datasheet没有.很多片子内部时钟都是1%误差起步啊,居然还在这里谈论精密,有个啥意义哦.
-----------------------------------------------------------------------

我从来不用单片机内部的RC,为了省钱也不会这样。
millwood0
4楼-- · 2020-02-11 06:28
 精彩回答 2  元偷偷看……
XA144F
5楼-- · 2020-02-11 12:02
回复【53楼】millwood0  
" th0=(65536-50000)/256;  
tl0=(65536-50000)%256;//这样的定时数据,是不是正好是50000*1微秒=50毫秒?  "
this way of setting timers is the biggest mistake that contributes to bad timing.
the reason is fairly simple: because of interrupt latency / context saving associated with entering an interrupt, by the time your code executes to this point, it is likely that the timer has advanced to a point where tl0 has some va......
-----------------------------------------------------------------------

我想不是。先记录了50000计数,溢出、进入中断程序,重新赋值,再计数50000……
millwood0
6楼-- · 2020-02-11 14:44
the following hopefully will help you all understand the issue here.

this is a shot of single stepping through an AVR timer interrupt service routine. I stop'd the code right after it entered the isr, before executing the first statement.

on the right, I was showing the value of the timer / counter, TCNT0. The timer here works similar to the C51 timer: once TCNT0 hits a pre-set value (100 here and 0x100 in the case of a C51 8-bit timer), it rolls over and fires an interrupt.

so TCNT0 was just reset and that triggered the interrupt.

because of latency and context saving, by the time we are to execute the very 1st user code in the isr, the timer has advanced from 0x00 to 0x19.

if you ignore the value of the timer / counter at this point, by writing an explicit value to it, you would have created timing errors.

instead, you should simply increment or decrement the timer, as suggested earlier.



(原文件名:avr tmr isr.PNG)

一周热门 更多>