找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机万年历的设计(带字库12864屏)程序及原理图和pcb图

  [复制链接]
ID:260378 发表于 2017-12-11 21:16 | 显示全部楼层 |阅读模式
该万年历具备闹钟时间设置,程序和原理图PCB图都放在附件里
1510462245295.jpg 1510462097123_副本.jpg
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
2017-12-11_210632.png 0.png
单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include "ds1302.h"
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. //变量定义
  7. uint count;
  8. SYSTEMTIME CurrentTime;
  9. uchar count1=0,count2=0,s1num=0;
  10. uchar flag=1,flag_rd=0;
  11. uchar miao,fen,shi,week,day,month,year;
  12. uchar miao1=0,fen1=0,shi1=0;
  13. /*12864端口定义*/
  14. #define LCD_data  P1             //数据口
  15. sbit LCD_RS  =  P2^7;            //寄存器选择输入
  16. sbit LCD_RW  =  P2^6;            //液晶读/写控制
  17. sbit LCD_EN  =  P2^5;            //液晶使能控制
  18. sbit LCD_PSB =  P2^4;            //串/并方式控制
  19. sbit LCD_RST =  P2^3;                           //复位
  20. //按键
  21. sbit s1=P0^0;
  22. sbit s2=P0^1;
  23. sbit s3=P0^2;
  24. sbit rd=P0^3;
  25. //蜂鸣器
  26. sbit beep=P3^7;

  27. uchar code dis1[] = {"20  年  月  日"};
  28. uchar code dis2[] = {"当前"};
  29. uchar code dis3[] = {"      时  分  秒"};
  30. uchar code dis4[] = {"----万年历----"};
  31. uchar code dis5[] = {"闹钟"};
  32. uchar code day0[]  = {"星期日"};
  33. uchar code day1[]  = {"星期一"};
  34. uchar code day2[]  = {"星期二"};
  35. uchar code day3[]  = {"星期三"};  
  36. uchar code day4[]  = {"星期四"};
  37. uchar code day5[]  = {"星期五"};
  38. uchar code day6[]  = {"星期六"};
  39. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
  40. //uchar IRDIS[2];
  41. //uchar IRCOM[4];
  42. void delay(int ms);                                //延时函数
  43. bit lcd_busy();                                                //忙检测
  44. void lcd_wcmd(uchar cmd);        //写命令
  45. void lcd_wdat(uchar dat);        //写数据
  46. void lcd_init();                                //12864初始化
  47. void DS1302_Getdate();        //获取当前1302时间
  48. void keyscan();                                        //按键扫描
  49. void rd_set();                                        //闹钟设置界面
  50. void di();                                                        //按键提示声
  51. void menu_timer();                        //时间显示界面
  52. void DS1302_Setdate();        //设置1302时间
  53. void menu(void);                                //主界面
  54. void lcd_pos(uchar X,uchar Y); //确定显示位置
  55. void time_init(void);                        //定时器初始化
  56. void lcd_write_char(uchar x_temp,uchar y_temp,uchar date);        //任一位置显示数字函数
  57. unsigned char GetWeekFromDay(unsigned char year,unsigned char month,unsigned char day);//计算星期函数
  58. /*********************************************************/
  59. /*                                                                                                                 */
  60. /* 主程序                                                                                    */
  61. /*                                                       */
  62. /*********************************************************/
  63. void main(void)
  64. {
  65.         lcd_init();         //初始化LCD      
  66.         time_init();                                //初始化定时器
  67.         delay(10);          //延时         
  68.         menu();                                                        //界面
  69.         DS1302_Getdate();                //上电获取时间
  70.         if(day==0&&month==0);//如果数据错误复位为2017年11月2日10时10分10秒
  71.         {
  72.                 year=17;
  73.                 month=11;
  74.                 day=2;
  75.                 week=4;
  76.                 shi=10;
  77.                 fen=10;
  78.                 miao=10;
  79.                 DS1302_Setdate();
  80.         }
  81.         while(1)
  82.         {
  83.                 keyscan();
  84.                 if(miao1==CurrentTime.Second&&fen1==CurrentTime.Minute&&shi1==CurrentTime.Hour&&flag_rd==2)
  85.                 {        //判断闹钟时间,相同则蜂鸣器响5下
  86.                         int i;
  87.                         for(i=0;i<5;i++)
  88.                         {
  89.                                 delay(200);
  90.                                 di();
  91.                         }
  92.                 }
  93.         }
  94. }


  95. /*******************************************************************/
  96. /*                                                                 */
  97. /*  延时函数                                                       */
  98. /*                                                                 */
  99. /*******************************************************************/
  100. void delay(int ms)
  101. {
  102.     while(ms--)
  103.         {
  104.       uchar i;
  105.           for(i=0;i<250;i++)  
  106.            {
  107.             _nop_();                           
  108.                 _nop_();
  109.                 _nop_();
  110.                 _nop_();
  111.            }
  112.         }
  113. }               
  114. /*******************************************************************/
  115. /*                                                                 */
  116. /*检查LCD忙状态                                                    */
  117. /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。      */
  118. /*                                                                 */
  119. /*******************************************************************/
  120. bit lcd_busy()
  121. {                          
  122.     bit result;
  123.     LCD_RS = 0;
  124.     LCD_RW = 1;
  125.     LCD_EN = 1;
  126.     delayNOP();
  127.     result = (bit)(P1&0x80);
  128.     LCD_EN = 0;
  129.     return(result);
  130. }
  131. /*******************************************************************/
  132. /*                                                                 */
  133. /*写指令数据到LCD                                                  */
  134. /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             */
  135. /*                                                                 */
  136. /*******************************************************************/
  137. void lcd_wcmd(uchar cmd)
  138. {                          
  139.    while(lcd_busy());
  140.     LCD_RS = 0;
  141.     LCD_RW = 0;
  142.     LCD_EN = 0;
  143.     _nop_();
  144.     _nop_();
  145.     P1 = cmd;
  146.     delayNOP();
  147.     LCD_EN = 1;
  148.     delayNOP();
  149.     LCD_EN = 0;  
  150. }
  151. /*******************************************************************/
  152. /*                                                                 */
  153. /*写显示数据到LCD                                                  */
  154. /*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               */
  155. /*                                                                 */
  156. /*******************************************************************/
  157. void lcd_wdat(uchar dat)
  158. {                          
  159.    while(lcd_busy());
  160.     LCD_RS = 1;
  161.     LCD_RW = 0;
  162.     LCD_EN = 0;
  163.     P1 = dat;
  164.     delayNOP();
  165.     LCD_EN = 1;
  166.     delayNOP();
  167.     LCD_EN = 0;
  168. }
  169. /*******************************************************************/
  170. /*                                                                 */
  171. /*  LCD初始化设定                                                  */
  172. /*                                                                 */
  173. /*******************************************************************/
  174. void lcd_init()
  175. {
  176.     LCD_PSB = 1;         //并口方式
  177.         LCD_RST = 1;
  178.     lcd_wcmd(0x34);      //扩充指令操作
  179.     delay(5);
  180.     lcd_wcmd(0x30);      //基本指令操作
  181.     delay(5);
  182.     lcd_wcmd(0x0C);      //显示开,关光标
  183.     delay(5);
  184.     lcd_wcmd(0x01);      //清除LCD的显示内容
  185.     delay(5);
  186. }

  187. /*********
  188. 从ds1302中读取当前时间
  189. *********/
  190. void DS1302_Getdate()
  191. {
  192.         miao=CurrentTime.Second;
  193.         fen=CurrentTime.Minute;
  194.         shi=CurrentTime.Hour;
  195.         week=CurrentTime.Week;
  196.         day=CurrentTime.Day;
  197.         month=CurrentTime.Month;
  198.         year=CurrentTime.Year;
  199. }
  200. /********
  201. 按键检测
  202. 逻辑过于复杂,不解释
  203. ********/
  204. void keyscan()
  205. {
  206.         if(s1==0)        
  207.         {
  208.                 delay(5);
  209.                 if(s1==0)
  210.                 {        
  211.                         s1num++;
  212.                         while(!s1);
  213.                         di();
  214.                         if(s1num==1)
  215.                         {
  216.                                 flag=0;
  217.                                 DS1302_Getdate();
  218.                                 DS1302_TimeStop(1);  // 是否将时钟停止  1为停止 0为继续
  219.                                 lcd_pos(2,6);
  220.                                 lcd_wcmd(0x0F);      //显示开,开光标
  221.                         }
  222.                         if(s1num==2)
  223.                         {
  224.                                 lcd_pos(2,4);
  225.                         }
  226.                         if(s1num==3)
  227.                         {
  228.                                 lcd_pos(2,2);
  229.                         }
  230.                         if(s1num==4)
  231.                         {
  232.                                 lcd_pos(0,5);
  233.                         }
  234.                         if(s1num==5)
  235.                         {
  236.                                 lcd_pos(0,3);
  237.                         }
  238.                         if(s1num==6)
  239.                         {
  240.                                 lcd_pos(0,1);
  241.                         }
  242.                         if(s1num==7)
  243.                         {
  244.                                 s1num=0;
  245.                                 flag=1;
  246.                                 Initial_DS1302();
  247.                                 week=GetWeekFromDay(year,month,day);
  248.                                 DS1302_Setdate();
  249.                                 DS1302_TimeStop(0);  // 是否将时钟停止  1为停止 0为继续
  250.                                 lcd_wcmd(0x0C);      //显示开,关光标
  251.                         }
  252.                  }
  253.         }
  254.         if(s1num!=0)
  255.         {
  256.                 if(s2==0)
  257.                 {
  258.                         delay(5);
  259.                         if(s2==0)
  260.                         {
  261.                                 while(!s2);
  262.                                 di();
  263.                                 if(s1num==1)
  264.                                 {
  265.                                         miao++;
  266.                                         if(miao==60)
  267.                                                 miao=0;
  268.                                         lcd_write_char(2,6,miao);
  269.                                         lcd_pos(2,6);
  270.                                 }
  271.                                 if(s1num==2)
  272.                                 {
  273.                                         fen++;
  274.                                         if(fen==60)
  275.                                                 fen=0;
  276.                                         lcd_write_char(2,4,fen);
  277.                                         lcd_pos(2,4);
  278.                                 }
  279.                                 if(s1num==3)
  280.                                 {
  281.                                         shi++;
  282.                                         if(shi==24)
  283.                                                 shi=0;
  284.                                         lcd_write_char(2,2,shi);
  285.                                         lcd_pos(2,2);
  286.                                 }
  287.                                 if(s1num==4)
  288.                                 {
  289.                                         day++;
  290.                                         if(day==32)
  291.                                                 day=1;
  292.                                         lcd_write_char(0,5,day);
  293.                                         lcd_pos(0,5);
  294.                                 }
  295.                                 if(s1num==5)
  296.                                 {
  297.                                         month++;
  298.                                         if(month==13)
  299.                                                 month=1;
  300.                                         lcd_write_char(0,3,month);
  301.                                         lcd_pos(0,3);
  302.                                 }
  303.                                 if(s1num==6)
  304.                                 {
  305.                                         year++;
  306.                                         if(year==99)
  307.                                                 year=0;
  308.                                         lcd_write_char(0,1,year);
  309.                                         lcd_pos(0,1);
  310.                                 }
  311.                         }
  312.                 }
  313.                 if(s3==0)
  314.                 {
  315.                         delay(5);
  316.                         if(s3==0)
  317.                         {
  318.                                 while(!s3);
  319.                                 di();
  320.                                 if(s1num==1)
  321.                                 {
  322.                                         miao--;
  323.                                         if(miao==-1)
  324.                                                 miao=59;
  325.                                         lcd_write_char(2,6,miao);
  326.                                         lcd_pos(2,6);
  327.                                 }
  328.                                 if(s1num==2)
  329.                                 {
  330.                                         fen--;
  331.                                         if(fen==-1)
  332.                                                 fen=59;
  333.                                         lcd_write_char(2,4,fen);
  334.                                         lcd_pos(2,4);
  335.                                 }
  336.                                 if(s1num==3)
  337.                                 {
  338.                                         shi--;
  339.                                         if(shi==-1)
  340.                                                 shi=23;
  341.                                         lcd_write_char(2,2,shi);
  342.                                         lcd_pos(2,2);
  343.                                 }
  344.                                 if(s1num==4)
  345.                                 {
  346.                                         day--;
  347.                                         if(day==0)
  348.                                                 
  349. ……………………

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

所有资料51hei提供下载:
程序及原理图和pcb图.zip (117.49 KB, 下载次数: 292)

评分

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

查看全部评分

回复

使用道具 举报

ID:720241 发表于 2020-4-4 19:34 | 显示全部楼层
好像不行,不能显示
回复

使用道具 举报

ID:305245 发表于 2018-4-10 18:20 | 显示全部楼层
正想做一个玩一下,谢了!
回复

使用道具 举报

ID:479749 发表于 2019-3-30 20:38 | 显示全部楼层
是只有闹钟的功能吗
回复

使用道具 举报

ID:643657 发表于 2019-11-25 21:55 | 显示全部楼层
怎么样
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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