找回密码
 立即注册

QQ登录

只需一步,快速开始

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

stc12单片机多功能数字电表程序

[复制链接]
跳转到指定楼层
楼主
ID:635572 发表于 2020-5-13 17:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include <STC12C5A60S2.h>
  2. #define uchar unsigned char
  3. #define uint  unsigned int
  4. #define ulong unsigned long
  5. uchar code acLEDCS[] = {0xef, 0xdf, 0xbf, 0x7f};              /* 位选地址码,低电平有效,接在P2口的高四位*/
  6. uchar code acLEDCS1[] = {0xe7, 0xd7, 0xb7, 0x77};
  7. uchar code acLedSegCode[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c}; /* 段码 */
  8. uchar acLED[4];          /* 显示缓冲区 */
  9. char cScanIndex;      /* 位选指针 0~3 */
  10. uchar cKey;              /* 初始键值    */
  11. uchar cKeyCode;       /* 键值 */
  12. uint nDelayKey;       /*键盘延时变量,为定时中断间隔时间的整数倍*/
  13. uchar cLongDelay;     /* 按键长按时间*/

  14. bit bStill;           /*是否松键标志*/
  15. char cMode = 2;       /*显示方式变量,0~3对应4种方式*/
  16. char cSetMode = 0;        /*功能模式变量,0~10对应11种方式*/
  17. uint nTimer1 = 0;         /*定时计数变量,为定时中断间隔时间的整数倍*/
  18. uint nTimer = 0;          /*定时计数变量,为定时中断间隔时间的整数倍*/
  19. /*********闹铃,低电平有效**************/
  20. uchar cTimeMin = 0;    /*闹铃定时时间变量:分钟*/
  21. uchar cTimeHour = 0;    /*闹铃定时时间变量:小时*/
  22. uchar cTimeflag = 0;
  23. sbit bell = P2^3;
  24. int flag = 0;

  25. /************* 秒表 *************/

  26. uint nStopflag = 0;    /*秒表计数开始标志,为1有效*/
  27. uint nStop = 0;    /*秒表计数,为中断的整数倍:100uS*/
  28. uint nStopSec = 0; /*秒表的秒*/
  29. uint nStopTenms = 0; /* 秒表的亳秒*/

  30. uint ncountSec = 30; /*倒计时的秒*/
  31. uint ncountTenms = 0; /* 倒计时的亳秒*/
  32. uint ncountflag = 0;    /*倒计时 开始标志,为1有效*/
  33. uint ncount = 0;    /*倒计时 计数,为中断的整数倍:100uS*/

  34. /*通用位寻址寄存器*/

  35. uchar bdata Reg = 0;
  36. sbit bReg0 = Reg^0;    /* 串行移位之用*/
  37. sbit bReg7 = Reg^7;    /* 串行移位之用*/
  38. /************ DS 1302 驱动程序 ************* */
  39. sbit DS_CLK = P1^4;
  40. sbit DS_IO = P1^5;
  41. sbit DS_RST = P1^6;


  42. typedef struct StrClock
  43. {
  44.     uchar Sec;    /* 秒 */
  45.     uchar Min;    /* 分 */
  46.     uchar Hour;    /* 时 */
  47.     uchar Day;    /* 日 */
  48.     uchar Mon;    /* 月 */
  49.     uchar Week;    /*星期*/
  50.     uchar Year;    /* 年 */
  51.     uchar Ctr;    /*控制字*/
  52. };
  53. union UniClock    /*时钟联合体1*/
  54. {
  55.     struct StrClock    sClock;
  56.     uchar Time[8];   
  57. }idata uClock;    /*时钟*/



  58. typedef struct StrTime /* 时钟结构体 2 */
  59. {
  60. uchar    Sec;    /* 秒 */
  61. uchar    Min;    /* 分 */
  62. uchar    Hour;    /* 时 */
  63. uchar    Day;    /* 日 */
  64. uchar    Mon;    /* 月 */
  65. uchar    Year;    /* 年 */
  66. };        
  67. union UniTime    /*时钟联合体2 */
  68. {        
  69.     struct StrTime sTime;
  70.     uchar Time[6];
  71. } idata uTime;    /* 时钟 */

  72. /* 16进制码转换为BCD码*/

  73. uchar H_BCD(uchar dat)
  74. {
  75.     uchar datl, dat2;
  76.     datl = dat / 10;
  77.     dat2 = dat % 10 + (datl<<4);
  78.     return(dat2);
  79. }
  80. void W_DS1302(uchar adr, uchar dat);/* 写一字节(dat)到指定地址(adr)*/
  81. uchar R_DS1302(uchar adr);
  82. /***************************************************/
  83. /***** DS 1302 驱动程序 *****/
  84. /*初始化*/
  85. void InitDS1302()
  86. {
  87.     uchar dat;

  88.     W_DS1302(0x8e, 0);             /* 控制命令,禁止写保护 */
  89.     W_DS1302(0x90, 0xa5);        /* 2K电阻,一个二极管 */
  90.     dat=R_DS1302(0x81);            /* 读秒字节 */
  91.     if(dat>127)
  92.     {
  93.         dat=0;
  94.         W_DS1302(0x80, dat);    /* 启动时钟 */
  95.     }   
  96.     W_DS1302(0x8e,0x80);         /* 控制命令,使能写保护 */
  97. }

  98. /* 写一字节 */
  99. void W_DS1302Byte(uchar dat)
  100. {
  101.     uchar i=8;
  102.     Reg=dat;
  103.     while(i--)
  104.     {
  105.         DS_CLK=0;
  106.         DS_IO=bReg0;
  107.         DS_CLK=1;
  108.         Reg >>=1;
  109.     }
  110. }
  111. /*读一字节*/
  112. uchar R_DS1302Byte()
  113. {
  114.         uchar i = 8;
  115.         while(i--)
  116.         {
  117.             DS_CLK = 0;
  118.             Reg >>= 1;
  119.             bReg7 = DS_IO;
  120.             DS_CLK = 1;
  121.         }
  122.         return(Reg);
  123. }
  124. /*写一字节(dat)到指定地址(adr) */
  125. void W_DS1302(uchar adr, uchar dat)
  126. {
  127.     DS_CLK = 0;
  128.     DS_RST = 0;
  129.     DS_RST = 1;
  130.     W_DS1302Byte(adr);    /* 地址,命令 */
  131.     W_DS1302Byte(dat);    /* 写 IByte 数据*/
  132.     DS_RST = 0;
  133.     DS_CLK = 0;
  134. }
  135. /*读一字节指定地址(adr)的数据*/
  136. uchar R_DS1302(uchar adr)
  137. {
  138.     uchar dat;
  139.     DS_CLK = 0;
  140.     DS_RST = 1;
  141.     W_DS1302Byte(adr);    /* 地址,命令 */
  142.     dat=R_DS1302Byte();    /* 读 IByte 数据 */
  143.     DS_RST = 0;
  144.     DS_CLK = 0;
  145.     return(dat);
  146. }
  147. /***************** 读时钟数据 ******************/
  148.    
  149.     /*格式为:秒分时日月星期年控制*/
  150. void R_DS1302Timer()
  151.     {
  152.         uchar i;
  153.         DS_CLK = 0;
  154.         DS_RST = 1;
  155.         W_DS1302Byte(0xbf); /* Oxbf:时钟多字节读命令 */
  156.         for(i = 0; i < 8; i++)
  157.         uClock.Time[i] = R_DS1302Byte();
  158.         DS_RST = 0;
  159.         DS_CLK = 0;
  160.     }
  161. /*************** 数码管显示函数 ****************** /*加(I 0x80)是为了点亮该数码管的小数点*/
  162. void display()
  163. {
  164.     {
  165.         if(cSetMode > 0 )
  166.         {
  167.             switch(cMode)
  168.             {

  169.             case 0:  //显示设置年
  170.                 acLED[0] = acLedSegCode[2];
  171.                 acLED[1] = acLedSegCode[0];
  172.                 acLED[2] = acLedSegCode[uTime.sTime.Year /10];
  173.                 acLED[3] = acLedSegCode[uTime.sTime.Year %10];
  174.                 break;
  175.             case 1: //显示设置月/设置日
  176.                 acLED[0] = acLedSegCode[uTime.sTime.Mon /10];
  177.                 acLED[1] = acLedSegCode[uTime.sTime.Mon %10] | 0x80;
  178.                 acLED[2] = acLedSegCode[uTime. sTime. Day / 10];
  179.                 acLED[3] = acLedSegCode[uTime. sTime. Day % 10];
  180.                 break;
  181.             case 2:   //显示设置时/设置分
  182.                 if (cSetMode == 1 || cSetMode == 2)
  183.                 {
  184.                     acLED[0] = acLedSegCode[uTime.sTime.Hour /10];
  185.                     acLED[1] = acLedSegCode[uTime.sTime.Hour %10] | 0x80;
  186.                     acLED[2] = acLedSegCode[uTime. sTime. Min / 10];
  187.                     acLED[3] = acLedSegCode[uTime. sTime. Min % 10];
  188.                     break;
  189.                 }
  190.                 else if (cSetMode == 3 || cSetMode == 4)
  191.                 {
  192.                     acLED[0] = acLedSegCode[cTimeHour /10];
  193.                     acLED[1] = acLedSegCode[cTimeHour %10] | 0x80;
  194.                     acLED[2] = acLedSegCode[cTimeMin / 10];
  195.                     acLED[3] = acLedSegCode[cTimeMin % 10];
  196.                     break;
  197.                 }
  198.             case 3: //显示设置秒
  199.                 acLED[0] = 0;
  200.                 acLED[1] = 0 | 0x80;
  201.                 acLED[2] = acLedSegCode[uTime.sTime.Sec /10];
  202.                 acLED[3] = acLedSegCode[uTime.sTime.Sec %10];
  203.                 break;
  204.             case 6:
  205.                 acLED[0] = acLedSegCode[ncountSec / 10];
  206.                 acLED[1] = acLedSegCode[ncountSec % 10] | 0x80;
  207.                 acLED[2] = acLedSegCode[ncountTenms / 10];
  208.                 acLED[3] = acLedSegCode[ncountTenms % 10];
  209.                 break;
  210.             case 7: // 显示
  211.                 acLED[0] = acLedSegCode[nStopSec / 10];
  212.                 acLED[1] = acLedSegCode[nStopSec % 10] | 0x80;
  213.                 acLED[2] = acLedSegCode[nStopTenms / 10] ;
  214.                 acLED[3] = acLedSegCode[nStopTenms % 10];
  215.                 break;
  216.             default:
  217.                 break;
  218.             }
  219.         }
  220.           else
  221.         {
  222.             switch(cMode)
  223.             {

  224.             case 0:  //显示年
  225.                 acLED[0] = acLedSegCode[2];
  226.                 acLED[1] = acLedSegCode[0];
  227.                 acLED[2] = acLedSegCode[uClock.Time[6] >>4];
  228.                 acLED[3] = acLedSegCode[uClock.Time[6] & 0x0f];
  229.                 break;
  230.             case 1: //显示月/日
  231.                 acLED[0] = acLedSegCode[uClock.Time[4]>>4];
  232.                 acLED[1] = acLedSegCode[uClock.Time[4] & 0x0f] | 0x80;
  233.                 acLED[2] = acLedSegCode[uClock.Time[3] >>4];
  234.                 acLED[3] = acLedSegCode[uClock.Time[3] & 0x0f];
  235.                 break;
  236.             case 2:   //显示时/分
  237.                
  238.                 acLED[0] = acLedSegCode[uClock.Time[2]>>4];
  239.                 acLED[1] = acLedSegCode[uClock.Time[2] & 0x0f] | 0x80;
  240.                 acLED[2] = acLedSegCode[uClock.Time[1] >>4];
  241.                 acLED[3] = acLedSegCode[uClock.Time[1]& 0x0f];
  242.                 break;
  243.             case 3: //显示?
  244.                 acLED[0] = acLedSegCode[uClock.Time[1] >>4];
  245.                 acLED[1] = acLedSegCode[uClock.Time[1]& 0x0f] | 0x80;
  246.                 acLED[2] = acLedSegCode[uClock.Time[0] >>4];
  247.                 acLED[3] = acLedSegCode[uClock.Time[0] & 0x0f];
  248.                 break;
  249.             case 4:
  250.                 acLED[0] = acLedSegCode[0];
  251.                 acLED[1] = acLedSegCode[0];
  252.                 acLED[2] = acLedSegCode[0];
  253.                 acLED[3] = acLedSegCode[0];
  254.                 break;
  255.             default:
  256.                 break;
  257.             
  258.             }
  259.         }
  260.      }
  261. }
  262. /******************** 按键处理程序 ******************/
  263. void DisposeKEY()
  264. {
  265.     switch(cKeyCode)
  266.     {
  267.     case 2:
  268.         if(bStill == 0)
  269.             {
  270.                 cMode++;
  271.             if(cMode >= 5)
  272.             {
  273.                 cMode = 0;
  274.             }
  275.                 bStill = 1;
  276.             }
  277.             break;
  278.     case 3:   
  279.         /*******设置 DS 1302 的时间*******/
  280.     if (cMode == 0 && cSetMode == 1)/*修改年数*/
  281.     {
  282.         if(uTime.sTime.Year < 99)
  283.         {
  284.             uTime.sTime.Year++;
  285.             nDelayKey = 2000;    /*按住键不动,可连续产生键值,相当于连续按键*/
  286.         }
  287.         W_DS1302(0x8e, 0);    /*控制命令,禁止写保护*/
  288.         W_DS1302(0x8c, H_BCD(uTime.sTime.Year));
  289.         W_DS1302(0x8e, 0x80);    /*控制命令,使能写保护*/
  290.         break;
  291.     }
  292.     else if(cMode == 1 && cSetMode == 1)/*修改月数*/
  293.     {
  294.         if (uTime.sTime.Mon < 12)
  295.         {
  296.             uTime.sTime.Mon++;
  297.             nDelayKey = 2000;
  298.         }
  299.         W_DS1302(0x8e, 0);
  300.         W_DS1302(0x88, H_BCD(uTime.sTime.Mon));
  301.         W_DS1302(0x8e, 0x80);
  302.         break;
  303.     }
  304.     else if(cMode == 1 && cSetMode == 2) /*修改天数*/
  305.     {
  306.         if(uTime.sTime.Day < 31)
  307.         {
  308.             uTime.sTime.Day++;
  309.             nDelayKey = 2000;
  310.         }
  311.         W_DS1302(0x8e, 0);
  312.         W_DS1302(0x86, H_BCD(uTime.sTime.Day));
  313.         W_DS1302(0x8e, 0x80);
  314.         break;
  315.     }
  316.    
  317.     else if(cMode == 2 && cSetMode == 1) /*修改小时数*/
  318.     {
  319.         if(uTime.sTime.Hour < 24)
  320.         {
  321.             uTime.sTime.Hour++;
  322.             nDelayKey = 2000;
  323.         }
  324.         W_DS1302(0x8e, 0);
  325.         W_DS1302(0x84, H_BCD(uTime.sTime.Hour));
  326.         W_DS1302(0x8e, 0x80);
  327.         break;
  328.     }
  329.     else if(cMode == 2 && cSetMode == 2) /*修改分钟数*/
  330.     {
  331.         if(uTime.sTime.Min < 59)
  332.          {
  333.             uTime.sTime.Min++;
  334.             nDelayKey = 2000;
  335.         }
  336.         W_DS1302(0x8e, 0);
  337.         W_DS1302(0x82, H_BCD(uTime.sTime.Min));
  338.         W_DS1302(0x8e, 0x80);
  339.         break;
  340.     }
  341.     /********设置闹铃时间*******/
  342.     else if(cMode == 2 && cSetMode == 3)/*设置闹铃小时数*/
  343.     {
  344.         if(cTimeHour < 24)
  345.             {
  346.                 cTimeHour++;
  347.                 nDelayKey = 2000;
  348.             }
  349.             break;
  350.     }
  351.     else if(cMode == 2 && cSetMode == 4)/*设置闹铃分钟数*/
  352.     {
  353.         if(cTimeMin < 59)
  354.             {
  355.                 cTimeMin++;
  356.                 nDelayKey = 2000;
  357.             }
  358.             break;
  359.     }


  360.     else if (cMode == 3 && (cSetMode == 1)) /*修改 秒数*/
  361.     {
  362.         if (uTime.sTime.Sec < 59)
  363.         {
  364.             uTime.sTime.Sec++;
  365.             nDelayKey = 2000;
  366.         }
  367.         W_DS1302(0x8e, 0);
  368.         W_DS1302(0x80, H_BCD(uTime.sTime.Sec));
  369.         W_DS1302(0x8e, 0x80);
  370.         break;
  371.     }
  372.     else if (cMode == 6 && cSetMode == 3) /*修改 倒计时分 */
  373.     {
  374.         if( ncountSec < 91)
  375.         {
  376.             ncountSec++;
  377.             nDelayKey = 2000;
  378.         }
  379.         ncountTenms = 0;
  380.         if (ncountSec == 91)
  381.             ncountSec = 0;
  382.         break;
  383.     }
  384.    
  385.     else
  386.         {
  387.             break;
  388.         }
  389.     case 6:    /*功能:KeySUB */
  390. /********设置 DS1302 的时间*********/
  391.         if (cMode == 0 && cSetMode == 1 )/*修改年数*/
  392.         {
  393.             if(uTime.sTime.Year > 0)
  394.             {
  395.                 uTime.sTime.Year--;
  396.                 nDelayKey = 1000;
  397.             }
  398.             W_DS1302(0x8e, 0);
  399.             W_DS1302(0x8c, H_BCD(uTime.sTime.Year));
  400.             W_DS1302(0x8e, 0x80);
  401.             nDelayKey = 2000;
  402.             break;
  403.         }
  404.         else if(cMode == 1 && cSetMode == 1)/*修改月数*/
  405.         {
  406.             if(uTime.sTime.Mon > 0)
  407.             {
  408.                 uTime. sTime.Mon--;
  409.                 nDelayKey = 2000;
  410.             }
  411.             W_DS1302(0x8e, 0);
  412.             W_DS1302(0x88, H_BCD(uTime. sTime. Mon));
  413.             W_DS1302(0x8e, 0x80);
  414.             break;
  415.         }
  416.         else if (cMode == 1 && cSetMode == 2)/*修改天数*/
  417.         {
  418.             if(uTime. sTime. Day > 0)
  419.             {
  420.                 uTime.sTime.Day--;
  421.                 nDelayKey = 2000;
  422.             }
  423.             W_DS1302(0x8e, 0);
  424.             W_DS1302(0x86, H_BCD(uTime.sTime.Day));
  425.             W_DS1302(0x8e, 0x80);
  426.             break;
  427.         }
  428.         else if(cMode == 2 && cSetMode == 1)/*修改小时数*/
  429.         {
  430.             if(uTime.sTime.Hour > 0)
  431.             {
  432.                 uTime.sTime.Hour--;
  433.                 nDelayKey = 1000;
  434.             }
  435.             W_DS1302(0x8e, 0);
  436.             W_DS1302(0x84, H_BCD(uTime.sTime.Hour));
  437.             W_DS1302(0x8e, 0x80);
  438.             break;
  439.         }
  440.         else if(cMode == 2 && cSetMode == 2)/*修改分钟数*/
  441.         {
  442.             if(uTime.sTime.Min > 0)
  443.             {
  444.                 uTime.sTime.Min--;
  445.                 nDelayKey = 2000;
  446.             }
  447.         W_DS1302(0x8e, 0);
  448.         W_DS1302(0x82, H_BCD(uTime.sTime.Min));
  449.         W_DS1302(0x8e, 0x80);
  450.         break;
  451.         }
  452.         else if (cMode == 3 && (cSetMode == 1 )) /*修改 秒数*/
  453.         {
  454.             if(uTime.sTime.Sec > 0)
  455.             {
  456.                 uTime.sTime.Sec--;
  457.                 nDelayKey = 2000;
  458.             }
  459.             W_DS1302(0x8e, 0);
  460.             W_DS1302(0x80, H_BCD(uTime.sTime.Sec));
  461.             W_DS1302(0x8e, 0x80);
  462.             break;
  463.         }
  464. /********设置闹铃时间********/
  465.         else if (cMode == 2 && cSetMode == 3)/*设置闹铃小时数*/
  466.         {
  467.             if(cTimeHour > 0)
  468.             {
  469.                 cTimeHour--;
  470.                 nDelayKey = 2000;
  471.             }
  472.             break;
  473.         }

  474.         else if(cMode == 2 && cSetMode == 4)/*设置闹铃分钟数*/
  475.         {
  476.             if(cTimeMin > 0)
  477.             {
  478.                 cTimeMin --;
  479.                 nDelayKey = 2000;
  480.             }
  481.             break;
  482.         }
  483.         else if (cMode == 6 && cSetMode == 3) /*修改 倒计时分 */
  484.         {
  485.             if(ncountSec > 0)
  486.             {
  487.                 ncountSec--;
  488.                 nDelayKey = 2000;
  489.             }
  490.             ncountTenms = 0;
  491.             if (ncountSec == 0)
  492.             ncountSec = 90;            
  493.             break;
  494.         }
  495.         else
  496.         {
  497.             break;
  498.         }
  499.     case 5:   
  500.             
  501.             if(bStill == 0)
  502.             {
  503.                 cSetMode++;
  504.                 bStill = 1;
  505.             }
  506.             if(cMode == 0 && cSetMode == 2)
  507.         {
  508.             cSetMode = 0;
  509.             break;
  510.         }
  511.         else if(cMode == 1 && cSetMode == 3)
  512.         {
  513.             cSetMode = 0;
  514.             break;
  515.         }
  516.         else if(cMode == 2 && cSetMode == 5)
  517.         {
  518.             cSetMode = 0;
  519.             break;
  520.         }
  521.         else if(cMode == 2 && cSetMode == 1&& cTimeflag == 1)
  522.         {
  523.             cTimeHour = 24;
  524.             cTimeMin = 60;
  525.             cTimeflag =0;
  526.             break;
  527.         }
  528.         
  529.         
  530.         
  531.         else if(cMode == 3 && cSetMode == 2)
  532.         {
  533.             cSetMode = 0;
  534.             break;
  535.         }
  536.         else if(cMode == 6 && cSetMode == 6)
  537.         {
  538.             cSetMode = 0;
  539.             cMode =4;
  540.             ncountTenms = 0;
  541.             ncountSec = 30;
  542.             nStopTenms = 0;
  543.             nStopSec = 0;
  544.             
  545.             break;
  546.         }
  547.         else if(cMode == 3 && cSetMode == 2)
  548.         {
  549.             cSetMode = 0;
  550.             break;
  551.         }
  552.         else if(cMode == 7 && cSetMode == 3)
  553.         {
  554.             ncountflag = 1;
  555.             break;
  556.         }
  557.         else if(cMode == 6 && cSetMode == 5)
  558.         {
  559.             ncountflag = 0;
  560.             break;
  561.         }
  562.         else if(cMode == 4 && cSetMode == 1)
  563.         {
  564.             nStopflag = 1;
  565.             break;
  566.         }
  567.         else if(cMode == 7 && cSetMode == 2)
  568.         {
  569.             nStopflag = 0;
  570.             break;
  571.         }
  572.         else
  573.         {
  574.             break;
  575.         }
  576.     }
  577.    
  578.         display ();
  579.         cKeyCode = 0;
  580. }



  581. void Alarm()
  582. {
  583.     if (cTimeHour - uClock.Time[2]  == 0&& cTimeMin - uClock.Time[1]  == 0&& cSetMode == 0 )
  584.     {   
  585.         cTimeflag = 1;    /*启动闹铃*/
  586.         bell = 0;
  587.     }
  588.     else    /*不启动闹铃*/
  589.         bell = 1;
  590.         cTimeflag = 0;    /*不启动闹铃*/
  591.         
  592. }
  593. /****************** 秒表函 数 *******************/
  594. void StopWatch()
  595. {
  596.     if(nStopflag == 1)
  597.     {
  598.         cMode = 7;
  599.         if(nStop >= 100)
  600.         {
  601.             nStop = 0;
  602.             nStopTenms++;
  603.             if(nStopTenms >= 100) /*100*10ms=ls*/
  604.             {
  605.                 nStopTenms = 0;
  606.                 if(nStopSec < 99)
  607.                     nStopSec++; /*秒表秒加一*/
  608.                 else    /*最长秒表为99.99s*/
  609.                 {
  610.                     nStopSec = 99;
  611.                     nStopTenms = 99;
  612.                     nStopflag = 0;
  613.                 }
  614.             }
  615.         }
  616.     }
  617.    
  618.     display();
  619. }
  620. void CountDown(void)

  621. {
  622.     if (ncountflag == 1)
  623.     {
  624.         cMode= 6;
  625.     }
  626.     if(cMode == 6 && cSetMode == 4)/*开始倒计时*/

  627.     {
  628.         if(ncount >= 100)
  629.         {
  630.             ncount = 0;
  631.             if (ncountTenms != 0)
  632.             {
  633.             ncountTenms--;
  634.             }
  635.             else if(ncountTenms==0 && ncountSec != 0)
  636.             {
  637.                 ncountTenms =99;
  638.                 ncountSec--;
  639.             }
  640.             
  641.             else
  642.             {
  643.                 ncountTenms =0;
  644.                 ncountSec = 0;
  645.                 ncountflag = 0;
  646.             }
  647.         }
  648.     }
  649. }
  650. /************************** 主函数 *****************************/
  651. void main(void)
  652. /**************** 定时器初始化 *******************/
  653. {
  654.     AUXR &= 0x7F;   
  655.     TMOD &= 0xF0;        
  656.     TMOD |= 0x01;        
  657.     TL0 = 0x48;        
  658.     TH0 = 0xFF;   
  659.     TF0 = 0;        
  660.     TR0 = 1;        
  661.     ET0 = 1;
  662.     EA = 1;        /*开总中断*/
  663.     P0M0 = 0xff; /*定义P0 口为强推挽模式*/
  664.     P0M1 = 0x00; /*POM1 = 00000000B*/
  665.     InitDS1302();  /* 初始化 DS1302 */
  666.     R_DS1302Timer();  /*读时钟数据()*/
  667.     display();  /*显示初始界面*/
  668.     while(1)



  669.     {
  670.         if(cKeyCode != 0)
  671.         {
  672.             DisposeKEY(); /*响应按键操作*/
  673.         }
  674.         R_DS1302Timer();      /*读时钟数据*/
  675.         display() ;  /*显示函数*/
  676.         Alarm();     /*闹铃函数*/
  677.         StopWatch();  /*秒表函数*/
  678.         CountDown();  /*倒计时函数*/
  679.     }
  680. }
  681. /**************** 多任务时序控制时钟中断 *****************/
  682. void IntT0() interrupt 1
  683. {
  684.     TL0 = 0x48;        
  685.     TH0 = 0xFF;   
  686.     nTimer1++;
  687.    
  688.     if(ncountflag == 1)
  689.     {        
  690.             ncount++;    /*秒表计数,为中断的整数倍:100us*/
  691.     }
  692.     if(nStopflag == 1)
  693.     {        
  694.             nStop++;    /*秒表计数,为中断的整数倍:100us*/
  695.     }
  696.      if (cTimeflag == 1)
  697.     {
  698.                     P0 = 0;
  699.                     P2 = acLEDCS1[cScanIndex];
  700.                     P0 = acLED[cScanIndex++];
  701.                     cScanIndex &= 3;
  702.     }
  703.     else
  704.         {
  705.         if (cSetMode > 0 && cSetMode < 8)    /*此处用于闪烁时,设置时间及闹铃。闪烁是通过数码管间歇性显示有效实现的*/
  706.         {   
  707.             if(nTimer1 <= 2500 )
  708.             {
  709.                 if (cMode == 0 && cSetMode == 1 ) /*设置 年时,数码管闪烁*/
  710.                                                               /*先淸显示再换位选*/
  711.                 {
  712.                     P0 = 0;
  713.                     P2 = acLEDCS[cScanIndex];
  714.                     cScanIndex++;
  715.                     P0 = 0;
  716.                     cScanIndex &= 3;
  717.                 }
  718.                     else if(cSetMode == 1 && cMode == 1)
  719.                     {
  720.                         P0 = 0;
  721.                         P2 = acLEDCS[cScanIndex];
  722.                         cScanIndex++;
  723.                         if(cScanIndex >= 1 && cScanIndex <= 2)
  724.                             P0 = 0;
  725.                         else
  726.                         {
  727.                             P0 = acLED[cScanIndex - 1];
  728.                             cScanIndex &= 3;
  729.                         }
  730.                     }
  731.                     else if(cSetMode == 2 && cMode == 1) /*日时,后两位数码管闪烁*/
  732.                     {
  733.                         P0 = 0;
  734.                         P2 = acLEDCS[cScanIndex];
  735.                         cScanIndex++;
  736.                         if(cScanIndex >= 3 && cScanIndex <= 4)
  737.                         {
  738.                             P0 = 0;   
  739.                             cScanIndex &= 4;    /*位选指针回位*/
  740.                         }
  741.                         else   
  742.                             P0 = acLED[cScanIndex - 1];    /*送显示数据,位选指针移位*/   
  743.                     }         
  744.                     else if(cSetMode == 1 && cMode == 2)    /*设置小时,前两位数码管闪烁*/
  745.         
  746.                     {
  747.                         P0 = 0;    /*先淸显示再换位选*/   
  748.                         P2 = acLEDCS[cScanIndex];    /*送位选数据*/   
  749.                         cScanIndex++;   
  750.                         if(cScanIndex >= 1 && cScanIndex <= 2)   
  751.                             P0 = 0;   
  752.                         else
  753.                         {
  754.                             P0 = acLED[cScanIndex - 1];    /*送显示数据,位选指针移位*/   
  755.                             cScanIndex &= 3;    /*位选指针回位*/
  756.                         }
  757.                     }

  758.                     else if(cSetMode == 2 && cMode == 2)    /*设置分钟时,后两位数码管闪烁*/
  759.                     {   
  760.                         P0 = 0;/*先淸显示再换位选*/
  761.                         P2 = acLEDCS[cScanIndex] ;    /* 送位选数据*/
  762.                         cScanIndex++;
  763.                         if(cScanIndex >= 3 && cScanIndex <= 4)
  764.                         {
  765.                             P0 = 0;
  766.                             cScanIndex &= 4;    /* 位选指针回位*/
  767.                         }
  768.                         else
  769.                             P0 = acLED[cScanIndex - 1];    /* 送显示数据,位选指针移位*/
  770.                     }
  771.                     else if (cMode == 3 && (cSetMode == 1 || cSetMode == 2))/*设置秒时,数码管闪烁*/

  772.                     {
  773.                         P0 = 0;    /*先清显示再换位选*/   
  774.                         P2 = acLEDCS[cScanIndex];    /*送位选数据*/        
  775.                         cScanIndex++;   
  776.                         P0 = 0;   
  777.                         cScanIndex &= 3;    /*位选指针回位*/        
  778.                     }
  779.                     else if(cSetMode == 3 && cMode == 2)    /*设置闹铃小时时,    前两位数码管闪烁*/
  780.                     {
  781.                         P0 = 0;    /*先淸显示再换位选*/   
  782.                         P2 = acLEDCS[cScanIndex];    /*送位选数据*/

  783.                         cScanIndex++;
  784.                         if(cScanIndex >= 1 && cScanIndex <= 2)
  785.                             P0 = 0;
  786.                     
  787.                         else
  788.                         {
  789.                             P0 = acLED[cScanIndex -1];  
  790.                             cScanIndex &= 3;
  791.                         }
  792.                     }
  793.                     else if(cSetMode == 4 && cMode == 2)
  794.                     {
  795.                         P0 = 0;
  796.                         P2 = acLEDCS[cScanIndex];
  797.                         cScanIndex++;
  798.                         if(cScanIndex >= 3 && cScanIndex <= 4)
  799.                         {
  800.                             P0 = 0;
  801.                             cScanIndex &= 4;
  802.                         }
  803.                         else
  804.                             P0 = acLED[cScanIndex - 1];
  805.                     }
  806.                     else if(cMode == 6 && cSetMode == 3)
  807.                     {
  808.                         P0 = 0;    /*先淸显示再换位选*/   
  809.                         P2 = acLEDCS[cScanIndex];    /*送位选数据*/   
  810.                         cScanIndex++;   
  811.                         if(cScanIndex >= 1 && cScanIndex <= 2)   
  812.                             P0 = 0;   
  813.                         else
  814.                         {
  815.                             P0 = acLED[cScanIndex - 1];    /*送显示数据,位选指针移位*/   
  816.                             cScanIndex &= 3;    /*位选指针回位*/
  817.                         }
  818.                     }
  819.                     else /*不闪烁*/
  820.                     {
  821.                         P0 = 0;
  822.                         P2 = acLEDCS[cScanIndex];
  823.                         P0 = acLED[cScanIndex++];
  824.                         cScanIndex &= 3;
  825.                     }
  826.                 }

  827.                 else

  828.                 {
  829.                     if(nTimer1 >= 5000 )
  830.                         nTimer1 = 0;
  831.                     P0 = 0;
  832.                     P2 = acLEDCS[cScanIndex];
  833.                     P0 = acLED[cScanIndex++];
  834.                     cScanIndex &= 3;
  835.                 }
  836.             }
  837.             else   
  838.             {
  839.                 P0 = 0;
  840.                 P2 = acLEDCS[cScanIndex];
  841.                 P0 = acLED[cScanIndex++];
  842.                 cScanIndex &= 3;
  843.             }
  844.     }
  845. /*********************扫 描按键********************/
  846.         if(nDelayKey == 0)
  847.         {
  848.             cKey = P2 & 0x07;  /* 取键值 P20、P21、P22*/
  849.             if(cKey != 0x07)
  850.                 nDelayKey = 100;       /*设置延退时间削颤*/
  851.             else
  852.             {

  853.                 bStill = 0;
  854.                 cLongDelay = 0;/*松键*//*有按键利用DelayKey按键消颤*/
  855.             }
  856.         }
  857.         else
  858.         {
  859.             nDelayKey--;
  860.             if(nDelayKey == 0)
  861.             {
  862.                 cKeyCode = P2 & 0x07;
  863.                 if(cKey != cKeyCode)
  864.                 {
  865.                     cKeyCode = 0;
  866.                 }
  867.             }
  868.         }
  869. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:635572 发表于 2020-5-13 17:06 | 只看该作者
这是一个完整的系统,里面包含了年月日,闹钟,计时,以及跳转设置等
回复

使用道具 举报

板凳
ID:1 发表于 2020-5-14 03:46 | 只看该作者
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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