找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1086|回复: 18
收起左侧

51单片机为什么定时器计时会差这么多?

  [复制链接]
ID:1091094 发表于 2024-1-18 09:55 | 显示全部楼层 |阅读模式
我用手机秒表和它对比,手机60秒跑完了,仿真软件还剩下12秒没跑,差这么多吗?
屏幕截图 2024-01-18 095149.png

单片机源程序如下:
  1. #include "reg52.h"

  2. #define smgled P0

  3. unsigned char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

  4. int num=60,count=0;

  5. sbit smg1=P1^0;
  6. sbit smg2=P1^1;
  7. sbit KEY=P3^2;

  8. unsigned char flag=0;


  9. //定时10微秒
  10. void delay_10us(unsigned int ten_us)
  11. {
  12.         while(ten_us--);        
  13. }

  14. void main()
  15. {
  16.         TMOD|=0X01;//选择为定时器0模式,工作方式1
  17.         TH0=0X3C;        //定时50ms
  18.         TL0=0XB0;        

  19.         ET0=1;//打开定时器0中断允许
  20.         EA=1;//打开总中断

  21.         //外部中断0
  22.         IT0=1;
  23.         EX0=1;//打开INT0的中断允许
  24.         
  25.   flag=0;
  26.         
  27.         num=60;

  28.         while(1)
  29.         {

  30.                 smgled=0XFF;//清屏
  31.                 smgled=table[num/10];//显示十位
  32.                 smg1=1;
  33.                 smg2=0;
  34.                 delay_10us(500);
  35.                 smgled=0XFF;//清屏
  36.                 smgled=table[num%10];//显示个位
  37.                 smg1=0;
  38.                 smg2=1;
  39.                 delay_10us(500);
  40.                 if(flag)
  41.                                 TR0=1;//打开定时器        
  42.                 else
  43.                 {
  44.                         num=60;
  45.                         TR0=0;//关掉定时器
  46.                 }
  47.                 if(num==0)  //判断是否到达60秒
  48.                  {
  49.                          flag=0;
  50.                          num=60;
  51.                  }
  52.                 if(count==20)//判断是否到1秒
  53.                 {
  54.                         num--;
  55.                         count=0;
  56.                 }

  57.         }
  58. }



  59. void timer() interrupt 1
  60. {
  61.         TH0=0X3c;        //给定时器赋初值,定时50ms
  62.         TL0=0Xb0;
  63.         count++;

  64. }

  65. void exti0() interrupt 0 //外部中断0中断函数
  66. {
  67.         delay_10us(1000);
  68.         if(KEY==0)
  69.                 flag=!flag;                        
  70. }
复制代码

222、60秒倒计时秒表.rar (160.02 KB, 下载次数: 2)
回复

使用道具 举报

ID:628113 发表于 2024-1-18 10:06 | 显示全部楼层
是何原因我不清楚, 但是 在0级中断中 使用延时循环 出问题那是必须的。
回复

使用道具 举报

ID:1064915 发表于 2024-1-18 10:06 | 显示全部楼层
手机秒表和仿真软件,都不是准确时间,没什么可比性
回复

使用道具 举报

ID:192020 发表于 2024-1-18 10:35 | 显示全部楼层
1,外部中断0是上升沿中断还是下降沿中断?引脚也没初始化,有没有可能一直进入外部中断0
2,运行主频不知道,定时50ms是准的吗

评分

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

查看全部评分

回复

使用道具 举报

ID:1091094 发表于 2024-1-18 10:48 | 显示全部楼层
ppcbug 发表于 2024-1-18 10:06
是何原因我不清楚, 但是 在0级中断中 使用延时循环 出问题那是必须的。

为什么这么说呢?
如果外部中断的服务函数里面没有对按键进行消抖处理,那么flag值是不确定。
大家都是这么用得啊
回复

使用道具 举报

ID:1091094 发表于 2024-1-18 10:51 | 显示全部楼层
qq475878026 发表于 2024-1-18 10:35
1,外部中断0是上升沿中断还是下降沿中断?引脚也没初始化,有没有可能一直进入外部中断0
2,运行主频不知 ...

