找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2511|回复: 1
收起左侧

51单片机学习,简易时钟

[复制链接]
ID:161768 发表于 2017-2-9 22:22 | 显示全部楼层 |阅读模式
使用芯片STC89C52RC, 2个锁存器
6个带小数点共阴极数码管显示一个24时制时钟
没有时钟芯片,所以掉电后时间会复位
原理图为TX-1C开发板

暂时显示了半小时,一秒不差,
未验证有无其他bug,代码贴上来,欢迎高手指点


==============================
最终显示的<时.分.秒>是 16.31.37  形式
  1.     #include <reg52.h>  
  2.     #include "MY51.H"  
  3.       
  4.     void show();  
  5.     uint8  shi=15;   //初始时间15:45:00  按复位按钮对时  
  6.     uint8  fen=45;  
  7.     uint8  miao=0;  
  8.       
  9.     void main()      
  10.     {  
  11.         startT0(1000);  //开始定时器  
  12.         while(1)  
  13.         {         
  14.             show();  
  15.         }  
  16.     }  
  17.       
  18.     void show()  //显示时钟  
  19.     {  
  20.         uint8 oneWela,twoWela,threeWela,foreWela,fiveWela,sixWela; //oneWela是最左边的数码管  
  21.         sixWela =miao%10;  
  22.         fiveWela=miao/10;     
  23.         foreWela=fen%10;  
  24.         threeWela=fen/10;  
  25.         twoWela=shi%10;  
  26.         oneWela=shi/10;  
  27.         displaySMG(oneWela,twoWela,threeWela,foreWela,fiveWela,sixWela,0xf5); //0xf5小数点位置  
  28.     }  
  29.       
  30.     void T0_Work()  //T0定时器调用的工作函数  
  31.     {   
  32.        miao++;  
  33.         if(miao>59)  
  34.         {  
  35.             miao=0;  
  36.             fen++;  
  37.         }  
  38.       
  39.         if(fen>59)  
  40.         {  
  41.             fen=0;  
  42.             shi++;  
  43.         }   
  44.          
  45.         if(shi>23)  
  46.         {  
  47.             shi=0;  
  48.         }  
  49.     }  
