找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机创意时钟制作(有PCB+程序,可以直接打板)

  [复制链接]
跳转到指定楼层
楼主
https://v.youku.com/v_show/id_XNDE3OTAzMjc2OA==.html?x&sharefrom=android&sharekey=c76503937c785df7b02933df8c154c891

有重力感应,不管你正放还是反放都能正常显示,可以diy显示,显示号码,就是停车号码牌。温度,时间,月份交替显示。可以自定义显示,有倒计时,计分器,模拟电梯,闹钟,自定义图片文字显示功能。

电路原理图如下:


元件清单



PCB截图



制作步骤:将原理图绘制成PCB,PCB发给厂家打板,根据原件清单购买元器件,焊接,编程调试
焊接注意事项:单片机方向、DS1302时钟芯片方向,二极管方向。不要有虚焊、漏焊。

成品赏析






部分程序
  1. #include "STC15.H"
  2. #define _REAL_TIMER_DS1302_2003_7_21_

  3. sbit  DS1302_CLK = P5^4;              //实时时钟时钟线引脚
  4. sbit  DS1302_IO  = P5^5;              //实时时钟数据线引脚
  5. sbit  DS1302_RST = P2^3;              //实时时钟复位线引脚  
  6. sbit  ACC0 = ACC^0;
  7. sbit  ACC7 = ACC^7;

  8. sbit col1 = P0^0;//点阵上第22脚
  9. sbit col2 = P0^1;//点阵上第21脚
  10. sbit col3 = P0^2;//点阵上第2脚
  11. sbit col4 = P0^3;//点阵上第19脚
  12. sbit col5 = P0^4;//点阵上第5脚
  13. sbit col6 = P0^5;//点阵上第6脚或17脚
  14. sbit col7 = P0^6;//点阵上第16脚
  15. sbit col8 = P0^7;//点阵上第8脚
  16. sbit col9 = P2^0;//点阵上第13脚
  17. sbit col10 = P2^1;//点阵上第10脚
  18. sbit col11= P2^2;//点阵上第11脚
  19. sbit col12 = P1^0;//点阵上第22脚
  20. sbit col13 = P1^1;//点阵上第21脚
  21. sbit col14 = P1^2;//点阵上第2脚
  22. sbit col15 = P1^3;//点阵上第19脚
  23. sbit col16 = P1^4;//点阵上第5脚
  24. sbit col17 = P1^5;//点阵上第6脚或17脚
  25. sbit col18 = P1^6;//点阵上第16脚
  26. sbit col19 = P1^7;//点阵上第8脚
  27. sbit col20 = P2^4;//点阵上第13脚
  28. sbit col21 = P2^5;//点阵上第10脚
  29. sbit col22 = P2^6;//点阵上第11脚

  30. #define AM(X)        X
  31. #define PM(X)        (X+12)                      // 转成24小时制
  32. #define DS1302_SECOND        0x80
  33. #define DS1302_MINUTE        0x82
  34. #define DS1302_HOUR                0x84
  35. #define DS1302_WEEK                0x8A
  36. #define DS1302_DAY                0x86
  37. #define DS1302_MONTH        0x88
  38. #define DS1302_YEAR                0x8C
  39. #define DS1302_RAM(X)        (0xC0+(X)*2)           //用于计算 DS1302_RAM 地址的宏

  40. #define t_hour CurrentTime.TimeString[0]*10+CurrentTime.TimeString[1]
  41. #define t_min CurrentTime.TimeString[2]*10+CurrentTime.TimeString[3]
  42. #define t_sec CurrentTime.TimeString[4]*10+CurrentTime.TimeString[5]
  43. #define t_year CurrentTime.DateString[0]*10+CurrentTime.DateString[1]
  44. #define t_month CurrentTime.DateString[2]*10+CurrentTime.DateString[3]
  45. #define t_day CurrentTime.DateString[4]*10+CurrentTime.DateString[5]

  46. typedef struct __SYSTEMTIME__
  47. {
  48.         unsigned char Second;
  49.         unsigned char Minute;
  50.         unsigned char Hour;
  51.         unsigned char Week;
  52.         unsigned char Day;
  53.         unsigned char Month;
  54.         unsigned char Year;
  55.         unsigned char DateString[8];
  56.         unsigned char TimeString[6];
  57. }SYSTEMTIME;        //定义的时间类型


  58. unsigned int time=0;
  59. unsigned char disp[22],*pdisp;

  60. /******************************DS1302时钟模块***************************************/

  61. void DS1302InputByte(unsigned char d)         //实时时钟写入一字节(内部函数)
  62. {
  63.     unsigned char i;
  64.     ACC = d;
  65.     for(i=8; i>0; i--)
  66.     {
  67.         DS1302_IO = ACC0;                   //相当于汇编中的 RRC
  68.         DS1302_CLK = 1;
  69.         DS1302_CLK = 0;
  70.         ACC = ACC >> 1;
  71.     }
  72. }

  73. unsigned char DS1302OutputByte(void)         //实时时钟读取一字节(内部函数)
  74. {
  75.     unsigned char i;
  76.     for(i=8; i>0; i--)
  77.     {
  78.         ACC = ACC >>1;                                 //相当于汇编中的 RRC
  79.         ACC7 = DS1302_IO;
  80.         DS1302_CLK = 1;
  81.         DS1302_CLK = 0;
  82.     }
  83.     return(ACC);
  84. }

  85. void Write1302(unsigned char ucAddr, unsigned char ucDa)        //ucAddr: DS1302地址, ucData: 要写的数据
  86. {
  87.     DS1302_RST = 0;
  88.     DS1302_CLK = 0;
  89.     DS1302_RST = 1;
  90.     DS1302InputByte(ucAddr);               // 地址,命令
  91.     DS1302InputByte(ucDa);               // 写1Byte数据
  92.     DS1302_CLK = 1;
  93.     DS1302_RST = 0;
  94. }

  95. unsigned char Read1302(unsigned char ucAddr)        //读取DS1302某地址的数据
  96. {
  97.     unsigned char ucData;
  98.     DS1302_RST = 0;
  99.     DS1302_CLK = 0;
  100.     DS1302_RST = 1;
  101.     DS1302InputByte(ucAddr|0x01);        // 地址,命令
  102.     ucData = DS1302OutputByte();         // 读1Byte数据
  103.     DS1302_CLK = 1;
  104.     DS1302_RST = 0;
  105.     return(ucData);
  106. }

  107. void DS1302_SetProtect(bit flag)        //是否写保护
  108. {
  109.         if(flag)
  110.                 Write1302(0x8E,0x10);
  111.         else
  112.                 Write1302(0x8E,0x00);
  113. }

  114. void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时间函数
  115. {
  116.         DS1302_SetProtect(0);
  117.         Write1302(Address, ((Value/10)<<4 | (Value%10)));
  118. }

  119. void DS1302_GetTime(SYSTEMTIME *Time)
  120. {
  121.         unsigned char ReadValue;
  122.         ReadValue = Read1302(DS1302_SECOND);
  123.         Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);        //八进制转换成十进制
  124.         ReadValue = Read1302(DS1302_MINUTE);
  125.         Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  126.         ReadValue = Read1302(DS1302_HOUR);
  127.         Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  128.         ReadValue = Read1302(DS1302_DAY);
  129.         Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);        
  130.         ReadValue = Read1302(DS1302_WEEK);
  131.         Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  132.         ReadValue = Read1302(DS1302_MONTH);
  133.         Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  134.         ReadValue = Read1302(DS1302_YEAR);
  135.         Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);        
  136. }

  137. void DateToStr(SYSTEMTIME *Time)         //
  138. {
  139.         Time->DateString[0] = Time->Year/10 ;         //分离出个位和十位
  140.         Time->DateString[1] = Time->Year%10 ;
  141.         Time->DateString[2] = Time->Month/10;
  142.         Time->DateString[3] = Time->Month%10 ;
  143.         Time->DateString[4] = Time->Day/10 ;
  144.         Time->DateString[5] = Time->Day%10 ;
  145.         Time->DateString[6] = Time->Week/10 ;
  146.         Time->DateString[7] = Time->Week%10 ;
  147. }

  148. void TimeToStr(SYSTEMTIME *Time)
  149. {
  150.         Time->TimeString[0] = Time->Hour/10 ;
  151.         Time->TimeString[1] = Time->Hour%10 ;
  152.         Time->TimeString[2] = Time->Minute/10 ;
  153.         Time->TimeString[3] = Time->Minute%10 ;
  154.         Time->TimeString[4] = Time->Second/10;
  155.         Time->TimeString[5] = Time->Second%10 ;
  156. }

  157. bit Initial_DS1302(void)
  158. {
  159.         unsigned char Second=Read1302(DS1302_SECOND);
  160.         if(Second&0x80)                  
  161.         {
  162.                 DS1302_SetTime(DS1302_SECOND,0);
  163.                 return         1;
  164.         }
  165.         return 0;
  166. }
  167. /*****************************************************************************/

  168. /************************点阵显示函数**************************/

  169. code char num_font1[]={
  170.                         0x3E,0x51,0x45,0x3E,//"0"
  171.                     0x00,0x21,0x7F,0x01,//"1"
  172.                         0x23,0x45,0x49,0x31,//"2"
  173.                         0x22,0x49,0x59,0x2E,//"3"
  174.                         0x0C,0x14,0x24,0x7F,//"4"
  175.                         0x72,0x51,0x51,0x4E,//"5"
  176.                         0x0E,0x19,0x29,0x46,//"6"
  177.                         0x40,0x4F,0x50,0x60,//"7"
  178.                         0x36,0x49,0x49,0x36,//"8"
  179.                         0x32,0x49,0x49,0x3E,//"9"
  180.                         0x00,0x36,0x36,0x00,//"::"
  181.                         };

  182. void buf_data(char num1,char num2)
  183. {
  184.         char i;
  185.         pdisp=&disp[0];
  186.         for(i=0;i<4;i++)
  187.         {
  188.                 *pdisp = num_font1[4*(num1/10)+i];
  189.                 pdisp++;
  190.         }
  191.         *pdisp = 0x00;
  192.         pdisp++;
  193.         for(i=0;i<4;i++)
  194.         {
  195.                 *pdisp = num_font1[4*(num1%10)+i];
  196.                 pdisp++;
  197.         }
  198.         for(i=0;i<4;i++)
  199.         {
  200.                 *pdisp = num_font1[40+i];
  201.                 pdisp++;
  202.         }
  203.         for(i=0;i<4;i++)
  204.         {
  205.                 *pdisp = num_font1[4*(num2/10)+i];
  206.                 pdisp++;
  207.         }
  208.         *pdisp = 0x00;
  209.         pdisp++;
  210.         for(i=0;i<4;i++)
  211.         {
  212.                 *pdisp = num_font1[4*(num2%10)+i];
  213.                 pdisp++;
  214.         }
  215. }

  216. void delay(unsigned int xms)//延时函数,大概延时时间                                
  217. {
  218.         unsigned int i,j;
  219.         for(i=xms;i>0;i--)                      //i=xms即延时约xms毫秒
  220.                 for(j=125;j>0;j--);
  221. }

  222. void led_clear()//清屏        
  223. {
  224.         P4 &= 0x80;
  225.         P1 |= 0xff;
  226.         P0 |= 0xff;
  227.         P2 |= 0x77;
  228. }

  229. void display_frame()//显示一帧画面
  230. {
  231.         char i;
  232.         for(i=0;i<22;i++)
  233.         {
  234.                 led_clear();
  235.                 switch(i+1)
  236.                 {
  237.                         case 1:                col1=0;         break;
  238.                         case 2:                col2=0;         break;
  239.                         case 3:                col3=0;         break;        
  240.                         case 4:                col4=0;         break;
  241.                         case 5:                col5=0;         break;
  242.                         case 6:                col6=0;         break;        
  243.                         case 7:                col7=0;         break;
  244.                         case 8:                col8=0;         break;
  245.                         case 9:                col9=0;         break;
  246.                         case 10:        col10=0; break;
  247.                         case 11:        col11=0; break;
  248.                         case 12:        col12=0; break;
  249.                         case 13:        col13=0; break;
  250.                         case 14:        col14=0; break;        
  251.                         case 15:        col15=0; break;
  252.                         case 16:        col16=0; break;
  253.                         case 17:        col17=0; break;        
  254.                         case 18:        col18=0; break;
  255.                         case 19:        col19=0; break;
  256.                         case 20:        col20=0; break;
  257.                         case 21:        col21=0; break;
  258.                         case 22:        col22=0; break;
  259.                         default:break;
  260.                 }
  261.                 P4=disp[i];
  262.                 if(time>500)
  263.                 {
  264.                         col11 = 1;
  265.                         col12 = 1;
  266.                 }
  267.                 if(time>1000)
  268.                 {
  269.                         time=0;
  270.                 }
  271.                 delay(5);
  272.         }
  273. }
  274. /*****************************************************************/

  275. void Timer0Init(void)                //1毫秒@11.0592MHz
  276. {
  277.         AUXR |= 0x80;                //定时器时钟1T模式
  278.         TMOD &= 0xF0;                //设置定时器模式
  279.         TL0 = 0xCD;                //设置定时初值
  280.         TH0 = 0xD4;                //设置定时初值
  281.         TF0 = 0;                //清除TF0标志
  282.         TR0 = 1;                //定时器0开始计时
  283. }

  284. void init()//初始化设置,推挽输出(强上拉输出,可达20mA)
  285. {
  286.         P1M1 = 0X00;
  287.         P1M0 = 0Xff;
  288.         P2M1 = 0X00;
  289.         P2M0 = 0Xff;
  290.         P4M1 = 0X00;
  291.         P4M0 = 0Xff;
  292. }

  293. void main()
  294. {
  295.         SYSTEMTIME CurrentTime;
  296.         init();        
  297.         led_clear();
  298.         Timer0Init();
  299.         EA=1;            //总中断打开
  300.          ET0=1;           //定时器中断打开
  301.         
  302.         DS1302_SetTime(DS1302_YEAR,0);        // 设置年月日为2000年1月1日
  303.         DS1302_SetTime(DS1302_MONTH,1);
  304.         DS1302_SetTime(DS1302_DAY,1);

  305.         DS1302_SetTime(DS1302_HOUR,0);        //设置的时间是01:00:00
  306.         DS1302_SetTime(DS1302_MINUTE,0);
  307.         DS1302_SetTime(DS1302_SECOND,0);
  308.         
  309.         while(1)
  310.         {        
  311.                 DS1302_GetTime(&CurrentTime);//获取当前时间
  312.                 DateToStr(&CurrentTime);
  313.                 TimeToStr(&CurrentTime);
  314.                 buf_data(t_min,t_sec);
  315.                 display_frame();
  316.         }           
  317. }

  318. void Timer0_isr(void) interrupt 1
  319. {
  320.         time++;
  321. }
复制代码


全部资料51hei下载地址:
创意时钟2.rar (5.07 MB, 下载次数: 60)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:484435 发表于 2019-5-15 20:03 | 只看该作者
谢谢分享
回复

使用道具 举报

板凳
ID:423911 发表于 2020-2-9 06:53 | 只看该作者
谢谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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