找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1425|回复: 9
收起左侧

关于51单片机的定时/计数器的疑惑,大佬们解决下菜鸟的疑惑

[复制链接]
ID:653298 发表于 2020-7-22 10:41 | 显示全部楼层 |阅读模式
就是下面的程序,我感觉是我不按k1,定时器应该也工作吧。这样的话通电后在隔一段时间再按k1,不是应该s不为0吗?
为什么隔了一段时间这个s还是。

单片机源程序如下:
  1. /*****定时器0与外部中断1制作计时器:够60秒则进为分,够60分则进位时*****/
  2. /*当按下k1键计时器开始工作,当按下k4键,定时器停止,再按一次k4,继续定省
  3. 当按下k3,定时器归0;再次按下k4,定时器开始定时。*/
  4. #include"reg52.h"
  5. typedef unsigned int u16;
  6. typedef unsigned char u8;
  7. sbit key1=P3^3;
  8. sbit key2=P3^1;
  9. sbit key0=P3^2;
  10. u16 s=0;u16 m=0;u16 h=0;
  11. u16 i,c;
  12. u16 code weixuan[8]={0xe3,0xe7,0xeb,0xef,0xf3,0xf7,0xfb,0xff};//位选数组:数码管第一个到最后一个
  13. u16 code smgduan[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//显示0—9最后有一个显示-
  14.                      //0  ,  1  , 2,  3,   4,    5,   6,   7,   8,   9,   —
  15. void delay_ms(u16 j)
  16. {
  17.         while(j--)
  18.         {
  19.                 u16 b;
  20.                 for(b=0;b<125;b++);
  21.         }
  22. }
  23. void time1()
  24. {
  25.         TMOD|=0x10;
  26.         TH1=0xFC; //给定时器赋初值定时1ms
  27.         TL1=0x18;
  28.         ET1=1;
  29.         TR1=1;
  30.         EA=1;
  31. }
  32. void zhongduan1()
  33. {
  34.         IT1=1;
  35.   EX1=1;
  36.   EA=1;
  37. }
  38. void zhongduan0()
  39. {
  40.         IT0=1;
  41.   EX0=1;
  42.   EA=1;
  43. }
  44. void shuma()
  45. {
  46.         u16 a;
  47.         for(a=1;a<9;a++)
  48.         {
  49.                 switch(a)
  50.                 {
  51.                         case(1):P2=weixuan[0];P0=smgduan[s%10];break;
  52.                         case(2):P2=weixuan[1];P0=smgduan[s/10];break;
  53.                         case(3):P2=weixuan[2];P0=smgduan[10];break;
  54.                         case(4):P2=weixuan[3];P0=smgduan[m%10];break;
  55.                         case(5):P2=weixuan[4];P0=smgduan[m/10];break;
  56.                         case(6):P2=weixuan[5];P0=smgduan[10];break;
  57.                         case(7):P2=weixuan[6];P0=smgduan[h%10];break;
  58.                         case(8):P2=weixuan[7];P0=smgduan[h/10];break;
  59.                 }
  60.                 delay_ms(1);
  61.                 P0=0x00;
  62.         }
  63. }
  64. void main()
  65. {
  66.         time1();
  67.         zhongduan1();
  68.         zhongduan0();
  69.         if(key2==0)delay_ms(6);//按下k1,主函数中的数码管函数开始执行,定时器开始工作
  70.         {
  71.                 if(key2==0)
  72.                 {
  73.                         while(1)
  74.                         {
  75.                                 shuma();
  76.                         }
  77.                 }
  78.           while(!key2);
  79. }
  80. }
  81.         
  82. void waibu0()interrupt 0//外部中断函数0,按下k3,s,m,h都归0;
  83. {
  84.         if(key0==0)
  85.         {
  86.                 delay_ms(6);
  87.                 if(key0==0)
  88.                 {
  89.                         s=0;m=0;h=0;
  90.                 }
  91.         }while(!key1);
  92. }
  93. void waibu()interrupt 2//外部中断函数,按下k4,定时器停止工作,再次按下k4继续工作
  94. {
  95.         if(key1==0)
  96.         {
  97.                 delay_ms(6);
  98.                 if(key1==0)
  99.                 {
  100.                         TR1=~TR1;
  101.                 }
  102.         }while(!key1);
  103. }
  104. void time1_()interrupt 3//定时器中断函数每一秒s加1,够60s则s变为0,m加1;
  105. {
  106.         TH1=0xFC; //给定时器再次赋初值
  107.         TL1=0x18;
  108.         i++;
  109.         if(i==1000)
  110.         {
  111.                 i=0;
  112.                 s++;
  113.                 if(s==60){m++;s=0;}
  114.                 if(m==60){h++;m=0;}
  115.         }
  116. }

复制代码


回复

使用道具 举报

ID:451718 发表于 2020-7-22 16:07 | 显示全部楼层
k3 和 key0 是什么关系?  k4 和 key1 是什么关系?  k2和key0 又是什么关系?  感觉你这个程序,硬件和定义的端口好混乱啊。 外部中断触发以后,如何回现场?  你这个框架,怎么感觉一直在中断里面跑?  程序早就跑飞了吧
回复

使用道具 举报

ID:332444 发表于 2020-7-22 16:13 | 显示全部楼层
主函数,控制显示代码逻辑问题。
回复

使用道具 举报

ID:332444 发表于 2020-7-22 16:15 | 显示全部楼层
本帖最后由 xianfajushi 于 2020-7-22 16:20 编辑

纠正一下:
  1. void main()
  2. {
  3.         time1();
  4.         zhongduan1();
  5.         zhongduan0();
  6.         if(key2==0)
  7.         {
  8. delay_ms(6);//按下k1,主函数中的数码管函数开始执行,定时器开始工作
  9.                 if(key2==0)
  10.                 {
  11.                         while(1)
  12.                         {
  13.                                 shuma();
  14.                         }
  15.                 }
  16.           while(!key2);
  17. }
  18. }
复制代码

这样的代码逻辑只有按住这个按键,释放按键,再按住按键,再释放按键,才能实现动态显示。
回复

使用道具 举报

ID:332444 发表于 2020-7-22 16:22 | 显示全部楼层
也就是key2按一下显示更新一下。
回复

使用道具 举报

ID:653298 发表于 2020-7-22 16:31 | 显示全部楼层
robinsonlin 发表于 2020-7-22 16:07
k3 和 key0 是什么关系?  k4 和 key1 是什么关系?  k2和key0 又是什么关系?  感觉你这个程序,硬件和定 ...

他不应该是外部中断1打断定时/计数器1,然后外部中断0打断外部中断1,外部中断0完了就返回外部中断1,然后外部中断0完了,推出去?
回复

使用道具 举报

ID:653298 发表于 2020-7-22 16:34 | 显示全部楼层
xianfajushi 发表于 2020-7-22 16:22
也就是key2按一下显示更新一下。

你说的这个改了,谢谢
回复

使用道具 举报

ID:451718 发表于 2020-7-22 17:26 | 显示全部楼层
fengbaobaohaha 发表于 2020-7-22 16:31
他不应该是外部中断1打断定时/计数器1,然后外部中断0打断外部中断1,外部中断0完了就返回外部中断1,然 ...

你这样做,架构是不科学的,以后想扩展都没有办法。 理论上是可以实现你想要的功能,但是,实际电路中如果有干扰,跑飞的几率是非常高的,可靠性很低。 而且,程序读起来很烧脑。  你今天做的逻辑架构,过段时间再看的时候,又要去读半天才理解。
回复

使用道具 举报

ID:653298 发表于 2020-7-22 18:34 | 显示全部楼层
robinsonlin 发表于 2020-7-22 17:26
你这样做,架构是不科学的,以后想扩展都没有办法。 理论上是可以实现你想要的功能,但是,实际电路中如 ...

原来如此,谢谢大佬
回复

使用道具 举报

ID:797247 发表于 2020-7-23 20:15 | 显示全部楼层
逻辑不太对
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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