复制代码
  1. #ifndef _MY51_H_  
  2. #define _MY51_H_  
  3. #include <math.h>  
  4. #include <intrins.h>  
  5.   
  6. typedef int                 int16  ;  
  7. typedef int                 INT16  ;  
  8. typedef unsigned int    uint16 ;  
  9. typedef unsigned int    UINT16 ;  
  10. typedef unsigned short  uint ;  
  11. typedef unsigned short  UINT ;  
  12. typedef unsigned short  word ;  
  13. typedef unsigned short  WORD ;  
  14. typedef unsigned long   uint32 ;  
  15. typedef unsigned long   UINT32 ;  
  16. typedef unsigned long   DWORD ;  
  17. typedef unsigned long   dword ;  
  18. typedef signed long    int32     ;  
  19. typedef signed long    INT32  ;  
  20. typedef float                   float32  ;  
  21. typedef double              double64  ;  
  22. typedef signed char     int8 ;  
  23. typedef signed char         INT8 ;  
  24. typedef unsigned char   byte ;  
  25. typedef unsigned char    BYTE    ;      //WINDOWS的windef.h里面是这么定义的  
  26. typedef unsigned char   uchar ;  
  27. typedef unsigned char   UCHAR ;  
  28. typedef unsigned char   UINT8 ;  
  29. typedef unsigned char   uint8 ;  
  30. typedef unsigned char   BOOL     ;      //windows中定义BOOL为int  
  31. typedef unsigned char   bool     ;          //bool是c++的内置类型  
  32.   
  33. #define TRUE     1  
  34. #define true     1  
  35. #define FALSE    0  
  36. #define false    0  
  37.   
  38. #define open     1    //open和close用于 标志打开和关闭状态  
  39. #define OPEN     1  
  40. #define close    0  
  41. #define CLOSE    0  
  42. #define lock     0  
  43. #define start    1  
  44. #define START    1  
  45. #define stop     0  
  46. #define STOP     0  
  47.   
  48. uint8    dulaIndex=0;       //数码管0~F段编码索引号  
  49. uint8    welaIndex=0;       //0~5位的数码管位索引号  
  50.   
  51. sbit dula =P2^6;  //段选锁存器控制  控制笔段  
  52. sbit wela =P2^7;  //位选锁存器控制  控制位置  
  53.   
  54. #define led P1    //灯总线控制  
  55. sbit led0=P1^0;   //8个led灯  
  56. sbit led1=P1^1;  
  57. sbit led2=P1^2;  
  58. sbit led3=P1^3;  
  59. sbit led4=P1^4;  
  60. sbit led5=P1^5;  
  61. sbit led6=P1^6;  
  62. sbit led7=P1^7;  
  63. sbit keyS2=P3^4; //4个独立按键  
  64. sbit keyS3=P3^5;  
  65. sbit keyS4=P3^6;  
  66. sbit keyS5=P3^7;  
  67.   
  68. void displaySMG(uint8 one,uint8 two,uint8 three,uint8 four,uint8 five,uint8 six,uint8 dot);   
  69. void delayms(uint16 ms);  
  70. void T0_Work();  
  71. //////////////////////////////////////////////////////////////////////////  
  72. void delayms(uint16 ms)  //软延时函数  
  73. {  
  74.     uint16 i,j;  
  75.     for(i=83;i>0;i--)  
  76.     {  
  77.         for(j=ms;j>0;j--)  
  78.         {}  
  79.     }  
  80. }  
  81.   
  82. ///////////////////////////////////////////////////////////////////////////  
  83. #define dark    0x11  //也就是索引第17号元素0x00,共阴极数码管正极全部输入低电平  
  84. uint8 code table[]= {           //0~F外加小数点和空输出的数码管编码  
  85. 0x3f , 0x06 , 0x5b , 0x4f , // 0 1 2 3  
  86. 0x66 , 0x6d , 0x7d , 0x07 , // 4 5 6 7  
  87. 0x7f , 0x6f , 0x77 , 0x7c , // 8 9 A B  
  88. 0x39 , 0x5e , 0x79 , 0x71 , // C D E F  
  89. 0x80 , 0x00                 // . 空     空时是第0x11号也就是第17号元素  
  90. };  
  91.   
  92. /////////////////////////////////////////////////////////////////////////////  
  93. uint8   TH0Cout=0 ;     //初值      
  94. uint8   TL0Cout=0 ;      
  95. uint16  T0IntCout=0;     //中断计数  
  96. uint16  T0IntCountAll=0; //(N-1)/65536+1;  //总中断次数  
  97. bool    bT0Delay=false;  //使用延时函数标志,初始未用  
  98. bool    bT0Over=false;   //中断处理函数执行结果之一  
  99.   
  100. void startT0(uint32 ms)  //开启定时器  
  101. {     
  102.     float32   t=ms/1000.0;               //定时时间  
  103.     double64    fox =11.0592*(pow(10,6));  //晶振频率  
  104.     uint32    N=(t*fox)/12 ;                 //定时器总计数值  
  105.   
  106.     TH0Cout =(65536-N%65536)/256;        //装入计时值零头计数初值  
  107.     TL0Cout =(65536-N%65536)%256;  
  108.     T0IntCountAll=(N-1)/65536+1;             //总中断次数  
  109.     TMOD=TMOD | 0x01;                        //设置定时器0的工作方式为1  
  110.       
  111.     EA =open;   //打开总中断  
  112.     ET0=open;   //打开定时器中断  
  113.   
  114.     TH0=TH0Cout;  //定时器装入初值  
  115.     TL0=TL0Cout;  
  116.     TR0=start;   //启动定时器  
  117. }  
  118.   
  119. void delayT0(uint32 ms)     //硬延时函数,自己乱写的不好用,求指点  
  120. {  
  121.     startT0(ms);                //启动定时器  
  122.     bT0Delay=true;          //告诉T0定时器,起用延时模式  
  123.     while(bT0Over==false);  //时间没到的话继续检测  
  124.     bT0Over=false;              //时间到了,让标志复位  
  125. }  
  126.   
  127. void T0_times() interrupt 1 //T0定时器中断函数  
  128. {  
  129.     T0IntCout++;  
  130.     if(T0IntCout==T0IntCountAll)  //达到总中断次数值  
  131.     {     
  132.         T0IntCout=0;         //中断次数清零,重新计时  
  133.         bT0Over=true;     //时间真的到了  
  134.         if(bT0Delay)             //本次中断是用来延时的吗  
  135.         {  
  136.             TR0=stop;        //如果是由延时函数开启T0的话,关闭T0  
  137.             return;  
  138.         }  
  139.   
  140.         TH0=TH0Cout;        //循环定时的话要重装初值,每次定时1秒,重装一次  
  141.         TL0=TL0Cout;  
  142.         T0_Work();             //工作函数  
  143.     }  
  144. }  
  145.   
  146. ////////////////////////////////////////////////////////////////////////////////  
  147. void displaySMG(uint8 oneWela,uint8 twoWela,uint8 threeWela,uint8 fourWela,uint8 fiveWela,uint8 sixWela,uint8 dot)  
  148. {       //控制6位数码管显示函数,不显示的位用参数 dark  
  149.         dula=1;         //小数点  
  150.         P0=table[16];  
  151.         dula=0;  
  152.         P0=0xff;  
  153.         wela=1;  
  154.         P0=dot;         
  155.         wela=0;  
  156.         delayms(1);  
  157.   
  158.          dula=1;  
  159.         P0=table[oneWela];   //送段数据  
  160.         dula=0;  
  161.         P0=0xff;    //送位数据前关闭所有显示,防止打开位选锁存后段选数据通过位选锁存器  
  162.         wela=1;  
  163.         P0=0xfe;  
  164.         wela=0;  
  165.         delayms(1);  
  166.   
  167.         dula=1;  
  168.         P0=table[twoWela];  
  169.         dula=0;  
  170.         P0=0xff;  
  171.         wela=1;  
  172.         P0=0xfd;  
  173.         wela=0;  
  174.         delayms(1);  
  175.   
  176.         dula=1;  
  177.         P0=table[threeWela];  
  178.         dula=0;  
  179.         P0=0xff;  
  180.         wela=1;  
  181.         P0=0xfb;  
  182.         wela=0;  
  183.         delayms(1);  
  184.   
  185.         dula=1;  
  186.         P0=table[fourWela];  
  187.         dula=0;  
  188.         P0=0xff;  
  189.         wela=1;  
  190.         P0=0xf7;  
  191.         wela=0;  
  192.         delayms(1);  
  193.   
  194.         dula=1;  
  195.         P0=table[fiveWela];  
  196.         dula=0;  
  197.         P0=0xff;  
  198.         wela=1;  
  199.         P0=0xef;  
  200.         wela=0;  
  201.         delayms(1);  
  202.   
  203.         dula=1;  
  204.         P0=table[sixWela];  
  205.         dula=0;  
  206.         P0=0xff;  
  207.         wela=1;  
  208.         P0=0xdf;  
  209.         wela=0;  
  210.         delayms(1);  
  211. }  
  212.   
  213. #endif
复制代码




回复

使用道具 举报

ID:829862 发表于 2022-2-5 00:11 | 显示全部楼层
:lol:loveliness::Q
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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