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

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条回答
wajlh
1楼-- · 2020-02-06 14:26
回复【11楼】takashiki  岚月影
我很奇怪,为什么51做不到精确定时?我的小弟也是这么说,我面试过几个,也这么说。但是我自己却从来都是认为51的定时器和时钟芯片的误差是一样的,误差的来源仅仅取决于振荡器。若要定时精确,就选用好的振荡器。
很是不明白为什么总以51的t0说事,52(现在基本上都是标准的52居多吧)是有t2定时器的,自动重载,何来的中断引起的误差?
我面试那些不知道有t2的都被我刷掉了,哈哈。
-----------------------------------------------------------------------
就你这点水平还面试别人,多少人被你冤枉掉了?误差不是来自于计数过程,而是来自于中断执行过程,跟自动重载有何关系?你大学老师没教你?今天心情好免费教你。51单片机中断响应机制就是“等待当前指令执行完毕再响应中断”,中断时随机发生的,所以当前指令时随机的,如果赶上单片机在执行除法指令,那么需要四个机器周期之后,中断才能执行,也有可能当前指令刚好执行完毕,无需等待即可响应中断程序。所以说最大误差4个机器周期。还不明白的话自己好好看看“51单片机中断响应过程”。
takashiki
2楼-- · 2020-02-06 14:46
回复【13楼】hsztc  
-----------------------------------------------------------------------

T0、T1的自动重载时是8位的,中断频率太快,最多256机器周期就中断一次,过于频繁了。T2重载是16位的,可以明显减少中断执行的频率。



回复【14楼】wajlh  
-----------------------------------------------------------------------
就你这点水平还面试别人,多少人被你冤枉掉了?误差不是来自于计数过程,而是来自于中断执行过程,跟自动重载有何关系?你大学老师没教你?今天心情好免费教你。51单片机中断响应机制就是“等待当前指令执行完毕再响应中断”,中断时随机发生的,所以当前指令时随机的,如果赶上单片机在执行除法指令,那么需要四个机器周期之后,中断才能执行,也有可能当前指令刚好执行完毕,无需等待即可响应中断程序。所以说最大误差4个机器周期。还不明白的话自己好好看看“51单片机中断响应过程”。


请你把51结构看清楚一次,尤其是自动重载部分。误差到底是不是来自中断执行过程。在定时器自动重载时,不管是不是有中断,都不会有误差的。已经由硬件完成的东西,你扯什么中断,有意义吗?
例如:
RCAP2 = 0x1000
那么,等到(TH2, TL2)=0xFFFF向上计数到0000时,(TH2、TL2)溢出并重载成0x1000,此时产生中断,不管你当前指令占用多长时间,进入中断进行跳转,保护现场到底用了多长时间,定时器还是一直在走,怎么会引起误差呢?


就凭你“所以说最大误差 4个机器周期。”就凭你这句话,就凭你这点水平,我就可以在面试时刷掉你了,一点也不冤枉你。学院派的吧?应该看书的应该是你吧?

举例:
我的系统中含有INT0中断、T0中断、×××中断一批。出于实时性的考虑,INT0中断优先级最高。
现在,INT0中断正在执行过程中,假设耗时100个机器周期,此时T0中断了,你给出一个T0中断最大误差4个机器周期的程序我看看。

误差不是来自于计数过程,而是来自于中断执行过程,跟自动重载有何关系?
好,退一步,我就认为你所谓的“误差来自中断执行过程”一下。我好像没说过误差来自计数过程吧,我是说来自振荡器。你看清楚了没有?你保证你的振荡器没有误差?
中断执行过程的任意时间运行那条指令你能保证?会不会被其他中断所中断?

书本知识都是有前提的,你随便应用到所有场合,行吗?



回复【2楼】wajlh  
软件延时可以做到精确,用中断不可能做到精确,因为51单片机每次进中断所用的时间是不固定的,最长4个机器周期,最短1个机器周期。12m晶振的话,误差就是3us。
-----------------------------------------------------------------------
再来打击你一下。软件延时精确?我给其他人做延时时都特别说明软件延时极其不可靠,可能会被中断。就算我写的《单片机大杂烩》软件中有软件延时的部分,也特别提到软件延时不精确,尽量少用。这还精确?
wajlh
3楼-- · 2020-02-06 17:51
回复【15楼】takashiki  岚月影
-----------------------------------------------------------------------
实践需要理论支持的,关于软件延时准确确实是在没有中断的情况下的。

来自于晶体振荡器的误差无论采取何种方法都是一样的,这个没有疑问,也不是这里讨论的。这里讨论的是定时器定时到底是否精确。看准了题目。
假设你需要每过100ms对P1.0口取反,12M晶振的前提下,你用定时器能实现输出波形周期精确到1us?


举例:
我的系统中含有INT0中断、T0中断、×××中断一批。出于实时性的考虑,INT0中断优先级最高。
现在,INT0中断正在执行过程中,假设耗时100个机器周期,此时T0中断了,你给出一个T0中断最大误差4个机器周期的程序我看看。
————————————————————————————————
你这个例子不恰当吧,INT0优先级最高,那么T0的中断子程序必须要等到INT0中断程序执行完才能执行,你在否定你自己?中断从产生到执行是需要时间的,好好看看,51单片机中断的执行过程。
takashiki
4楼-- · 2020-02-06 19:55
假设你需要每过100ms对P1.0口取反,12M晶振的前提下,你用定时器能实现输出波形周期精确到1us?

鉴于这个题目的变态性,变态解法:

每一步都精确到1us也能做到,只是没有意义。N步平均值精确到1us要做到很容易。

每一步都精确到1us的做法:
前提:T2可以直接在P1.0输出时钟。
关了中断,让T2自由定时计数(递增、递减都可以,比如每次10ms吧),那么9次之后,再改变T2的T2CAP以及控制模式,搞定。
little_Monkey
5楼-- · 2020-02-07 00:36
 精彩回答 2  元偷偷看……
wajlh
6楼-- · 2020-02-07 05:53
不管变不变态,这里讨论的是中断能不能做到精确定时。上两个仿真图吧,看图说话。第一个图式软件实现的延时,第二个图是定时器中断的方式实现的延时。
看到最大4个机器的误差了吧。


软件延时50us对P1.0取反效果 (原文件名:软件延时1.JPG)


中断延时50us对P1.0取反效果 (原文件名:中断延时1.JPG)

一周热门 更多>