找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4642|回复: 27
打印 上一主题 下一主题
收起左侧

51单片机写的一个秒表程序,但是发现单片机时间比手机秒表时间走得慢

  [复制链接]
跳转到指定楼层
楼主
ID:510532 发表于 2019-12-5 23:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
完整代码如下。还望各位知道的告知小弟一声是什么原因。
普中的板子
#include <REGX52.H>
sbit L1=P3^1;
sbit L2=P3^0;
unsigned char t_005s;
unsigned char t_s;
unsigned char t_m;
//==============================


void delay(unsigned int j)
{
  while(j--);
}


unsigned char code smg_duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                           0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};
unsigned char code smg_wei[]={0x00,0x04,0x08,0x0c,0x10,0x14,0x18,0x1c};
void display()
{
   P2=smg_wei[0];
   //delay(1000);
   P0=smg_duan[t_005s%10];
   delay(100);


   P2=smg_wei[1];
   //delay(1000);
   P0=smg_duan[t_005s/10];
   delay(100);


   P2=smg_wei[2];
   //delay(1000);
   P0=smg_duan[16];
   delay(100);


   P2=smg_wei[3];
   //delay(1000);
   P0=smg_duan[t_s%10];
   delay(100);


   P2=smg_wei[4];
   //delay(1000);
   P0=smg_duan[t_s/10];
   delay(100);


   P2=smg_wei[5];
   //delay(1000);
   P0=smg_duan[16];
   delay(100);


    P2=smg_wei[6];
   //delay(1000);
   P0=smg_duan[t_m%10];
   delay(100);


   P2=smg_wei[7];
   //delay(1000);
   P0=smg_duan[t_m/10];
   delay(100);

}


//=============================




void InitTimer0()
{
    TMOD=0x01;
    TH1=(65535-50000)/256;
    TH1=(65535-50000)%256;
    ET0=1;
    EA=1;
    TR0=1;
}


void ServiceTimer0() interrupt 1
{
          TH1=(65535-50000)/256;
    TH1=(65535-50000)%256;
        t_005s++;
        if(t_005s==20)
        {
           t_s++;
           t_005s=0;
           if(t_s==60)
           {  
             t_m++;
             t_s=0;
           }
           if(t_m==99)
           {
             t_m=0;
           }
        }
}


//=============================




void Scnkey()
{
  if (L1==0)
  {
     delay(500);
         if(L1==0)
         {
           TR0=~TR0;
         }
         while(L1==0)
         {
            display();
         }
  }


  if (L2==0)
  {
     InitTimer0();
     delay(500);
         if(L2==0)
         {
             t_005s=0;
                 t_s=0;
                 t_m=0;
         }
         while(L2==0)
         {
            display();
         }
  }
}




