找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5960|回复: 8
收起左侧

基于51单片机电子万年历设计 lcd12864+24c02+ds1302

  [复制链接]
ID:522907 发表于 2019-10-17 20:29 | 显示全部楼层 |阅读模式
原则  技术有限 分享无限
作品名称:基于51单片机电子万年历设计
作评功能:1:实现ds1302的读写
                2:lcd12864的显示
                3:24c02的读写
                4:更改日期,时间
                5:整点报时,闹钟的功能
                6:阴阳历的转换
硬件部分:普中开发板(程序内明确标明接线方式)
软件部分:原创
                1:代码规范:易于更改
                2:封装良好,可以直接移植。
1F63723179C3E715DCD5AB9357461A0A.png

单片机源程序如下:
  1. #include "reg51.h"    //此文件中定义了单片机的一些特殊功能寄存器
  2. #include "lcd12864.h"
  3. #include "ds1302.h"
  4. #include "24c04.h"
  5. #include "stdio.h"
  6. #include "string.h"
  7. #include "ALG.h"
  8. //预编译
  9. #define DISPLAY_DATA_SIZE 30                //显示显示一帧数据长度
  10. #define GPIO_KEY P1

  11. //全局变量
  12. unsigned char display_buff[DISPLAY_DATA_SIZE];
  13. unsigned char ds1302_buff[2*sizeof(TIME)];
  14. unsigned char key_value=0xff;
  15. unsigned char receive_buff[sizeof(TIME)];
  16. unsigned char store_row=0;
  17. unsigned char store_line=0;
  18. unsigned char interface_flag=0;
  19. unsigned char ds1302_receive_flag=0;
  20. unsigned char temp[8];
  21. unsigned char display_flag=0;
  22. unsigned char table[32][4]=
  23. {       
  24.         {0x01,0x01, 0x00, 0x12},
  25.         {0x01,0x20, 0x00, 0x12},
  26.         {0x01,0x30, 0x00, 0x12},
  27.         {0x00,0x40, 0x00, 0x12},
  28.         {0x00,0x50, 0x00, 0x12},
  29.         {0x01,0x00, 0x01, 0x12},
  30.         {0x01,0x50, 0x01, 0x12},
  31.         {0x01,0x50, 0x01, 0x12},
  32.         {0x01,0x01, 0x00, 0x12},
  33.         {0x01,0x20, 0x00, 0x12},
  34.         {0x01,0x30, 0x00, 0x12},
  35.         {0x00,0x40, 0x00, 0x12},
  36.         {0x00,0x50, 0x00, 0x12},
  37.         {0x01,0x00, 0x01, 0x12},
  38.         {0x01,0x50, 0x01, 0x12},
  39.         {0x01,0x50, 0x01, 0x12},
  40.         {0x01,0x01, 0x00, 0x12},
  41.         {0x01,0x20, 0x00, 0x12},
  42.         {0x01,0x30, 0x00, 0x12},
  43.         {0x00,0x40, 0x00, 0x12},
  44.         {0x00,0x50, 0x00, 0x12},
  45.         {0x01,0x00, 0x01, 0x12},
  46.         {0x01,0x50, 0x01, 0x12},
  47.         {0x01,0x50, 0x01, 0x12},
  48.         {0x01,0x01, 0x00, 0x12},
  49.         {0x01,0x20, 0x00, 0x12},
  50.         {0x01,0x30, 0x00, 0x12},
  51.         {0x00,0x40, 0x00, 0x12},
  52.         {0x00,0x50, 0x00, 0x12},
  53.         {0x01,0x00, 0x01, 0x12},
  54.         {0x01,0x50, 0x01, 0x12},
  55.         {0x01,0x50, 0x01, 0x12}
  56. };

  57. sbit buzzer=P3^7;
  58. //全局函数声明
  59. void system_init(void);
  60. void delay_ms(int ms);
  61. void lcd_display(char row,char* buff,char num);
  62. void timer_init(void);
  63. void key_check(void);
  64. void major_interface(void);
  65. void store_interface(void);
  66. void time_interface(void);
  67. void key_pro(void);
  68. void bcd_to_ascii(unsigned char* buff,unsigned char num);
  69. void data_pro(unsigned char*des_buff,unsigned char*src_buff,unsigned char num);
  70. /*
  71.         biref                主函数
  72.         param                无
  73.         return        无
  74. */
  75. void main(void)
  76. {       
  77.         unsigned char temp[7];
  78.         unsigned char i=0;
  79.         system_init();
  80.         //在24cxx中读取数据。
  81.         for(i=0;i<32;i++)
  82.         {
  83.                 read_24cxx(0x00+i*4,table+i,4);
  84.         }
  85.         while(1)
  86.         {  
  87.                 major_interface();
  88.                 store_interface();
  89.                 time_interface();
  90.                 key_check();
  91.                 key_pro();
  92.         }               
  93. }

  94. /*
  95.         biref                系统初始化函数
  96.         param                无
  97.         return        无
  98. */
  99. void system_init(void)
  100. {
  101.         LCD12864_Init();
  102.         Ds1302Init(TIME);
  103. //        Ds18b20Init();
  104.         timer_init();
  105. }

  106. /*
  107.         biref         延时函数
  108.         param                延时时间,单位ms;
  109.         return        无
  110. */
  111. void delay_ms(int ms)
  112. {
  113.         int x,i;
  114.         x=ms;
  115.         while(x--)
  116.                 for(i=123;i;i--);
  117. }
  118. /*
  119.         biref                12864显示函数
  120.         param                显示缓存区
  121.         return        无
  122. */
  123. void lcd_display(char row,char* buff,char num)
  124. {
  125.         unsigned int i;
  126.                
  127.         switch(row)
  128.         {
  129.                 case 0:
  130.                 {
  131.                         LCD12864_SetWindow(0, 0);
  132.                         for(i=0;i<num;i++)
  133.                         {
  134.                                 LCD12864_WriteData(buff[i]);
  135.                         }
  136.                         break;
  137.                 }
  138.                 case 1:
  139.                 {
  140.                         LCD12864_SetWindow(1, 0);
  141.                         for(i=0;i<num;i++)
  142.                         {
  143.                                 LCD12864_WriteData(buff[i]);
  144.                         }
  145.                         break;
  146.                 }
  147.                 case 2:
  148.                 {
  149.                         LCD12864_SetWindow(2, 0);
  150.                         for(i=0;i<num;i++)                       
  151.                         {
  152.                                 LCD12864_WriteData(buff[i]);
  153.                         }
  154.                         break;
  155.                 }
  156.                 case 3:
  157.                 {
  158.                         LCD12864_SetWindow(3, 0);
  159.                         for(i=0;i<num;i++)
  160.                         {
  161.                                 LCD12864_WriteData(buff[i]);
  162.                         }
  163.                         break;
  164.                 }
  165.                 default:
  166.                 {
  167.                         break;
  168.                 }
  169.         }
  170. }
  171. /*
  172.         biref                BCD码转换到ASCII
  173.         param                无
  174.         return        无
  175. */
  176. void bcd_to_ascii(unsigned char* buff,unsigned char num)
  177. {
  178.         unsigned int i;
  179.         for(i=0;i<num;i++)
  180.         {
  181.                 if(buff[i]>=0&&buff[i]<=9)
  182.                         buff[i]+=0x30;
  183.         }
  184. }
  185. /*
  186.         biref                ds1302数据处理函数
  187.         param                des_buff                目标数组
  188.                                         src_buff                源数组
  189.                                         num                                        源头数组长度
  190.         return        无
  191. */
  192. void data_pro(unsigned char* des_buff,unsigned char*src_buff,unsigned char num)
  193. {
  194.         unsigned int i;
  195.         unsigned char t;
  196.         for(i=0;i<num;i++)
  197.         {
  198.                 des_buff[2*i]=src_buff[i]/16;
  199.                 des_buff[2*i+1]=src_buff[i]%16;
  200.         }
  201.        
  202.         for(i=0;i<num;i++)//实现数组的整体倒序
  203.         {
  204.                 t=des_buff[i];
  205.                 des_buff[i]=des_buff[2*num-1-i];
  206.                 des_buff[2*num-1-i]=t;
  207.         }
  208.        
  209.         for(i=0;i<num;i++)
  210.         {
  211.                 t=des_buff[2*i];
  212.                 des_buff[2*i]=des_buff[2*i+1];
  213.                 des_buff[2*i+1]=t;
  214.         }
  215. }

  216. /*
  217.         biref                定时器0初始化
  218.         param                无
  219.         return        无
  220. */
  221. void timer_init(void)
  222. {
  223.         TMOD|=0X01;
  224.         TH0=(65536-50000)/0xff;       
  225.         TL0=(65536-50000)%0xff;       
  226.         ET0=1;
  227.         EA=1;
  228.         TR0=1;
  229. }

  230. /*
  231.         biref                定时器0中断服务函数
  232.         param                无
  233.         return        无
  234. */
  235. void Timer0() interrupt 1
  236. {
  237.         static unsigned char number=0;
  238.         unsigned char i=0;
  239.         TH0=(65536-50000)/0xff;       
  240.         TL0=(65536-50000)%0xff;       
  241.         number++;
  242.         if(number==20)
  243.         {
  244.                 Ds1302ReadTime();
  245.                 ds1302_receive_flag=1;
  246.                 if(TIME[0]==0x00 &&TIME[1]==0x00)
  247.                 {
  248.                         for(i=0;i<200;i++)
  249.                         {
  250.                                 buzzer=~buzzer;
  251.                                 delay_ms(2);
  252.                         }
  253.                 }
  254.                 for(i=0;i<32;i++)
  255.                 {
  256.                         if(!strncmp(table[0]+1+i*sizeof(table[0]),TIME,sizeof(table[0])-1)&& *(table[0]+i*sizeof(table[0]))==0x01 )
  257.                         {
  258.                                 for(i=0;i<50;i++)
  259.                                 {
  260.                                         buzzer=~buzzer;
  261.                                         delay_ms(20);
  262.                                 }
  263.                                 break;
  264.                         }
  265.                 }
  266.                 number=0;
  267.         }       
  268. }

  269. /*
  270.         biref                按键检测
  271.         param                无
  272.         return        无
  273. */
  274. void key_check(void)
  275. {
  276.         char a=0;
  277.         GPIO_KEY=0x0f;
  278.         key_value=0xff;
  279.         if(GPIO_KEY!=0x0f)//读取按键是否按下
  280.         {
  281.                 delay_ms(10);//延时10ms进行消抖
  282.                 if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
  283.                 {       
  284.                         //测试列
  285.                         GPIO_KEY=0X0F;
  286.                         switch(GPIO_KEY)
  287.                         {
  288.                                 case(0X07):        key_value=0;break;
  289.                                 case(0X0b):        key_value=1;break;
  290.                                 case(0X0d): key_value=2;break;
  291.                                 case(0X0e):        key_value=3;break;
  292.                         }
  293.                         //测试行
  294.                         GPIO_KEY=0XF0;
  295.                         switch(GPIO_KEY)
  296.                         {
  297.                                 case(0X70):        key_value=key_value;break;
  298.                                 case(0Xb0):        key_value=key_value+4;break;
  299.                                 case(0Xd0): key_value=key_value+8;break;
  300.                                 case(0Xe0):        key_value=key_value+12;break;
  301.                         }
  302.                         while((a<50)&&(GPIO_KEY!=0xf0))         //检测按键松手检测
  303.                         {
  304.                                 delay_ms(10);
  305.                                 a++;
  306.                         }
  307.                 }
  308.         }
  309. }

  310. /*
  311.         biref                按键处理
  312.         param                无
  313.         return        无
  314. */
  315. unsigned char key_num=1;
  316. void key_pro(void)
  317. {
  318.         unsigned char i=0;
  319.         unsigned char temp[7],t;
  320.         switch(key_value)
  321.         {
  322.                 case 0:
  323.                 case 1:
  324.                 case 2:
  325.                 case 3:
  326.                 case 4:
  327.                 case 5:
  328.                 case 6:
  329.                 case 7:
  330.                 case 8:
  331.                 case 9:
  332.                 {
  333.                         if(interface_flag==1)//存储界面的按键
  334.                         {
  335.                                 if(key_num%2==1)
  336.                                 {
  337.                                         table[store_row][sizeof(table[0])-1-store_line]=table[store_row][sizeof(table[0])-1-store_line]&0x0f|key_value<<4;
  338.                                         key_num++;
  339.                                 }
  340.                                 else
  341.                                 {
  342.                                         table[store_row][sizeof(table[0])-1-store_line]=table[store_row][sizeof(table[0])-1-store_line]&0xf0|key_value;
  343.                                         key_num++;
  344.                                         if(store_line<=1)
  345.                                                 store_line++;
  346.                                         else
  347.                                                 store_line=2;
  348.                                 }
  349.                                 display_flag=1;
  350.                         }
  351.                         else if(interface_flag==2)//时间更改界面的按键
  352.                         {
  353.                                 if(key_num%2==1)
  354.                                 {
  355.                                         ds1302_buff[2*store_line]=key_value+0x30;
  356.                                         key_num++;
  357.                                 }
  358.                                 else
  359.                                 {
  360.                                         ds1302_buff[2*store_line+1]=key_value+0x30;
  361.                                         key_num++;
  362.                                         if(store_line<=5)
  363.                                                 store_line++;
  364.                                         else
  365.                                                 store_line=6;
  366.                                 }
  367.                                 display_flag=1;
  368.                         }
  369.                         else
  370.                         {
  371.                                
  372.                         }
  373.                         break;
  374.                 }
  375.                 case 10:
  376.                 {
  377.                         if(store_line>=1)
  378.                                 store_line--;
  379.                         else
  380.                                 store_line=0;
  381.                         display_flag=1;
  382.                         break;
  383.                 }
  384.                 case 11:
  385.                 {
  386.                         if(interface_flag==1)
  387.                         {
  388.                                 if(store_line<=1)
  389.                                         store_line++;
  390.                                 else
  391.                                         store_line=2;
  392.                                 display_flag=1;
  393.                         }
  394.                         else if(interface_flag==2)
  395.                         {
  396.                                 if(store_line<=5)
  397.                                         store_line++;
  398.                                 else
  399.                                         store_line=6;
  400.                                 display_flag=1;
  401.                         }
  402.                         else
  403.                         {

  404.                         }
  405.                         break;
  406.                 }
  407.                 case 12:
  408.                 {
  409.                         if(store_row<=30)
  410.                                 store_row++;
  411.                         else
  412.                                 store_row=31;
  413.                         display_flag=1;
  414.                         break;
  415.                 }
  416.                 case 13:
  417.                 {
  418.                         if(store_row>=1)
  419.                                 store_row--;
  420.                         else
  421.                                 store_row=0;
  422.                         display_flag=1;
  423.                         break;
  424.                 }
  425.                 case 14://界面切换按钮
  426.                 {
  427.                         if(interface_flag==0)
  428.                         {
  429.                                 LCD12864_WriteCmd(0x01);
  430.                                 interface_flag=1;
  431.                                 store_line=0;
  432.                                 store_row=0;
  433.                                 display_flag=1;
  434.                                 key_num=1;
  435.                         }
  436.                         else if(interface_flag==1)
  437.                         {
  438.                                 for(i=0;i<32;i++)
  439.                                 {
  440.                                         write_24cxx(0x00+4*i,table+i,sizeof(table[0]));
  441.                                 }
  442.                                 LCD12864_WriteCmd(0x01);
  443.                                 display_flag=1;
  444.                                 interface_flag=2;
  445.                                 store_line=0;
  446.                                 store_row=1;
  447.                                 key_num=1;
  448.                         }
  449.                         else if(interface_flag==2)
  450.                         {
  451.                                 LCD12864_WriteCmd(0x01);
  452.                                 for(i=0;i<sizeof(ds1302_buff)/sizeof(ds1302_buff[0]);i++)
  453.                                 {
  454.                                         ds1302_buff[i]-=0x30;
  455.                                 }
  456.                                 for(i=0;i<sizeof(ds1302_buff)/sizeof(ds1302_buff[0]);i++)
  457.                                 {
  458.                                         temp[i]=(ds1302_buff[2*i]<<4)+ds1302_buff[2*i+1];
  459.                                 }
  460.                                 for(i=0;i<sizeof(temp)/sizeof(temp[0])/2;i++)
  461.                                 {
  462.                                         t=temp[i];
  463.                                         temp[i]=temp[sizeof(temp)-1-i];
  464.                                         temp[sizeof(temp)-1-i]=t;
  465.                                 }
  466.                                 Ds1302Init(temp);
  467.                                 display_flag=1;
  468.                                 interface_flag=0;
  469.                         }
  470.                         else
  471.                         {
  472.                                 while(1);
  473.                         }
  474.                         break;
  475.                 }
  476.                 case 15:
  477.                 {
  478.                         table[store_row][0]=~table[store_row][0];
  479.                         display_flag=1;
  480.                         break;
  481.                 }
  482.                 default:
  483.                         break;
  484.         }
  485. }
  486. /*
  487.         biref                主要界面显示
  488.         param                无
  489.         return        无
  490. */
  491. void major_interface(void)
  492. {
  493.         if(interface_flag==0&&ds1302_receive_flag==1)
  494.         {
  495.                 ds1302_receive_flag=0;
  496.                 LCD12864_WriteCmd(0x0c);
  497.                 Ds1302ReadTime();
  498.                 data_pro(ds1302_buff,TIME,sizeof(TIME)/sizeof(TIME[0]));
  499.                 solar_to_lunar(2000+ds1302_buff[0]*10+ds1302_buff[1],ds1302_buff[4]*10+ds1302_buff[2],ds1302_buff[6]*10+ds1302_buff[7],display_buff);
  500.                 lcd_display(3,display_buff,8);
  501.                 bcd_to_ascii(ds1302_buff,sizeof(ds1302_buff)/sizeof(ds1302_buff[0]));
  502.                 sprintf(display_buff,"20%2.2s年%2.2s月%2.2s日",ds1302_buff,ds1302_buff+4,ds1302_buff+6);
  503.                 lcd_display(0,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
  504.                 sprintf(display_buff,"    星期%2.2s     ",ds1302_buff+2);
  505.                 lcd_display(1,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
  506.                 sprintf(display_buff,"  %2.2s时%2.2s分%2.2s秒  ",ds1302_buff+8,ds1302_buff+10,ds1302_buff+12);
  507.                 lcd_display(2,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
  508.         }
  509. }
  510. /*
  511.         biref        存储界面
  512.         param        无
  513.         return        无
  514. */
  515. void store_interface(void)
  516. {
  517.         unsigned char i;
  518.         if(interface_flag==1)
  519.         {
  520.                 if(display_flag==1)
  521.                 {
  522.                         for(i=0;i<4;i++)
  523.                         {
  524.                                 data_pro(temp,table+4*(store_row/4)+i,sizeof(table[0]));
  525.                                 bcd_to_ascii(temp,sizeof(temp)/sizeof(temp[0]));
  526.                                 if(temp[7]=='1')
  527.                                 {
  528.                                         sprintf(display_buff,"%6.2s--%2.2s--%2.2s开",temp,temp+2,temp+4);
  529.                                         display_buff[0]=(store_row/4*4+i)/10+0x30;
  530.                                         display_buff[1]=(store_row/4*4+i)%10+0x30;
  531.                                         lcd_display(i,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
  532.                                 }
  533.                                 else
  534.                                 {
  535.                                         sprintf(display_buff,"%6.2s--%2.2s--%2.2s关",temp,temp+2,temp+4);
  536.                                         display_buff[0]=(store_row/4*4+i)/10+0x30;
  537.                                         display_buff[1]=(store_row/4*4+i)%10+0x30;
  538.                                         lcd_display(i,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
  539.                                 }
  540.                         }
  541.                         display_flag=0;
  542.                 }
  543.                 LCD12864_WriteCmd(0x0f);
  544.                 switch(store_line)
  545.                 {
  546.                         case 0:
  547.                                 LCD12864_SetWindow(store_row%4,2);
  548.                                 break;
  549.                         case 1:
  550.                                 LCD12864_SetWindow(store_row%4,4);
  551.                                 break;
  552.                         case 2:
  553.                                 LCD12864_SetWindow(store_row%4,6);
  554.                                 break;
  555.                         case 3:
  556.                                 LCD12864_SetWindow(store_row%4,7);
  557.                                 break;
  558.                         default:
  559.                                 break;
  560.                 }
  561.                
  562.         }
  563. }

  564. /*
  565.         biref        时间调节界面
  566.         param        无
  567.         return        无
  568. */
  569. void time_interface(void)
  570. {
  571.         unsigned char str[]="更改时间界面";
  572.         if(interface_flag==2)
  573.         {
  574.                 if(display_flag==1)
  575.                 {
  576.                         lcd_display(0,str,sizeof(str));
  577.                         sprintf(display_buff,"20%2.2s年%2.2s月%2.2s日",ds1302_buff,ds1302_buff+4,ds1302_buff+6);
  578.                         lcd_display(1,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
  579.                         sprintf(display_buff,"    星期%2.2s     ",ds1302_buff+2);
  580.                         lcd_display(2,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
  581.                         sprintf(display_buff,"  %2.2s时%2.2s分%2.2s秒  ",ds1302_buff+8,ds1302_buff+10,ds1302_buff+12);
  582.                         lcd_display(3,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
  583.                         display_flag=0;
  584.                 }
  585.                
  586.                 LCD12864_WriteCmd(0x0f);
  587.                 switch(store_line)
  588.                 {
  589.                         case 0:
  590.                                 LCD12864_SetWindow(1,1);
  591.                                 break;
  592.                         case 1:
  593.                                 LCD12864_SetWindow(2,4);
  594.                                 break;
  595.                         case 2:
  596.                                 LCD12864_SetWindow(1,3);
  597.                                 break;
  598.                         case 3:
  599.                                 LCD12864_SetWindow(1,5);
  600.                                 break;
  601.                         case 4:
  602.                                 LCD12864_SetWindow(3,1);
  603.                                 break;
  604.                         case 5:
  605.                                 LCD12864_SetWindow(3,3);
  606.                                 break;
  607.                         case 6:
  608.                                 LCD12864_SetWindow(3,5);
  609.                                 break;
  610.                         default:
  611.                                 break;
  612.                 }
  613.         }
  614. }
复制代码

所有资料51hei提供下载:
电子万年历.rar (141.26 KB, 下载次数: 317)

评分

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

查看全部评分

回复

使用道具 举报

ID:84745 发表于 2019-10-20 11:57 来自手机 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:699321 发表于 2020-2-27 22:52 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:709315 发表于 2020-3-17 17:11 | 显示全部楼层
你好 请问有原理图吗?
回复

使用道具 举报

ID:669769 发表于 2020-4-19 08:50 | 显示全部楼层
编译没通过!!!
回复

使用道具 举报

ID:836280 发表于 2020-10-29 17:23 | 显示全部楼层
想知道压缩包里除了代码还有啥
回复

使用道具 举报

ID:837495 发表于 2020-11-2 09:35 | 显示全部楼层
请问这个支持仿真吗?
回复

使用道具 举报

ID:587458 发表于 2020-11-11 21:57 | 显示全部楼层
给个原理图呗
回复

使用道具 举报

ID:865245 发表于 2021-1-7 17:07 | 显示全部楼层
表示看不出这么接线。。。。。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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