找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4877|回复: 16
收起左侧

STC89c52rc单片机4位数码时钟,4个按键是怎么设置时间的? 求帮助

[复制链接]
ID:476064 发表于 2019-4-1 15:43 来自手机 | 显示全部楼层 |阅读模式
手里有这个单片机也想做一个,但是仿真时 图上的4个按键是怎么设置时间的?有知道的大神说下
ourdev_714824ELCVI2.JPG
回复

使用道具 举报

ID:164602 发表于 2019-4-2 08:12 | 显示全部楼层
肯定没人能说的!因为你的问题不完整!
你的电路,必须配合你的程序。
你都在问是电路问题还是程序问题,程序呢?
从你的电路上看,你的时钟,只是使用定时器,没有专门的时间芯片,应该很简单。你说设置不了,我也没办法。
发程序来看看吧
回复

使用道具 举报

ID:476064 发表于 2019-4-2 01:18 来自手机 | 显示全部楼层
没人回答 不知道是程序问题还是我电路问题,就是设置不了时间这是在网上找的,也不知道是哪位大神之作。麻烦帮我修改下, 不求多么准!只求能正常运行和调整 !(我仿真时4个按键无用)
  1. #include <reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define DispOFF 10;        //显示关
  5. #define POINT 21;        //显示小点
  6. #define F 22;
  7. #define H 23;
  8. #define M 24;
  9. #define N 25;
  10. #define O 26;
  11. sbit buzzer=P3^7;        //蜂鸣器控制脚
  12. uchar T2Count;
  13. uint T0Count;
  14. uchar key,key_new,key_old,KeyPressTime;
  15. uchar status;
  16. uchar month,day,hour,min,sec,AlarmHr,AlarmMin;
  17. uchar LastDay;
  18. uchar AlmTime,AlmCount,DispTime;
  19. uchar CountHr,CountMin,CountSec,CountSetSta=0;
  20. uint year;
  21. bit TimeAdj,AlarmAdj,AlarmSta;
  22. bit adjust,DigiBit;
  23. //数码管显示代码
  24. uchar code LedCode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,
  25.                       0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x7f,
  26.                       0x8e,0x89,0xc8,0xab,0xa3
  27.                      };
  28. uchar Disp[4];
  29. void LedScan(void);
  30. void KeyScan(void);
  31. void years(void);
  32. void date(void);
  33. void timer(void);
  34. void alarmClock(void);
  35. void CountDown(void);
  36. void ring(void);
  37. uchar DaysCount(void);
  38. void Init(void)
  39. {
  40. TH2=0x3c;TL2=0xb0;
  41. RCAP2H=0x3c;RCAP2L=0xb0;
  42. EA=1;ET2=1;
  43. TR2=1;
  44. TMOD=0x01;
  45. //TH0=0x3c;
  46. //TL0=0xb0;
  47. ET0=1;
  48. P1=0xff;
  49. year=2011;
  50. month=1;
  51. day=1;
  52. hour=0;
  53. min=0;
  54. status=2;
  55. buzzer=1;
  56. }
  57. /************主函数*************/
  58. void main(void)
  59. {
  60. Init();
  61. while(1)
  62.    {
  63.     KeyScan();
  64.     LastDay=DaysCount();
  65.         switch(status)        //显示状态                                
  66.              {
  67.                   case 0:years();break;                        //显示年
  68.                   case 1:date();break;                        //显示日期
  69.                   case 2:timer();break;                        //显示时间
  70.           case 3:alarmClock();break;        //显示闹钟时间
  71.                   case 4:CountDown();break;                //显示倒计时
  72.          }
  73.     LedScan();        
  74.     ring();
  75.    }
  76. }

  77. /***************定时器T0中断函数,用于倒计时**************/
  78. void timer0(void) interrupt 1 using 2
  79. {TH0=0x3c;
  80. TL0=0xb0;
  81. T0Count++;
  82. if(CountHr||CountMin||CountSec)
  83.          {if(T0Count==20)
  84.                  {CountSec--;T0Count=0;}
  85.          if(CountSec>=60)
  86.                  {CountSec=59;CountMin--;}
  87.          if(CountMin>=60)
  88.                  {CountMin=59;CountHr--;}
  89.          }
  90. if(T0Count==1200)
  91.          {TR0=0;
  92.          T0Count=0;
  93.         }
  94. }
  95. /**************定时器T2中断函数,用于计时**************/
  96. void timer2(void) interrupt 5 using 1
  97. {
  98. TF2=0;
  99. if(++T2Count==20)
  100.    {sec++;T2Count=0;}
  101. if(!TimeAdj)        //时间调整时,暂停计时
  102.          {if(sec==60)
  103.                    {min++;sec=0;}
  104.           if(min==60)
  105.                    {hour++;min=0;}
  106.           if(hour==24)
  107.                    {day++;hour=0;}
  108.           if(day>LastDay)
  109.                    {month++;day=1;}
  110.           if(month>12)
  111.             {year++;month=1;}
  112.         }
  113. }

  114. void delay(uchar x)
  115. {
  116. uchar k;
  117. while(x--)
  118.       for(k=0;k<123;k++);
  119. }
  120. /***********数码管扫描显示函数***************/
  121. void LedScan(void)
  122. {
  123. uchar i;
  124. uchar temp=0x08;
  125. for(i=0;i<4;i++)
  126.     {
  127.      P0=LedCode[Disp[i]];        //送段码
  128.      P2=~temp;temp>>=1;                //LED显示位控制
  129.      delay(3);                                //延时
  130.          P2=0xff;                                //关显示
  131.     }
  132. }
  133. /**********按键扫描程序***************/
  134. void KeyScan(void)
  135. {
  136. if((P1&0x0f)!=0x0f)                //如果按下按键
  137.    {if(KeyPressTime>0)                //延时
  138.           {
  139.            switch(~(P1|0xf0))        //判断键值
  140.              {
  141.               case 0x01:key_new=1;break;
  142.               case 0x02:key_new=2;break;
  143.               case 0x04:key_new=3;break;
  144.                           case 0x08:key_new=4;break;
  145.                          }
  146.           }
  147.         KeyPressTime++;                        //按键时间加1
  148.    }
  149. else                                                //如果没有按键按下
  150.    {key_new=0;                                //键值清零
  151.     KeyPressTime=0;                        //按键时间清零
  152.    }
  153. if(key_new!=key_old)                //如果前后两次键值不同
  154.     {key=key_new;                        //键值等于本次键值
  155.         }
  156. else                                                //如果前后两次键值相同(按住按键未释放)
  157.    {key=0;                                        //键值清零
  158.     if(KeyPressTime>100)        //按键时间大于100,差不多1秒(作长按键处理)
  159.           {KeyPressTime-=30;        //按键时间减30,当累加到100再次动作,相当于300毫秒按键一次,
  160.            key=key_new;                        //得到本次键值
  161.           }
  162.    }
  163. key_old=key_new;                   //记住本次键值
  164. }
  165. /***********计算本月有多少天**************/
  166. uchar DaysCount(void)                                                        
  167. {
  168. if(month==4||month==6||month==9||month==11)                //4、6、9、11月为30天
  169.    return 30;
  170. else if(month!=2)                                                                //1、3、5、7、8、10、12月为31天
  171.         return 31;
  172. if(month==2)
  173.   {if((year%4==0&&year%100!=0)||(year%400==0))
  174.       return 29;                                                                //闰年2月为29天
  175.    else
  176.       return 28;                                                                //非闰年2月为28天
  177.   }
  178. }
  179. /**************年函数**************/
  180. void years(void)
  181. {
  182. if(adjust)                //设置,调整年
  183.    {
  184.         switch(key)        //处理按键
  185.                 {case 1:{
  186.                              year++;                //年加1
  187.                                  break;
  188.                                 }
  189.                  case 2:{
  190.                                  year--;                //年减1
  191.                  break;
  192.                                 }
  193.                  case 3:{
  194.                                  adjust=0;                //退出设置
  195.                                  DispTime=0;
  196.                                  break;
  197.                                  }
  198.             }
  199.    }
  200. else
  201.    {
  202.     if(key==2) status++;                //显示状态加1,进入日期显示
  203.         if(key==3) adjust=1;                //进入设置
  204.         if(++DispTime==200)                        //显示时间加1,系统默认显示时间,通过按键切换其他显示一段时间后自动返回时间显示
  205.                  {status=2;                                //利用程序循环执行一次的时间作延时,每循环一次DispTime+1,加到200后退出返回时间显示
  206.                   DispTime=0;                        //DispTime清零
  207.                 }
  208.    }
  209. Disp[0]=year/1000;                                //年份千位
  210. Disp[1]=year/100%10;                        //年份百位
  211. Disp[2]=year/10%10;                        //年份十位
  212. Disp[3]=year%10;                                //年份个位
  213. if(T2Count<=10)
  214.    {if(adjust)                                        //如果调整年份,显示闪烁
  215.             Disp[0]=Disp[1]=Disp[2]=Disp[3]=DispOFF;                                 
  216.    }
  217. }
  218. /***********日期函数***************/
  219. void date(void)
  220. {
  221. if(adjust)        //调整日期
  222.    {
  223.         switch(key)
  224.             {case 1:{
  225.                                  if(DigiBit==0) month++;        //月加1
  226.                                  else day++;                                //日加1
  227.                  if(month>12) month=1;                //月大于12,月份等于1
  228.                                  if(day>LastDay) day=1;                //日大于本月最后一日,日等于1
  229.                                  break;
  230.                                 }
  231.                  case 2:{
  232.                                  if(DigiBit==0) month--;        //月减1
  233.                                  else day--;                                //日减1
  234.                                  if(month==0) month=12;                //月=0,月份=12
  235.                                  if(day==0) day=LastDay;        //日=0,日等于本月最后一天
  236.                  break;
  237.                                 }
  238.                  case 3:{
  239.                                  DigiBit=~DigiBit;                        //月、日设置选择切换
  240.                                  if(DigiBit==0)                                //DigiBit=0 选择月 DigiBit=1 选择日
  241.                                           {adjust=0;                                
  242.                                          DispTime=0;
  243.                                         }
  244.                                  break;
  245.                                 }
  246.                 }                        
  247.    }
  248. else
  249.    {
  250.         if(key==1) {status--;DispTime=0;}                //显示年,显示时间清零重新计算
  251.     if(key==2) status++;                                        //显示时间
  252.         if(key==3) adjust=1;                                        //进入设置
  253.         if(++DispTime==200)                                                //显示时间到,返回时间显示
  254.                  {status=2;
  255.                   DispTime=0;
  256.                 }
  257.    }
  258. Disp[0]=month/10;
  259. Disp[1]=month%10;
  260. Disp[2]=day/10;
  261. Disp[3]=day%10+11;
  262. if(T2Count<=10)
  263.    {if(adjust)
  264.            {
  265.            if(!DigiBit)                        //如果调整日,日显示闪烁
  266.              {
  267.                   Disp[0]=DispOFF;
  268.                   Disp[1]=DispOFF;
  269.                  }
  270.            else                                        //如果调整月,月显示闪烁
  271.                  {
  272.                   Disp[2]=DispOFF;
  273.                   Disp[3]=POINT;
  274.                  }
  275.           }                                         
  276.    }
  277. }
  278. /**************时间函数****************/
  279. void timer(void)
  280. {
  281. if(TimeAdj)        //调整时间
  282.    {
  283.         switch(key)
  284.                 {case 1:{                        //up/加 按键
  285.                                  if(DigiBit==0) hour++;        //根据按键选择时间、分钟加调整
  286.                                  else min++;
  287.                  if(hour==24) hour=0;
  288.                                  if(min==60) min=0;
  289.                                  break;
  290.                                 }
  291.                  case 2:{                        //down 减 按键
  292.                                  if(DigiBit==0) hour--;        //时间、分钟减调整
  293.                                  else min--;
  294.                                  if(hour>=24) hour=23;
  295.                                  if(min>=60) min=59;
  296.                  break;
  297.                                 }
  298.                  case 3:{
  299.                                  DigiBit=~DigiBit;                //DigiBit=0 小时,DigiBit=1 分钟
  300.                                  if(DigiBit==0)                 //时间设置完后,秒清零,定时器重新计时
  301.                                          {sec=0;
  302.                                          TR2=0;
  303.                                          TH2=0x3c;TL2=0xb0;
  304.                                          T2Count=0;
  305.                                          TR2=1;
  306.                                          TimeAdj=0;
  307.                                         }
  308.                                  break;
  309.                                 }
  310.                    }
  311.    }
  312. else
  313.    {
  314.         if(key==1) {status--;DispTime=0;}
  315.     if(key==2) {status++;DispTime=80;}//进入闹钟显示,显示时间初始值为80
  316.         if(key==3) TimeAdj=1;
  317.    }
  318. Disp[0]=hour/10;
  319. Disp[1]=hour%10;
  320. Disp[2]=min/10+11;
  321. Disp[3]=min%10+11;
  322. if(T2Count<=10)
  323.    {if(TimeAdj)
  324.            {
  325.            if(!DigiBit)
  326.                  {
  327.                   Disp[0]=DispOFF;
  328.                   Disp[1]=DispOFF;
  329.                  }
  330.            else
  331.                  {
  332.                   Disp[2]=POINT;
  333.                   Disp[3]=POINT;
  334.                  }
  335.           }
  336.         else
  337.           {
  338.            Disp[2]=min/10;
  339.            Disp[3]=min%10;        
  340.            }
  341.    }
  342. }
  343. /*************闹钟函数***************/
  344. void alarmClock(void)
  345. {Disp[0]=AlarmHr/10;
  346. Disp[1]=AlarmHr%10;
  347. Disp[2]=AlarmMin/10+11;
  348. Disp[3]=AlarmMin%10+11;
  349. if(DispTime<80)//显示时间<80,显示闹钟开关状态,显示时间>=80,显示闹钟时间
  350.          {if(AlarmSta)
  351.                 {Disp[0]=DispOFF;
  352.                  Disp[1]=DispOFF;
  353.                  Disp[2]=O;
  354.                  Disp[3]=N;
  355.                 }
  356.          else
  357.                  {Disp[0]=DispOFF;
  358.                  Disp[1]=O;
  359.                  Disp[2]=F;
  360.                  Disp[3]=F;
  361.                 }
  362.         }
  363. if(AlarmAdj)//设置闹钟时间
  364.    {
  365.         switch(key)
  366.                 {case 1:{
  367.                                  if(DigiBit==0) AlarmHr++;
  368.                                  else AlarmMin++;
  369.                  if(AlarmHr==24) AlarmHr=0;
  370.                                  if(AlarmMin==60) AlarmMin=0;
  371.                                  break;
  372.                                 }
  373.                  case 2:{
  374.                                  if(DigiBit==0) AlarmHr--;
  375.                                  else AlarmMin--;
  376.                                  if(AlarmHr>=24) AlarmHr=23;
  377.                                  if(AlarmMin>=60) AlarmMin=59;
  378.                  break;
  379.                                 }
  380.                  case 3:{
  381.                                  DigiBit=~DigiBit;
  382.                                  if(DigiBit==0)
  383.                                          {AlarmAdj=0;
  384.                                          DispTime=80;
  385.                                         }
  386.                                  break;
  387.                                 }
  388.                 }
  389.     if(T2Count<=10)
  390.           {
  391.            if(!DigiBit)
  392.                  {
  393.                   Disp[0]=DispOFF;
  394.                   Disp[1]=DispOFF;
  395.                  }
  396.            else
  397.               {
  398.                    Disp[2]=POINT;
  399.                    Disp[3]=POINT;
  400.                   }
  401.       }
  402.    }
  403. else
  404.    {
  405.         if(key==1) status--;
  406.     if(key==2)
  407.             {status++;
  408.                  DispTime=0;
  409.                 }
  410.         if(key==3) AlarmAdj=1;
  411.         if(key==4)//闹钟开关按键
  412.                 {if(DispTime<80)                //初次按下,显示上次设置状态
  413.                         AlarmSta=~AlarmSta;        //再按可改变设置
  414.                  DispTime=0;//每按一次,显示时间清零,显示闹钟开关状态
  415.                 }
  416.         DispTime++;
  417.         if(DispTime==255)
  418.                 {status=2;
  419.                  DispTime=0;
  420.                 }
  421.    }

  422. }
  423. /**************倒计时函数*****************/
  424. void CountDown(void)
  425. {
  426. if(adjust)//设置倒数时间
  427.    {
  428.         switch(CountSetSta)
  429.                 {case 0:{//设置倒数小时
  430.                                  if(key==1) CountHr++;
  431.                                  if(key==2) CountHr--;
  432.                                  if(key==3) CountSetSta++;
  433.                                  if(CountHr==100) CountHr=0;
  434.                                  if(CountHr>100) CountHr=99;
  435.                                  Disp[0]=H;
  436.                                  Disp[1]=DispOFF;
  437.                                  Disp[2]=CountHr/10;
  438.                                  Disp[3]=CountHr%10;
  439.                                  break;
  440.                                 }
  441.                  case 1:{//设置倒数分钟
  442.                                  if(key==1) CountMin++;
  443.                                  if(key==2) CountMin--;
  444.                                  if(key==3) CountSetSta++;
  445.                                  if(CountMin==60) CountMin=0;
  446.                                  if(CountMin>60) CountMin=59;
  447.                                  Disp[0]=M;
  448.                                  Disp[1]=DispOFF;
  449.                                  Disp[2]=CountMin/10;
  450.                                  Disp[3]=CountMin%10;
  451.                                  break;
  452.                                 }
  453.                  case 2:{//设置倒数秒
  454.                                  if(key==1) CountSec++;
  455.                                  if(key==2) CountSec--;
  456.                                  if(key==3) //设置键
  457.                                          {if(CountHr||CountMin||CountSec)//设置完成后,若倒数的时、分、秒不为零,倒计时开始
  458.                                                 {TH0=0x3c; TL0=0xb0;
  459.                                                  T0Count=0;
  460.                                                   TR0=1;
  461.                                                 }
  462.                                          CountSetSta=0;
  463.                                          adjust=0;
  464.                                          DispTime=0;
  465.                                         }
  466.                                  if(CountSec==60) CountSec=0;
  467.                                  if(CountSec>60) CountSec=59;
  468.                                  Disp[0]=5;
  469.                                  Disp[1]=DispOFF;
  470.                                  Disp[2]=CountSec/10;
  471.                                  Disp[3]=CountSec%10;
  472.                                  break;
  473.                                 }
  474.                 }
  475.    }
  476. else
  477.    {
  478.         if(key==1)                //进入闹钟显示
  479.                 {status--;
  480.                  DispTime=80;
  481.                 }
  482.         if(key==3)                //设置倒数时间
  483.                  {
  484.                  TR0=0;
  485.                   CountHr=CountMin=CountSec=0;
  486.                  adjust=1;
  487.                   }
  488.         if(key==4)                //停止倒计时
  489.                 {TR0=0;
  490.                  CountHr=CountMin=CountSec=0;
  491.                 }
  492.         if(CountHr==0)        //若倒数时间小于1小时,倒计时显示分钟、秒
  493.                  {Disp[0]=CountMin/10;
  494.                  Disp[1]=CountMin%10;
  495.                  Disp[2]=CountSec/10+11;
  496.                  Disp[3]=CountSec%10+11;
  497.             }
  498.          else                        //若倒数时间大于1小时,倒计时显示小时、分钟
  499.                  {Disp[0]=CountHr/10;
  500.                  Disp[1]=CountHr%10;
  501.                  Disp[2]=CountMin/10+11;
  502.                  Disp[3]=CountMin%10+11;
  503.                 }
  504.         if(T2Count<=10)//倒计时显示闪烁
  505.                          Disp[0]=Disp[1]=Disp[2]=Disp[3]=DispOFF;
  506.         if(!TR0)                //倒计时完成后,显示一段时间后退出
  507.                 {if(++DispTime==200)
  508.                         {status=2;
  509.                          DispTime=0;
  510.                         }
  511.                   
  512.                 }
  513.           }
  514. }
  515. /*****************闹铃控制********************/
  516. void ring(void)
  517. {bit StopFlag;
  518. if((hour==AlarmHr&&min==AlarmMin&&AlarmSta)||(CountHr==0&&CountMin==0&&CountSec==0)&TR0)//闹钟时间到或倒数时间到,闹铃响
  519.    {
  520.     if(key==4&status!=3)
  521.                    StopFlag=~StopFlag;
  522.     if(!AlarmAdj&&!StopFlag)
  523.             {AlmTime++;                //计时,程序循环一次加1
  524.              if(AlmTime<=8)        //时间0-8
  525.                         buzzer=0;        //蜂鸣器响(有源蜂鸣器,接通就响,断开就停)
  526.                  if(AlmTime>8)        //时间8-16
  527.                         buzzer=1;        //蜂鸣器停
  528.                  if(AlmTime==16)
  529.                         {if(++AlmCount!=4)//循环4次
  530.                                 AlmTime=0;
  531.                         }
  532.                  if(AlmTime==30)//延时一定时间重复上述动作,使蜂鸣器发出嘀、嘀、嘀、嘀的报警声。
  533.                         {AlmTime=0;
  534.                           AlmCount=0;
  535.                         }
  536.                 }
  537.         else
  538.                 {buzzer=1;
  539.                  
  540.                 }
  541.    }
  542. else
  543.          {buzzer=1;
  544.          StopFlag=0;
  545.          AlmTime=0;
  546.          AlmCount=0;
  547.         }
  548. }
