找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6005|回复: 4
收起左侧

单片机2408点阵时钟电子制作

[复制链接]
ID:76556 发表于 2015-4-10 04:08 | 显示全部楼层 |阅读模式
本帖最后由 nius 于 2015-4-10 04:10 编辑

    这是一款由单片机TC89C52RD为控制核必的2408点阵时钟电子制作点阵的驱动是用单片机直驱,图中是用STC89C52单片机,直驱三个8*8的共阳点阵屏,亮度还基本可以,白天看都很清楚!驱动能力不是很好,有条件的话用STC12C5A60S,驱动能力已经比较好,屏的亮度会比较高。白天看都很清楚!P0口需要接上1K的上拉电阻,P1-P3口分别接三个8*8屏的阴极,用去了单片机的全部32个I/O口。为了能调时间,P2口的P2.0-P2.6接屏的1-7列,P2.7口接一个按扭作于调时间,调整方法: 长按一次是进入调时状态,短按是加1,长按二次是调分,短按是加1,长按3次回复正常状态! 感兴趣的爱好者可以动手实践一下,体验一下电子制作点阵时钟的乐趣。


                                                
                                                                                               

  1. //单片机点阵电子钟C语言程序
  2. //MCU:STC89C52RD  晶振频率:12MHZ
  3. #include <reg52.H>
  4. #include<stdio.h>
  5. #define uchar unsigned char       //宏定义
  6. #define uint  unsigned int

  7. sbit KEY=P2^7;            //时调整键
  8. uchar keymode;          //键状态
  9. uchar keydate;          //键值,
  10. uint  keycount;          //键延时值
  11. unsigned char c=0;       //时分调整位置变量,0不调,1时调时,2时调分
  12. bit D7,D6;              //键值有效,长按标志,
  13. bit  SHAN;               //闪烁标志位
  14. uchar second,minute,hour;        //定义秒、分、时寄存器
  15. //以下字模与ASCII对应是,只要将 'A'-0x20就可以得到A的字模了
  16. //高8*5宽 ASCII码  
  17. //采用"字模提取软件V2.2"
  18. //提取方式:纵向取模,字节倒序
  19. uchar code ASCII86[10][5]=
  20. {
  21. {0x3E,0x41,0x49,0x41,0x3E},//0
  22. {0x00,0x42,0x7F,0x40,0x00},//1
  23. {0x72,0x49,0x49,0x49,0x46},//2
  24. {0x21,0x41,0x49,0x4D,0x32},//3
  25. {0x18,0x14,0x12,0x7F,0x10},//4
  26. {0x27,0x45,0x45,0x45,0x38},//5
  27. {0x3C,0x4A,0x49,0x49,0x31},//6
  28. {0x41,0x21,0x11,0x09,0x07},//7
  29. {0x36,0x49,0x49,0x49,0x36},//8
  30. {0x46,0x49,0x49,0x29,0x16},//9
  31. };
  32. uchar code seg[24][3]=
  33. {
  34. {0xfe,0xff,0xff},
  35. {0xfd,0xff,0xff},
  36. {0xfb,0xff,0xff},
  37. {0xf7,0xff,0xff},
  38. {0xef,0xff,0xff},
  39. {0xdf,0xff,0xff},
  40. {0xbf,0xff,0xff},
  41. {0x7f,0xff,0xff},
  42. {0xff,0xfe,0xff},
  43. {0xff,0xfd,0xff},
  44. {0xff,0xfb,0xff},
  45. {0xff,0xf7,0xff},
  46. {0xff,0xef,0xff},
  47. {0xff,0xdf,0xff},
  48. {0xff,0xbf,0xff},
  49. {0xff,0x7f,0xff},
  50. {0xff,0xff,0xfe},
  51. {0xff,0xff,0xfd},
  52. {0xff,0xff,0xfb},
  53. {0xff,0xff,0xf7},
  54. {0xff,0xff,0xef},
  55. {0xff,0xff,0xdf},
  56. {0xff,0xff,0xbf},
  57. {0xff,0xff,0x7f}
  58. };  //P1,P3,P2扫描列选码
  59. uchar disbuf[]={0,0,0,0,0,0};//定义缓冲数组区
  60. void delay(uchar t);          //延时函数
  61. void init();              //初始化函数
  62. void display();             //显示函数

  63. void main()
  64. {   
  65. init();                //调用初始化函数
  66. P0=0xff; P1=0x00; P3=0x00; P2=0x00;
  67. for(c=0;c<10;c++) delay(255);
  68.   P1=0xff; P3=0xff; P2=0xff;   //测试点阵屏全亮3秒.
  69.   P0=0x00; P1=0x00; P3=0x00; P2=0x00;
  70. for(c=0;c<10;c++) delay(255);
  71.   P1=0xff; P3=0xff; P2=0xff;   //测试点阵屏全灭3秒.
  72.   P0=0xff; P1=0x00; P3=0x00; P2=0x00;
  73. for(c=0;c<10;c++) delay(255);
  74.   P1=0xff; P3=0xff; P2=0xff;   //测试点阵屏全亮3秒.
  75.     P0=0x00; P1=0x00; P3=0x00; P2=0x00;
  76. for(c=0;c<10;c++) delay(255);
  77.   P1=0xff; P3=0xff; P2=0xff;   //测试点阵屏全灭3秒.
  78.   c=0;
  79. while(1)               //主程序循环
  80.   {
  81. switch(keymode)        //键盘处理程序
  82.    {
  83.    case 0x00:
  84.     if(KEY==0)  { keymode=1; keycount=2;}
  85.           break;
  86.    case 0x01:
  87.       if(keycount==0)
  88.     { if(KEY==0)
  89.         { keymode=2; keydate=1;D7=0;} else {keymode=0; break;}
  90.     }
  91.     else
  92.     {
  93.     keycount--;
  94.     break;}
  95.    case 0x02:
  96.         if(KEY==1)
  97.        { keymode=0; D7=1; break;}
  98.      else
  99.      {keymode=3; keycount=50;  break; }
  100.    case 0x03:
  101.         if(KEY==1)
  102.      { keymode=0; D7=1; break;}
  103.     else
  104.      if(keycount==0)
  105.       { keymode=4; D6=1; break; }
  106.     else
  107.     { keycount--; break;}
  108.    case 0x04:
  109.      if(KEY==1)
  110.      {keymode=0; D7=1; break;}
  111.    else
  112.      break;
  113.   
  114.    default: break;
  115.    }  
  116.   //以下的键值调时间处理
  117.    if(D7==1)
  118. {
  119.     if(D6==0) {
  120.   if(c==1) hour++;
  121.     if(hour==24) hour=0;
  122.   if(c==2) minute++;
  123.   if(minute==60) minute=0;
  124.   D7=0; }
  125.     else
  126.   {c++; if(c>2) c=0; D6=0; D7=0;}
  127.   }
  128.   

  129.   disbuf[0]=(second);
  130.   disbuf[1]=(second/10);
  131.   disbuf[2]=(minute);
  132.   disbuf[3]=(minute/10);
  133.   disbuf[4]=(hour);
  134.   disbuf[5]=(hour/10);
  135.   display();              //调用显示函数

  136. }
  137. }

  138. void init()
  139. {
  140. TMOD=1;TH0=0X3C;TL0=0XB0;       //定时器0模式1,50毫秒
  141. ET0=1;TR0=1;EA=1;           //开定时器0中断、启动定时器0、开总中断
  142. }

  143. void display( )
  144. {
  145.    unsigned char i,j=0;  //j为列位置变量
  146.    
  147.             
  148.                for(i=0;i<5;i++)                                   //时十位
  149.                      {
  150.                       if(disbuf[5]==0) P0=0x00;             //时十分为0时不显示
  151.                               else P0=ASCII86[disbuf[5]];
  152.         P1=seg[j][0]; P3=seg[j][1]; P2=seg[j][2];
  153.                         delay(1);
  154.              P1=0xff; P3=0xff; P2=0xff;
  155.                         j++;      
  156.                       }
  157.         j++;                          //隔一列            
  158.                  
  159.      for(i=0;i<5;i++)                                 //时个位
  160.                      {
  161.                       if(c==1&&SHAN)P0=0x00;
  162.         else P0=ASCII86[disbuf[4]];          //调时状态时个位闪烁
  163.              P1=seg[j][0]; P3=seg[j][1]; P2=seg[j][2];
  164.                         delay(1);
  165.              P1=0xff; P3=0xff; P2=0xff;
  166.                         j++;      
  167.                       }
  168.    if(!SHAN) {P0=0x81;} else P0=0x00;          //秒闪
  169.            
  170.                  P1=seg[j][0]; P3=seg[j][1]; P2=seg[j][2];              
  171.                         delay(1);
  172.        P1=0xff; P3=0xff; P2=0xff;
  173.                         j++;      
  174.                 for(i=0;i<5;i++)                                    //分十位
  175.                      {
  176.                       P0=ASCII86[disbuf[3]];
  177.              P1=seg[j][0]; P3=seg[j][1]; P2=seg[j][2];
  178.                         delay(1);
  179.              P1=0xff; P3=0xff; P2=0xff;
  180.                         j++;      
  181.                       }
  182.         j++;
  183.      for(i=0;i<5;i++)                                    //分个位
  184.                      {
  185.                       if(c==2&&SHAN)P0=0x00;
  186.         else P0=ASCII86[disbuf[2]];     //调分状态时分闪烁
  187.              P1=seg[j][0]; P3=seg[j][1]; P2=seg[j][2];
  188.                         delay(1);
  189.              P1=0xff; P3=0xff; P2=0xff;
  190.                         j++;      
  191.                       }
  192.    

  193. }

  194. void delay(uchar t)
  195. {
  196. uchar i;               //定义变量
  197. for(;t>0;t--)             //如果t大于0,t减1(外层循环)
  198.   for(i=124;i>0;i--);         //i等于124,如果i大于0,i减1
  199. }


  200. void timer0() interrupt 1        //定时器0(中断1)
  201. {
  202.    uchar tim1,tim2;           //定义临时变量
  203. TL0=TL0+0XB0;TH0=0X3C;        //重装定时器初值
  204. tim1++;                //每中断一次tim1加1
  205. if(tim1==10)             //中断10(0.5秒)
  206. {                  
  207.   SHAN=!SHAN;             //闪烁标志取反
  208.   tim1=0;tim2++;           //tim1清零,tim2加1
  209.   if(tim2==2)             //到了1秒
  210.   {
  211.    tim2=0;second++;         //tim2清零,秒加1
  212.    if(second>=60)          //如果秒到60
  213.    {               
  214.     second=0;minute++;       //秒变0,分加1
  215.     if(minute>=60)         //如果分到60
  216.     {
  217.      minute=0;hour++;       //分变0,时加1
  218.      if(hour>=24) hour=0;     //如果时到24,时变0
  219.     }
  220.    }
  221.   }
  222. }
  223. }
复制代码



回复

使用道具 举报

ID:74992 发表于 2015-4-10 12:41 | 显示全部楼层
做得不错,浅显易懂。
回复

使用道具 举报

ID:76554 发表于 2015-4-11 23:59 | 显示全部楼层
做得不错,不过就是点阵中,时间的那两点看不是清楚
回复

使用道具 举报

ID:166064 发表于 2017-3-11 20:42 | 显示全部楼层
做得不错,不过就是点阵中,时间的那两点看不是清楚  
回复

使用道具 举报

ID:99130 发表于 2017-7-2 16:16 | 显示全部楼层
不错 就是中间的冒号可以往中间靠一点,太靠边了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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