void main()
{
  while(1)
  {
     Scnkey();
     display();
  }
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:656419 发表于 2019-12-6 02:58 | 只看该作者
请参考一下这篇文章   http://www.51hei.com/mcu/696.html
一般如果是用循环延时使用12M的晶振要方便些,如果是定时器则是用11.0592的要方便和精确一些.
回复

使用道具 举报

板凳
ID:213173 发表于 2019-12-6 06:13 | 只看该作者
这是因为晶振频率精度不高或程序不合理引起的误差。
回复

使用道具 举报

地板
ID:584814 发表于 2019-12-6 07:58 | 只看该作者
你取的时基与单片机运行速度有关,可精确计算或用外部时钟。
回复

使用道具 举报

5#
ID:25310 发表于 2019-12-6 08:11 | 只看该作者

延时函数调整一下,延时太长时间会影响视觉效果。
回复

使用道具 举报

6#
ID:164602 发表于 2019-12-6 08:32 | 只看该作者
很正常。单片机计时很准的。但你没有考虑到:当计时达到后,还要执行一些语句,也是要用时间的,一次没有感觉,累积多了,误差就出来了。真的要走时准确,还得用仪器测量整个程序的运行时间,调整定时器才行。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

7#
ID:470332 发表于 2019-12-6 08:43 | 只看该作者
那么多delay能不慢吗
回复

使用道具 举报

8#
ID:332444 发表于 2019-12-6 08:51 | 只看该作者
正常,用外部时钟信号好点,若获取标准时钟矫正最佳。
回复

使用道具 举报

9#
ID:648281 发表于 2019-12-6 08:52 | 只看该作者
那就减少单片机延时
回复

使用道具 举报

10#
ID:235200 发表于 2019-12-6 09:12 | 只看该作者
把中断程序内 t_005s++;后面的语句移到主循环,或者修改定时时间小于50ms达到比较精确的目的
回复

使用道具 举报

11#
ID:94031 发表于 2019-12-6 09:22 | 只看该作者
如果误差不大应该调整定时器系数。
回复

使用道具 举报

12#
ID:636435 发表于 2019-12-6 09:53 | 只看该作者
计算好延迟,有时候影响很大。晶振对好,不同晶振也会不同。计时器搞好
回复

使用道具 举报

13#
ID:395176 发表于 2019-12-6 09:58 | 只看该作者
TH1=(65535-50000)/256;
TH1=(65535-50000)%256;
这两个什么鬼
回复

使用道具 举报

14#
ID:657323 发表于 2019-12-6 10:02 | 只看该作者
delay的时间没算你机器周期,稍微调整一下就可以了
回复

使用道具 举报

15#
ID:657325 发表于 2019-12-6 10:08 | 只看该作者
第一确认晶振是否是外部晶振,即晶振是否准确。
第二程序中使用了大量的延时函数会对你的时间造成非常大的影响,建议修改去掉试试。
回复

使用道具 举报

16#
ID:646543 发表于 2019-12-6 10:35 | 只看该作者
因为单片机执行语句需要一定时间,尤其是循环语句,不同的嵌套方式,就像长循环和短循环在内和在外都会有很大影响,一般把长循环放在内,短循环放在外,可以减少CPU跨切循环层的次数,减小响应延时。
回复

使用道具 举报

17#
ID:123289 发表于 2019-12-6 17:03 | 只看该作者
本帖最后由 yzwzfyz 于 2019-12-14 01:13 编辑

普通晶振即使精度不够,但稳定度也还是相当高的,时钟做到日差1秒之内没有问题。
关键看你的程序架构是否合理。
回复

使用道具 举报

18#
ID:657847 发表于 2019-12-6 21:43 | 只看该作者
程序有点问题,delay太多了,占内部空间
回复

使用道具 举报

19#
ID:465554 发表于 2019-12-7 12:28 | 只看该作者
程序运行也是需要时间的,一个循环下来,肯定与计算的时间不同
回复

使用道具 举报

20#
ID:658104 发表于 2019-12-7 12:32 | 只看该作者
主要是振荡器的原因引起的,和手机的秒表没有什么可比性,其实手机的秒表也不一定精确
回复

使用道具 举报

21#
ID:658203 发表于 2019-12-7 14:43 | 只看该作者
你程序写的不合理  有延时
回复

使用道具 举报

22#
ID:426861 发表于 2019-12-7 15:28 | 只看该作者
选好晶振,用定时器处理。时序要求越高,越忌用延时,尤其是长延时
回复

使用道具 举报

23#
ID:658332 发表于 2019-12-7 17:12 | 只看该作者
晶振的频率以及单片机执行指令的时间是有误差的
回复

使用道具 举报

24#
ID:658338 发表于 2019-12-7 17:45 | 只看该作者
建议:调整中断定时器的时间,尽量长些,例如500ms,这样CPU响应时间就可以忽略了。精度会很高。另外定时值要精准,不要有误差。这个需要选择晶振频率,及定时值配合,使得定时时间没有误差。最后,运行一小时,一天看看有没有误差,如果有,在程序里面就一个小时后调整一边。这样长期跑起来很小误差。

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

25#
ID:307020 发表于 2019-12-8 22:54 | 只看该作者
还要考虑这一堆程序代码运行时需要的指令周期,会累积进去,让两个不同的走得一样(同步)很麻烦的,所以须“不二法门”。
回复

使用道具 举报

26#
ID:640414 发表于 2019-12-9 09:21 | 只看该作者
一个是。。本身会有点误差。。误差累积起来就会有点差别了
还有一个就是 你的delay太多了。delay在调用的时候 实质上会比你想象的还要多耗时,(因为有误差,所以和第一点一样),误差累积起来,就会不准了
回复

使用道具 举报

27#
ID:656893 发表于 2019-12-9 15:14 | 只看该作者
跟硬件有关系,也就是跟一个机器周期的时间有关系,所以会有误差
回复

使用道具 举报

28#
ID:416239 发表于 2019-12-10 13:20 | 只看该作者
因为你程序的原因,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表