找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11553|回复: 0
收起左侧

51单片机电子钟设计6位共阳数码管显示的PCB及仿真源程序

[复制链接]
ID:408881 发表于 2018-10-13 09:12 | 显示全部楼层 |阅读模式
Altium Designer画的8位共阳数码管显示51单片机时钟原理图和PCB图如下:(51hei附件中可下载工程文件)
0.png 0.png 0.png

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png

单片机源程序如下:
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. uchar sec,min,hour;//定义时、分、秒变量
  5. uchar counter10ms0,counter10ms1; //定义T0和T1的10ms计数变量
  6. uchar counter05s0;//定义0.5秒变量

  7. uchar KeyCounter; //定义保存功能按键计数值变量

  8. uchar OldKey;  //定义保存按键状态变量
  9. bit AddFlag,SubbFlag;//定义加、减按键标志
  10. bit FlashFlag; //定义闪烁标志
  11. sbit LED1=P1^0;
  12. sbit LED2=P1^1;
  13. sbit LED3=P1^2;
  14. sbit LED4=P1^3;
  15. uchar Disbuff[8]={0,0,10,0,0,10,0,0};//定义数码管显示缓冲区单元
  16. uchar code DisCode[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};        //共阳数码管段码,0~9及“-”“熄灭”字符的字型码

  17. sbit LED=P3^4; //工作指示灯

  18. /****************************************
  19. * 延时函数Delaynms(uint dly)          *
  20. * 延时时间 dly x 1ms    12MHz           *
  21. ****************************************/
  22. void Delaynms(uint dly)
  23. {
  24.         uchar i;
  25.         while(dly--)
  26.                 for(i=0;i<123;i++);
  27. }
  28. /***************************************/

  29. /****************************************
  30. * 显示函数Display()                     *
  31. * 功能:根据将8个数码管显示一遍         *
  32. ****************************************/
  33. void Display(void)
  34. {
  35.         uchar i,n=0x01;
  36.         for(i=0;i<8;i++)
  37.         {
  38.                  P0=DisCode[Disbuff[i]];         //送段码  
  39.                 P2=~n;                        //开位选
  40.                 Delaynms(1);   //延时
  41.                 n=n<<1;           //位选移位
  42.                 P0=0xff;                //段码低电平全灭
  43.                 P2=0xff;           //经过非门后变成高电平,使得位选关闭
  44.         }
  45. }
  46. /****************************************/

  47. /****************************************
  48. * BIN码变换成BCD码函数TimeDataBin2Bcd() *
  49. * 功能:将时、分、秒分离出十位和个位    *
  50. ****************************************/
  51. void TimeDataBin2Bcd()
  52. {
  53.          Disbuff[0]=hour/10;//分离小时十位
  54.          Disbuff[1]=hour%10;//分离小时个位
  55.          Disbuff[3]=min/10;//分离分钟十位
  56.          Disbuff[4]=min%10;//分离分钟个位
  57.          Disbuff[6]=sec/10;//分离秒十位
  58.          Disbuff[7]=sec%10;//分离秒个位

  59. }
  60. /***************************************/

  61. /****************************************
  62. * 读入按键函数ReadKey()                 *
  63. * 功能:若有按键按下,返回按键值        *
  64. *       若没有按键按下,返回255         *
  65. ****************************************/
  66. uchar ReadKey()
  67. {
  68.         uchar Key;
  69.         Key=P3&0xe0; //读入按键值  P3&1110 0000
  70.         if(Key!=0xe0)
  71.         {                          //若有键按下
  72.                  
  73.                 Delaynms(10);
  74.                 Key=P3&0xe0; //重新读入按键值
  75.                 if(Key!=0xe0)
  76.                 {                         //若有键按下
  77.                         if((Key!=0xe0)&&(OldKey==0xe0))        //判断是否下降沿  
  78.                          {
  79.                                 OldKey=Key;         //保存本次按键值
  80.                                 return(Key); //返回按键值
  81.                         }
  82.                 }        
  83.         }
  84.         OldKey=Key;        //无键按下,保存本次按键值,返回255
  85.         return(255);        //不能够删,否则出错   
  86. }
  87. /***************************************/

  88. /****************************************
  89. * 按键分析函数KeyAnalysis(uchar Key)    *
  90. * 功能:对功能键计数                    *
  91. *       对加、减键设标志                *
  92. ****************************************/
  93. void KeyAnalysis(uchar Key)
  94. {
  95.         if(Key!=255)
  96.         {        //有键按下
  97.                 switch(Key)
  98.                 {
  99.                 case 0x60:        KeyCounter++;        //功能键按下           0110 0000  因为85行Key=P3&0xe0; //重新读入按键值
  100.                                                 if(KeyCounter==3)KeyCounter=0;
  101.                                                 break;
  102.                 case 0xa0:  if(KeyCounter!=0)AddFlag=1;break;  //+键按下        1010 0000         
  103.                 case 0xc0:  if(KeyCounter!=0)SubbFlag=1;break; //-键按下        1100 0000
  104.                 }
  105.         }
  106. }
  107. /***************************************/

  108. /****************************************
  109. * 时间调整函数AdjTime()                 *
  110. * 功能:对分钟、小时加、减设置          *
  111. *                                       *
  112. ****************************************/
  113. void AdjTime()
  114. {
  115.          if(KeyCounter==1)
  116.         {                                 //设置分钟
  117.                  if(AddFlag)
  118.                 {                         //分钟+设置
  119.                          AddFlag=0; //标志位要清零 ,否则影响下次按键判断
  120.                         min++;
  121.                         if(min==60)min=0;
  122.                 }
  123.                 if(SubbFlag)
  124.                 {                   //分钟-设置
  125.                          SubbFlag=0;                 //标志位要清零 ,否则影响下次按键判断
  126.                         min--;
  127.                         if(min==255)min=59;        //分钟减到0的时候,unsigned char型的变量回到255
  128.                 }
  129.         }
  130.         if(KeyCounter==2)
  131.         {                          //设置小时
  132.                  if(AddFlag)
  133.                 {                  //小时+设置
  134.                          AddFlag=0;
  135.                         hour++;
  136.                         if(hour==24)hour=0;
  137.                 }
  138.                 if(SubbFlag)
  139.                 {                   //小时-设置
  140.                          SubbFlag=0;
  141.                         hour--;
  142.                         if(hour==255)hour=23;
  143.                 }
  144.         }
  145. }
  146. /***************************************/


  147. /****************************************
  148. * 闪烁控制函数FlashControl()            *
  149. * 功能:对调整的分钟、小时进行熄灭设置  *
  150. *                                       *
  151. ****************************************/
  152. void FlashControl()
  153. {
  154.         if(FlashFlag)
  155.         {
  156.                  if(KeyCounter==1)
  157.                 {
  158.                            Disbuff[3]=11;        //DisCode[11]=0x00,数码管灭
  159.                          Disbuff[4]=11;
  160.                 }
  161.                  if(KeyCounter==2)
  162.                 {
  163.                            Disbuff[0]=11;
  164.                          Disbuff[1]=11;
  165.                 }
  166.         }
  167. }
  168. /******************************?????*********/

  169. /*void LEDFLASH(void)                  
  170. {
  171.         LED1=~LED1;
  172.         LED2=~LED2;
  173.         LED3=~LED3;
  174.         LED4=~LED4;
  175.         
  176. }
  177. */

  178. void main(void)
  179. {
  180.         uchar Key;
  181.         P1=0XF0;   //时分间隔的两个LED灯亮
  182.         TMOD=0x11;         //定时器0,1都设置为工作方式一
  183.         TH0=(65536-10000)/256;
  184.         TL0=(65536-10000)%256;
  185.         TH1=(65536-10000)/256;
  186.         TL1=(65536-10000)%256;
  187.         ET0=1;ET1=1;   //开定时器0,1的中断
  188.         EA=1;                //开总中断
  189.         while(1)
  190.         {
  191.                 Key=ReadKey();                //读取按键,检测按键是否按下
  192.                 KeyAnalysis(Key);        //判断哪个按键按下
  193.                 if(KeyCounter==0)         //假如没有按下功能键
  194.                 {        TR0=1;                         //启动定时器0,秒计数
  195.                         TR1=0;
  196.                         TimeDataBin2Bcd();           //分离变量以便后面数码管的显示
  197.                 }
  198.                 else
  199.                 {
  200.                          TR0=0;                //关闭定时器0,
  201.                         TR1=1;                   //启动定时器1
  202.                         AdjTime();        //调整时间
  203.                         TimeDataBin2Bcd(); //分离变量以便后面数码管的显示
  204.                         FlashControl();           //对调整的分钟、小时进行熄灭数码管设置
  205.                 }
  206.                 Display();         //显示数码管
  207.         }
  208. }

  209. void Timer0(void) interrupt 1
  210. {
  211.         TH0=(65536-10000)/256;
  212.         TL0=(65536-10000)%256;
  213.         counter10ms0++;
  214.         
  215.         if(counter10ms0==50)
  216.         {
  217.                  counter10ms0=0;
  218.                 counter05s0++;
  219.                 LED=0;                //LED=P3^4; //工作指示灯亮

  220.                 if(counter05s0==2)         //1s到来
  221.                 {         
  222.                         counter05s0=0;
  223.                         sec++;
  224. ……………………

  225. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
电子时钟资料全.zip (2.56 MB, 下载次数: 180)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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