复制代码


回复

使用道具 举报

ID:230559 发表于 2019-4-2 10:00 | 显示全部楼层
程序配合四个按键:移位选定、确认、上键、下键。
回复

使用道具 举报

ID:503018 发表于 2019-4-2 10:39 | 显示全部楼层
#include
#define uchar unsigned char
uchar code shuzi[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc0};//0 1 2 3 4 5 6 7 8 9 0
uchar code shuza[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0xc0};//0 1 2 3 4 5 0
uchar ss,dd,ff,gg,zz;
uchar qq,ww,ee,rr,tt;
uchar z,x,qw,qe,qr,as,fe;
sbit a=P2^0;//锁存器1
sbit b=P2^1;//锁存器2
sbit c=P2^2;//锁存器3
sbit d=P2^3;//锁存器4
sbit e=P2^4;//秒灯
sbit f=P2^5;//时间指示灯
sbit g=P2^6;//设置指示灯
sbit h=P2^7;//....
sbit i=P1^0;//时间设置按键
sbit j=P1^1;//返回
sbit k=P1^2;//加
sbit l=P1^3;//减
sbit m=P1^4;//定时设置
sbit y=P1^5;//启动定时
void ys();

    void main()
{
EA=1;      //打开总中断
TH0=(65535-50000)/256;  //定时器复初值
TL0=(65535-50000)%256;
ET0=1;      //
TR0=1;      //启动定时器
P0=0xc0;
P2=0xff;
P2=0xd0;
  while(1)
{f=0;g=1;
    if(i==0)//设置时间 判断
  {g=0;f=1;
  while(1)
{if(j==0){break;}
  if(i==0){ys();if(i==0){while(i==0){if(i==1){x++;break;}}}}
  if(x==5){x=1;}if(x==0){x=1;}

      if(x==1)
  {if(k==0){ys();if(k==0){ss++;if(k==0)if(ss==10){ss=0;}}} if(l==0){ys();if(l==0){if(ss==0){ss=10;}ss--;}}
  a=1;P0=0x7f;P0=shuzi[ss];a=0; }
  
   if(x==2)
  {if(k==0){ys();if(k==0){dd++;if(k==0)if(dd==6){dd=0;}}} if(l==0){ys();if(l==0){if(dd==0){dd=6;}dd--;}}
  b=1;P0=0x7f;P0=shuza[dd];b=0; }
  
   if(x==3)
  {if(k==0){ys();if(k==0){ff++;if(k==0)if(ff==10){ff=0;}}} if(l==0){ys();if(l==0){if(ff==0){ff=10;}ff--;}}
  c=1;P0=0x7f;P0=shuzi[ff];c=0; }
  
   if(x==4)
  {if(k==0){ys();if(k==0){gg++;if(k==0)if(gg==3){gg=0;}}} if(l==0){ys();if(l==0){if(gg==0){gg=3;}gg--;}}
  d=1;P0=0x7f;P0=shuzi[gg];d=0; }

     }
  }  //设置时间完

          if(m==0)//定时 判断
  {g=0;f=0;as=1;
  while(1)
{if(j==0){as=0;break;}
  if(m==0){ys();if(m==0){while(m==0){if(m==1){x++;break;}}}}
  if(x==5){x=1;}if(x==0){x=1;}

      if(x==1)
  {if(k==0){ys();if(k==0){qq++;if(k==0)if(qq==10){qq=0;}}} if(l==0){ys();if(l==0){if(qq==0){qq=10;}qq--;}}a=1;P0=0x7f;P0=shuzi[qq];a=0; }
  
   if(x==2)
  {if(k==0){ys();if(k==0){ww++;if(k==0)if(ww==6){ww=0;}}} if(l==0){ys();if(l==0){if(ww==0){ww=6;}ww--;}} b=1;P0=0x7f;P0=shuza[ww];b=0;  }
  
   if(x==3)
  {if(k==0){ys();if(k==0){ee++;if(k==0)if(ee==10){ee=0;}}} if(l==0){ys();if(l==0){if(ee==0){ee=10;}ee--;}}c=1;P0=0x7f;P0=shuzi[ee];c=0; }
  
   if(x==4)
  {if(k==0){ys();if(k==0){rr++;if(k==0)if(rr==3){rr=0;}}} if(l==0){ys();if(l==0){if(rr==0){rr=3;}rr--;}}d=1;P0=0x7f;P0=shuzi[rr];d=0;}

     }
  }  //定时时间完
  if(y==0)//启动定时功能
  {while(1){if(y==1){h=!h;if(h==0){fe=1;}if(h==1){fe=0;}break;}}}
if(fe==1)
{if(gg==rr){if(ff==ee){if(dd==ww){if(ss==qq){ g=0;f=0;;ys();g=1;f=1;ys(); }}}}}

     }
}
void zhongduan() interrupt 1  //中断函
{  TH0=(65535-50000)/256;  //定时器复初值
  TL0=(65535-50000)%256;
  z++;
    if(z==80)
  {z=0;
    e=!e;
zz++;
if(zz==120){zz=0;ss++;}
  if(ss==10){ss=0;dd++;}
  if(dd==6){dd=0;ff++;}
  if(ff==10){ff=0;gg++;}

      if(gg==2) {if(ff>=4){ff=0;gg=0;}}
  if(gg>=3) {gg=0;}
    if(rr==2) {if(ee>=4){ee=0;rr=0;}}
  if(rr>=3) {rr=0;}
  
if(as==0)
{P0=shuzi[ss];a=1;a=0;
    P0=shuza[dd];b=1;b=0;
    P0=shuzi[ff];c=1;c=0;
    P0=shuzi[gg];d=1;d=0;
}
if(as==1)
  { a=1;P0=shuzi[qq];a=0;
    b=1;P0=shuza[ww];b=0;
    c=1;P0=shuzi[ee];c=0;
    d=1;P0=shuzi[rr];d=0;
  }
    }

    }