这个是51单片机,没有引脚模式选择的,也没有什么主频副频。
它就用一个晶振的。
回复

使用道具 举报

ID:384109 发表于 2024-1-18 10:56 | 显示全部楼层
代码编写方式问题
回复

使用道具 举报

ID:1090026 发表于 2024-1-18 11:05 | 显示全部楼层
3038838599 发表于 2024-1-18 10:51
这个是51单片机,没有引脚模式选择的,也没有什么主频副频。
它就用一个晶振的。

你知道你选择的晶振频率吗?延时长度根据晶振频率来计算出来的。程序运行一行需要时间,递减循环需要一定的时间
回复

使用道具 举报

ID:1090026 发表于 2024-1-18 11:08 | 显示全部楼层
3038838599 发表于 2024-1-18 10:51
这个是51单片机,没有引脚模式选择的,也没有什么主频副频。
它就用一个晶振的。

IT0=1 这个应该是下降沿触发
回复

使用道具 举报

ID:712097 发表于 2024-1-18 11:14 | 显示全部楼层
仿真不准确的。
回复

使用道具 举报

ID:213173 发表于 2024-1-18 11:28 | 显示全部楼层
仿真计时本来就不准确,主函数里有延时,如果恰巧错过 if(count==20),就要等下一轮。
回复

使用道具 举报

ID:192020 发表于 2024-1-18 11:34 | 显示全部楼层
3038838599 发表于 2024-1-18 10:51
这个是51单片机,没有引脚模式选择的,也没有什么主频副频。
它就用一个晶振的。

用晶振的话应该外接12M跑的才对,你应该是接了11.0592M吧
回复

使用道具 举报

ID:192020 发表于 2024-1-18 11:44 | 显示全部楼层
qq475878026 发表于 2024-1-18 11:34
用晶振的话应该外接12M跑的才对,你应该是接了11.0592M吧

算错,你看看仿真里面设置的,估计你设成了10M晶振
回复

使用道具 举报

ID:161164 发表于 2024-1-18 11:46 | 显示全部楼层
电脑越快,仿真时间越贴进现实
系统越复杂,仿真时间越慢
你要对比的应该时仿真运行时,左下角那个时计 2024-01-18_114617.png

回复

使用道具 举报

ID:458247 发表于 2024-1-18 14:35 | 显示全部楼层
3038838599 发表于 2024-1-18 10:48
为什么这么说呢?
如果外部中断的服务函数里面没有对按键进行消抖处理,那么flag值是不确定。
大家都是 ...

消抖也可以不通过延时函数去消的噢,可以1ms执行一次按键程序,进行时间累计,key按下累计10次也就是10ms,再输出按键值的,你在中断函数中用延时肯定是有问题的,这次还没执行完,下次中断又来了,就嵌套了
回复

使用道具 举报

ID:1091094 发表于 2024-1-18 19:35 | 显示全部楼层
wulin 发表于 2024-1-18 11:28
仿真计时本来就不准确,主函数里有延时,如果恰巧错过 if(count==20),就要等下一轮。

我把这些判断放在定时器0的中断服务函数里面也一样的
回复

使用道具 举报

ID:1091094 发表于 2024-1-18 23:50 | 显示全部楼层
lkc8210 发表于 2024-1-18 11:46
电脑越快,仿真时间越贴进现实
系统越复杂,仿真时间越慢
你要对比的应该时仿真运行时,左下角那个时计

很正确,我验证了,程序没有问题,不能拿手机和proteus仿真的时间直接比较。
感谢感谢
回复

使用道具 举报

ID:883242 发表于 2024-1-19 00:01 | 显示全部楼层
找到问题就好,也算是增长了经验,什么东西是仿真可以仿真出来的,什么是仿真不出来的。
回复

使用道具 举报

ID:332444 发表于 2024-1-19 09:50 | 显示全部楼层
仿真可以很准确的,看已经运行2个多小时依然不差秒的准确,不是读取时钟信息的,时钟信息只在仿真运行初期读取用来初始化的,是用定时器计时的.
无标题.png

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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