void ys()
{for(qw=255;qw>0;qw--)
for(qe=255;qe>0;qe--);
for(qw=255;qw>0;qw--)
for(qe=50;qe>0;qe--);
}
回复

使用道具 举报

ID:213173 发表于 2019-4-2 11:22 | 显示全部楼层
按照你的硬件电路给你改写的程序,仿真走时不一定准确,实物比较准,也可以软件调整精确度。 无标题.jpg

  1. //K1键调整选择,K2键+,长按连+,K3键-,长按连-,K4键闹钟设置
  2. //定时器初始化程序根据晶振频率选择
  3. #include <reg51.h>
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. //#define key_S 300                                        //宏定义短按(约20ms)实物
  7. //#define key_L 6000                                        //宏定义长按(约2/3s)
  8. //#define key_M 3000                                        //宏定义长按(约1/3s)
  9. #define key_S 100                                        //宏定义短按(约20ms)仿真
  10. #define key_L 2000                                        //宏定义长按(约2/3s)
  11. #define key_M 1000                                        //宏定义长按(约1/3s)
  12. sbit K1 = P1^0;                                                //走时时间调整选择/退出
  13. sbit K2 = P1^1;                                                //++,长按连+
  14. sbit K3 = P1^2;                                                //--,长按连-
  15. sbit K4 = P1^3;                                                //闹钟时间调整选择/退出
  16. sbit wela1=P2^0;                                        //位选1
  17. sbit wela2=P2^1;                                        //位选2
  18. sbit wela3=P2^2;                                        //位选3
  19. sbit wela4=P2^3;                                        //位选4
  20. sbit Buzzer=P3^7;                                        //蜂鸣器
  21. uchar code table[]={//共阳数码管段码"0~f-."
  22.                 0xc0,0xf9,0xa4,0xb0,
  23.                 0x99,0x92,0x82,0xf8,
  24.                 0x80,0x90,0x88,0x83,
  25.                 0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
  26. uint Cnt200us;                                                //定义200微秒变量
  27. uchar hour=12,min=0,sec=0;                        //定义时、分、秒变量
  28. uchar hour4=0,min4=0;                                //定义闹钟时、分变量
  29. uchar  Choice=0,Choice4=0;                        //调整走时的选择变量、设置闹钟的选择变量
  30. bit Buzzer_sign;                                        //蜂鸣器闹钟标志
  31. bit Twinkle,second=1;                                //闪烁标志、秒标志
  32. /**************************************
  33.         定时器0初始化程序 @12.000MHz
  34. **************************************/
  35. void Timer_Init(void)
  36. {
  37.         TMOD= 0x02;                        //设置定时器模式
  38.         TL0 = 0x38;                        //设置定时初值200微秒
  39.         TH0 = 0x38;                        //设置定时重载值200微秒
  40.         TR0 = 1;                        //定时器0开始计时
  41.         EA=1;                                //开总中断
  42.         ET0=1;                                //开定时器1中断
  43. }
  44. /***************************************
  45.         定时器0初始化程序 @11.0592MHz
  46. ***************************************/
  47. /*
  48. void Timer_Init()
  49. {
  50.         TMOD = 0x02;                //设置自动重载模式
  51.         TL0 = 0x48;                        //设置定时初值200微秒
  52.         TH0 = 0x48;                        //设置定时重载值200微秒
  53.         TR0 = 1;                        //定时器0开始计时
  54.         EA=1;                                //开总中断
  55.         ET0=1;                                //开定时器1中断
  56. }*/
  57. /*************************
  58.           按键扫描程序
  59. *************************/
  60. void key_scan()
  61. {
  62.         static bit key1_sign,key4_sign;        //按键自锁标志变量
  63.         static uint count1,count2,count3=0,count4=0;//消抖计数变量                       

  64.         if(!K1)                                                        //检测按键1按下
  65.         {
  66.                 count1++;                                        //消抖计数1自+1
  67.                 if((count1>=key_S)&&(key1_sign==0))//检测消抖计数与按键1自锁标志
  68.                 {                       
  69.                         key1_sign=1;                        //按键1自锁标志置1
  70.                         Choice++;                                //调整选择变量自+1
  71.                         if(Choice>=3)                        //调整时间选择0正常走时,1调时,2调分
  72.                         {
  73.                                 Choice=0;                        //调整时间选择清0
  74.                                 Cnt200us=0;                        //时间变量Cnt200us清0
  75.                                 sec=0;
  76.                         }
  77.                 }
  78.         }
  79.         else
  80.         {
  81.                 key1_sign=0;                                //按键1自锁标志清0
  82.                 count1=0;                                        //消抖计数count1清0
  83.         }
  84.                                
  85.         if(!K2)   
  86.         {  
  87.                 count2++;  
  88.                 if(count2>=key_L)                        //长按快调
  89.                 {
  90.                         if(Choice==1)                        //选择变量1调时
  91.                         {
  92.                                 hour++;
  93.                                 if(hour>=24)
  94.                                         hour=0;
  95.                         }
  96.                         if(Choice==2)                        //选择变量2调分
  97.                         {
  98.                                 min++;
  99.                                 if(min>=60)
  100.                                         min=0;
  101.                         }
  102.                         if(Choice4==1)                        //选择变量1调时
  103.                         {
  104.                                 hour4++;
  105.                                 if(hour4>=24)
  106.                                         hour4=0;
  107.                         }
  108.                         if(Choice4==2)                        //选择变量2调分
  109.                         {
  110.                                 min4++;
  111.                                 if(min4>=60)
  112.                                         min4=0;
  113.                         }
  114.                         count2=key_M;
  115.                 }
  116.         }  
  117.         else                                                        //按键抬起
  118.         {  
  119.                 if(count2>key_S && count2<key_L)//短按
  120.                 {
  121.                         if(Choice==1)                        //选择变量1调时
  122.                         {
  123.                                 hour++;
  124.                                 if(hour>=24)
  125.                                         hour=0;
  126.                         }
  127.                         if(Choice==2)                        //选择变量2调分
  128.                         {
  129.                                 min++;
  130.                                 if(min>=60)
  131.                                         min=0;
  132.                         }
  133.                         if(Choice4==1)                        //选择变量1调时
  134.                         {
  135.                                 hour4++;
  136.                                 if(hour4>=24)
  137.                                         hour4=0;
  138.                         }
  139.                         if(Choice4==2)                        //选择变量2调分
  140.                         {
  141.                                 min4++;
  142.                                 if(min4>=60)
  143.                                         min4=0;
  144.                         }
  145.                 }
  146.                 count2=0;                                        //count2清0
  147.         }   
  148.         if(!K3)   
  149.         {  
  150.                 count3++;  
  151.                 if(count3>=key_L)                        //长按
  152.                 {
  153.                         if(Choice==1)                        //选择变量
  154.                         {
  155.                                 hour--;
  156.                                 if(hour>=24)
  157.                                         hour=23;
  158.                         }
  159.                         if(Choice==2)                        //选择变量
  160.                         {
  161.                                 min--;
  162.                                 if(min>=60)
  163.                                         min=59;
  164.                         }
  165.                         if(Choice4==1)                        //选择变量
  166.                         {
  167.                                 hour4--;
  168.                                 if(hour4>=24)
  169.                                         hour4=23;
  170.                         }
  171.                         if(Choice4==2)                        //选择变量
  172.                         {
  173.                                 min4--;
  174.                                 if(min4>=60)
  175.                                         min4=59;
  176.                         }
  177.                         count3=key_M;
  178.                 }
  179.         }  
  180.         else                                                        //按键抬起
  181.         {  
  182.                 if(count3>key_S && count3<key_L)//短按
  183.                 {
  184.                         if(Choice==1)                        //选择变量
  185.                         {
  186.                                 hour--;
  187.                                 if(hour>=24)
  188.                                         hour=23;
  189.                         }
  190.                         if(Choice==2)                        //选择变量
  191.                         {
  192.                                 min--;
  193.                                 if(min>=60)
  194.                                         min=59;
  195.                         }
  196.                         if(Choice4==1)                        //选择变量
  197.                         {
  198.                                 hour4--;
  199.                                 if(hour4>=24)
  200.                                         hour4=23;
  201.                         }
  202.                         if(Choice4==2)                        //选择变量
  203.                         {
  204.                                 min4--;
  205.                                 if(min4>=60)
  206.                                         min4=59;
  207.                         }
  208.                 }
  209.                 count3=0;                                        //count3清0
  210.         }   
  211.         if(!K4)                                                        //检测按键1按下
  212.         {
  213.                 count4++;                                        //消抖计数1自+1
  214.                 if((count4>=key_S)&&(key4_sign==0))//检测消抖计数与按键1自锁标志
  215.                 {                       
  216.                         key4_sign=1;                        //按键1自锁标志置1
  217.                         Choice4++;                                //调整选择变量自+1
  218.                         if(Choice4>=4)                        //调整闹钟时间选择0闹钟关闭,1调时,2调分,3开启闹钟
  219.                         {
  220.                                 Choice4=0;                        //调整时间选择清0
  221.                         }
  222.                 }
  223.         }
  224.         else
  225.         {
  226.                 key4_sign=0;                                //按键1自锁标志清0
  227.                 count4=0;                                        //消抖计数count1清0
  228.         }
  229. }
  230. /********************************
  231.                 数码管显示程序
  232. ********************************/
  233. void display()
  234. {
  235.         static uchar num=0;                                //分时显示变量
  236.         if((Choice4>0)&&(Choice4<3))        //闹钟设置显示部分
  237.         {
  238.                 P0=0xff;        //消隐
  239.                 switch(num)
  240.                 {
  241.                         case 0:
  242. //                                P2=0x01;                        //时十位位码
  243.                                 P2=0xfe;                        //加PNP管反向
  244.                                 P0=table[hour4/10];        //时十位段码
  245.                                 num++;
  246.                          break;       
  247.        
  248.                         case 1:
  249. //                                P2=0x02;                        //时个位位码
  250.                                 P2=0xfd;                        //加PNP管反向
  251.                                 if((Twinkle==1)&&(Choice4==1))//时点闪烁
  252.                                         P0=table[hour4%10];
  253.                                 else
  254.                                         P0=table[hour4%10]&0x7f;//时个位段码+点
  255.                                 num++;
  256.                          break;       
  257.        
  258.                         case 2:
  259. //                                P2=0x04;                        //分十位位码
  260.                                 P2=0xfb;                        //加PNP管反向
  261.                                 P0=table[min4/10];        //分十位段码
  262.                                 num++;
  263.                          break;       
  264.        
  265.                         case 3:
  266. //                                P2=0x08;                        //分个位位码
  267.                                 P2=0xf7;                        //加PNP管反向
  268.                                 if((Twinkle==1)&&(Choice4==2))//分点闪烁
  269.                                         P0=table[min4%10];
  270.                                 else
  271.                                         P0=table[min4%10]&0x7f;//分个位段码+点
  272.                                 num=0;
  273.                          break;       
  274.                 }
  275.         }
  276.         else        //正常走时显示部分
  277.         {
  278.                 P0=0xff;        //消隐
  279.                 switch(num)
  280.                 {
  281.                         case 0:
  282. //                                P2=0x01;                        //时十位位码
  283.                                 P2=0xfe;                        //加PNP管反向
  284.                                 P0=table[hour/10];        //时十位段码
  285.                                 num++;
  286.                          break;       
  287.        
  288.                         case 1:
  289. //                                P2=0x02;                        //时个位位码
  290.                                 P2=0xfd;                        //加PNP管反向
  291.                                 if((Twinkle==1)&&(Choice==1))//时点闪烁
  292.                                         P0=table[hour%10];
  293.                                 else
  294.                                         P0=table[hour%10]&0x7f;//时个位段码+点
  295.                                 num++;
  296.                          break;       
  297.        
  298.                         case 2:
  299. //                                P2=0x04;                        //分十位位码
  300.                                 P2=0xfb;                        //加PNP管反向
  301.                                 P0=table[min/10];        //分十位段码
  302.                                 num++;
  303.                          break;       
  304.        
  305.                         case 3:
  306. //                                P2=0x08;                        //分个位位码
  307.                                 P2=0xf7;                        //加PNP管反向
  308.                                 if(Choice4==3)
  309.                                         P0=table[min%10]&0x7f;//闹钟启动后秒个位+点
  310.                                 else if((Twinkle==1)&&(Choice==2))//分+点闪烁
  311.                                         P0=table[min%10]&0x7f;
  312.                                 else if(Choice==1)        //分+点
  313.                                         P0=table[min%10]&0x7f;//分个位段码+点
  314.                                 else
  315.                                         P0=table[min%10];//分个位段码
  316.                                 num=0;
  317.                          break;       
  318.                 }
  319.         }
  320. }
  321. /********************************
  322.                 闹钟程序
  323. ********************************/
  324. void Buzzer_nz()
  325. {
  326.         if((Choice4==3)&&(hour4==hour)&&(min4==min)&&(sec<30))
  327.                 Buzzer_sign=1;
  328.         else Buzzer_sign=0;

  329.         if((second==1)&&(Buzzer_sign==1))//计时周期1s       
  330.                 Buzzer=0;                                        //蜂鸣器响
  331.         else Buzzer=1;
  332. }
  333. /********************************
  334.                 主程序
  335. ********************************/
  336. void main(void)
  337. {
  338.         Timer_Init();                                        //初始化定时器
  339.         while(1)
  340.         {
  341.                 key_scan();                                        //按键扫描函数
  342.                 display();                                        //显示函数
  343.                 Buzzer_nz();                                //闹钟函数
  344.         }
  345. }
  346. /*-----------------------------
  347.   定时器0中断服务程序  200微秒
  348. ------------------------------*/
  349. void timer0() interrupt        1
  350. {
  351.         Cnt200us++;                                                //时间变量Cnt200us自+1
  352.         if((Cnt200us>1250 && Cnt200us<2500)||(Cnt200us>3750 && Cnt200us<5000))//闪烁频率2Hz               
  353.                 Twinkle=1;                                        //闪烁标志
  354.         else Twinkle=0;
  355.         if(Cnt200us>=5000)                            //在此可以调整走时精度
  356.         {
  357.                 Cnt200us=0;                                        //变量Cnt200us清0
  358.                 second=~second;                                //秒标志取反
  359.                 if(Choice==0)                                //调整选择变量>0停止走秒
  360.                 {
  361.                         sec++;                                        //秒自+1
  362.                         if(sec>=60)                                //如果秒>=60
  363.                         {
  364.                                 sec=0;                                //秒清0
  365.                                 min++;                                //分自+1
  366.                                 if(min>=60)                        //分>=60
  367.                                 {
  368.                                         min=0;                        //分清0
  369.                                         hour++;                  //小时自+1
  370.                                         if(hour>=24)        //小时>=24
  371.                                                 hour=0;                //小时清0
  372.                                 }
  373.                         }
  374.                 }
  375.         }
  376. }


复制代码



回复

使用道具 举报

ID:476064 发表于 2019-4-2 18:11 来自手机 | 显示全部楼层
太感谢了 回家试试去
回复

使用道具 举报

ID:476064 发表于 2019-4-2 18:13 来自手机 | 显示全部楼层
wulin 发表于 2019-4-2 11:22
按照你的硬件电路给你改写的程序,仿真走时不一定准确,实物比较准,也可以软件调整精确度。

谢谢!回家仿真一下试试,不能让手里的单片机躺着睡觉
回复

使用道具 举报

ID:476064 发表于 2019-4-3 08:23 来自手机 | 显示全部楼层
wulin 发表于 2019-4-2 11:22
按照你的硬件电路给你改写的程序,仿真走时不一定准确,实物比较准,也可以软件调整精确度。

用你这个代码编译后,也是无法在仿真软件上无法调整时间。4个按键完全失效。
回复

使用道具 举报

ID:476064 发表于 2019-4-3 09:29 来自手机 | 显示全部楼层
wulin 发表于 2019-4-2 11:22
按照你的硬件电路给你改写的程序,仿真走时不一定准确,实物比较准,也可以软件调整精确度。

用不同的机器居然可以仿真了! 运行的很好,按键也能调整了。那个4069为啥不能用三极管代替
回复

使用道具 举报

ID:213173 发表于 2019-4-3 11:21 | 显示全部楼层
zsf333666 发表于 2019-4-3 09:29
用不同的机器居然可以仿真了! 运行的很好,按键也能调整了。那个4069为啥不能用三极管代替

按键完全失效是因为用主循环计数方式消抖和判断长短按,仿真时主循环周期要比实际电路长得多(与PC配置有关),按键在预定消抖时间内没有响应,需要按的时间长些才行。4069就是反相器,实物完全可以用三极管代替,但仿真用三极管会不正常。
回复

使用道具 举报

ID:63400 发表于 2019-4-3 13:10 | 显示全部楼层
通过按键 检测 你要设置的按键状态 给你个思路吧 比如按键s1 进入后停止定时器闪烁数码管 如何按s2 设置加 s3设置减 你自己试试不想在来问我  
回复

使用道具 举报

ID:476064 发表于 2019-4-3 16:16 来自手机 | 显示全部楼层
已经搞定,是共阳极的4个三级管应该改成反相的
回复

使用道具 举报

ID:478454 发表于 2019-4-4 01:05 | 显示全部楼层
wulin 发表于 2019-4-2 11:22
按照你的硬件电路给你改写的程序,仿真走时不一定准确,实物比较准,也可以软件调整精确度。

????我是哪里弄错错了么
QQ截图20190404010411.png
回复

使用道具 举报

ID:478454 发表于 2019-4-4 01:22 | 显示全部楼层
wulin 发表于 2019-4-2 11:22
按照你的硬件电路给你改写的程序,仿真走时不一定准确,实物比较准,也可以软件调整精确度。

OK啦!,谢谢
QQ截图20190404012216.png
回复

使用道具 举报

ID:478454 发表于 2019-4-4 01:43 | 显示全部楼层
wulin 发表于 2019-4-3 11:21
按键完全失效是因为用主循环计数方式消抖和判断长短按,仿真时主循环周期要比实际电路长得多(与PC配置有 ...

那么仿真的使用哪一种才能让它正常呢???
回复

使用道具 举报

ID:478454 发表于 2019-4-4 03:04 | 显示全部楼层
wulin 发表于 2019-4-2 11:22
按照你的硬件电路给你改写的程序,仿真走时不一定准确,实物比较准,也可以软件调整精确度。

我想让蜂鸣器常鸣60S后关闭,是有源的蜂鸣器。。要怎么改程序呢?
QQ截图20190404030306.png
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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