原则 技术有限 分享无限
作品名称:基于51单片机电子万年历设计
作评功能:1:实现ds1302的读写
2:lcd12864的显示
3:24c02的读写
4:更改日期,时间
5:整点报时,闹钟的功能
6:阴阳历的转换
硬件部分:普中开发板(程序内明确标明接线方式)
软件部分:原创
1:代码规范:易于更改
2:封装良好,可以直接移植。
单片机源程序如下:
- #include "reg51.h" //此文件中定义了单片机的一些特殊功能寄存器
- #include "lcd12864.h"
- #include "ds1302.h"
- #include "24c04.h"
- #include "stdio.h"
- #include "string.h"
- #include "ALG.h"
- //预编译
- #define DISPLAY_DATA_SIZE 30 //显示显示一帧数据长度
- #define GPIO_KEY P1
- //全局变量
- unsigned char display_buff[DISPLAY_DATA_SIZE];
- unsigned char ds1302_buff[2*sizeof(TIME)];
- unsigned char key_value=0xff;
- unsigned char receive_buff[sizeof(TIME)];
- unsigned char store_row=0;
- unsigned char store_line=0;
- unsigned char interface_flag=0;
- unsigned char ds1302_receive_flag=0;
- unsigned char temp[8];
- unsigned char display_flag=0;
- unsigned char table[32][4]=
- {
- {0x01,0x01, 0x00, 0x12},
- {0x01,0x20, 0x00, 0x12},
- {0x01,0x30, 0x00, 0x12},
- {0x00,0x40, 0x00, 0x12},
- {0x00,0x50, 0x00, 0x12},
- {0x01,0x00, 0x01, 0x12},
- {0x01,0x50, 0x01, 0x12},
- {0x01,0x50, 0x01, 0x12},
- {0x01,0x01, 0x00, 0x12},
- {0x01,0x20, 0x00, 0x12},
- {0x01,0x30, 0x00, 0x12},
- {0x00,0x40, 0x00, 0x12},
- {0x00,0x50, 0x00, 0x12},
- {0x01,0x00, 0x01, 0x12},
- {0x01,0x50, 0x01, 0x12},
- {0x01,0x50, 0x01, 0x12},
- {0x01,0x01, 0x00, 0x12},
- {0x01,0x20, 0x00, 0x12},
- {0x01,0x30, 0x00, 0x12},
- {0x00,0x40, 0x00, 0x12},
- {0x00,0x50, 0x00, 0x12},
- {0x01,0x00, 0x01, 0x12},
- {0x01,0x50, 0x01, 0x12},
- {0x01,0x50, 0x01, 0x12},
- {0x01,0x01, 0x00, 0x12},
- {0x01,0x20, 0x00, 0x12},
- {0x01,0x30, 0x00, 0x12},
- {0x00,0x40, 0x00, 0x12},
- {0x00,0x50, 0x00, 0x12},
- {0x01,0x00, 0x01, 0x12},
- {0x01,0x50, 0x01, 0x12},
- {0x01,0x50, 0x01, 0x12}
- };
- sbit buzzer=P3^7;
- //全局函数声明
- void system_init(void);
- void delay_ms(int ms);
- void lcd_display(char row,char* buff,char num);
- void timer_init(void);
- void key_check(void);
- void major_interface(void);
- void store_interface(void);
- void time_interface(void);
- void key_pro(void);
- void bcd_to_ascii(unsigned char* buff,unsigned char num);
- void data_pro(unsigned char*des_buff,unsigned char*src_buff,unsigned char num);
- /*
- biref 主函数
- param 无
- return 无
- */
- void main(void)
- {
- unsigned char temp[7];
- unsigned char i=0;
- system_init();
- //在24cxx中读取数据。
- for(i=0;i<32;i++)
- {
- read_24cxx(0x00+i*4,table+i,4);
- }
- while(1)
- {
- major_interface();
- store_interface();
- time_interface();
- key_check();
- key_pro();
- }
- }
- /*
- biref 系统初始化函数
- param 无
- return 无
- */
- void system_init(void)
- {
- LCD12864_Init();
- Ds1302Init(TIME);
- // Ds18b20Init();
- timer_init();
- }
- /*
- biref 延时函数
- param 延时时间,单位ms;
- return 无
- */
- void delay_ms(int ms)
- {
- int x,i;
- x=ms;
- while(x--)
- for(i=123;i;i--);
- }
- /*
- biref 12864显示函数
- param 显示缓存区
- return 无
- */
- void lcd_display(char row,char* buff,char num)
- {
- unsigned int i;
-
- switch(row)
- {
- case 0:
- {
- LCD12864_SetWindow(0, 0);
- for(i=0;i<num;i++)
- {
- LCD12864_WriteData(buff[i]);
- }
- break;
- }
- case 1:
- {
- LCD12864_SetWindow(1, 0);
- for(i=0;i<num;i++)
- {
- LCD12864_WriteData(buff[i]);
- }
- break;
- }
- case 2:
- {
- LCD12864_SetWindow(2, 0);
- for(i=0;i<num;i++)
- {
- LCD12864_WriteData(buff[i]);
- }
- break;
- }
- case 3:
- {
- LCD12864_SetWindow(3, 0);
- for(i=0;i<num;i++)
- {
- LCD12864_WriteData(buff[i]);
- }
- break;
- }
- default:
- {
- break;
- }
- }
- }
- /*
- biref BCD码转换到ASCII
- param 无
- return 无
- */
- void bcd_to_ascii(unsigned char* buff,unsigned char num)
- {
- unsigned int i;
- for(i=0;i<num;i++)
- {
- if(buff[i]>=0&&buff[i]<=9)
- buff[i]+=0x30;
- }
- }
- /*
- biref ds1302数据处理函数
- param des_buff 目标数组
- src_buff 源数组
- num 源头数组长度
- return 无
- */
- void data_pro(unsigned char* des_buff,unsigned char*src_buff,unsigned char num)
- {
- unsigned int i;
- unsigned char t;
- for(i=0;i<num;i++)
- {
- des_buff[2*i]=src_buff[i]/16;
- des_buff[2*i+1]=src_buff[i]%16;
- }
-
- for(i=0;i<num;i++)//实现数组的整体倒序
- {
- t=des_buff[i];
- des_buff[i]=des_buff[2*num-1-i];
- des_buff[2*num-1-i]=t;
- }
-
- for(i=0;i<num;i++)
- {
- t=des_buff[2*i];
- des_buff[2*i]=des_buff[2*i+1];
- des_buff[2*i+1]=t;
- }
- }
- /*
- biref 定时器0初始化
- param 无
- return 无
- */
- void timer_init(void)
- {
- TMOD|=0X01;
- TH0=(65536-50000)/0xff;
- TL0=(65536-50000)%0xff;
- ET0=1;
- EA=1;
- TR0=1;
- }
- /*
- biref 定时器0中断服务函数
- param 无
- return 无
- */
- void Timer0() interrupt 1
- {
- static unsigned char number=0;
- unsigned char i=0;
- TH0=(65536-50000)/0xff;
- TL0=(65536-50000)%0xff;
- number++;
- if(number==20)
- {
- Ds1302ReadTime();
- ds1302_receive_flag=1;
- if(TIME[0]==0x00 &&TIME[1]==0x00)
- {
- for(i=0;i<200;i++)
- {
- buzzer=~buzzer;
- delay_ms(2);
- }
- }
- for(i=0;i<32;i++)
- {
- if(!strncmp(table[0]+1+i*sizeof(table[0]),TIME,sizeof(table[0])-1)&& *(table[0]+i*sizeof(table[0]))==0x01 )
- {
- for(i=0;i<50;i++)
- {
- buzzer=~buzzer;
- delay_ms(20);
- }
- break;
- }
- }
- number=0;
- }
- }
- /*
- biref 按键检测
- param 无
- return 无
- */
- void key_check(void)
- {
- char a=0;
- GPIO_KEY=0x0f;
- key_value=0xff;
- if(GPIO_KEY!=0x0f)//读取按键是否按下
- {
- delay_ms(10);//延时10ms进行消抖
- if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
- {
- //测试列
- GPIO_KEY=0X0F;
- switch(GPIO_KEY)
- {
- case(0X07): key_value=0;break;
- case(0X0b): key_value=1;break;
- case(0X0d): key_value=2;break;
- case(0X0e): key_value=3;break;
- }
- //测试行
- GPIO_KEY=0XF0;
- switch(GPIO_KEY)
- {
- case(0X70): key_value=key_value;break;
- case(0Xb0): key_value=key_value+4;break;
- case(0Xd0): key_value=key_value+8;break;
- case(0Xe0): key_value=key_value+12;break;
- }
- while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测
- {
- delay_ms(10);
- a++;
- }
- }
- }
- }
- /*
- biref 按键处理
- param 无
- return 无
- */
- unsigned char key_num=1;
- void key_pro(void)
- {
- unsigned char i=0;
- unsigned char temp[7],t;
- switch(key_value)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- {
- if(interface_flag==1)//存储界面的按键
- {
- if(key_num%2==1)
- {
- table[store_row][sizeof(table[0])-1-store_line]=table[store_row][sizeof(table[0])-1-store_line]&0x0f|key_value<<4;
- key_num++;
- }
- else
- {
- table[store_row][sizeof(table[0])-1-store_line]=table[store_row][sizeof(table[0])-1-store_line]&0xf0|key_value;
- key_num++;
- if(store_line<=1)
- store_line++;
- else
- store_line=2;
- }
- display_flag=1;
- }
- else if(interface_flag==2)//时间更改界面的按键
- {
- if(key_num%2==1)
- {
- ds1302_buff[2*store_line]=key_value+0x30;
- key_num++;
- }
- else
- {
- ds1302_buff[2*store_line+1]=key_value+0x30;
- key_num++;
- if(store_line<=5)
- store_line++;
- else
- store_line=6;
- }
- display_flag=1;
- }
- else
- {
-
- }
- break;
- }
- case 10:
- {
- if(store_line>=1)
- store_line--;
- else
- store_line=0;
- display_flag=1;
- break;
- }
- case 11:
- {
- if(interface_flag==1)
- {
- if(store_line<=1)
- store_line++;
- else
- store_line=2;
- display_flag=1;
- }
- else if(interface_flag==2)
- {
- if(store_line<=5)
- store_line++;
- else
- store_line=6;
- display_flag=1;
- }
- else
- {
- }
- break;
- }
- case 12:
- {
- if(store_row<=30)
- store_row++;
- else
- store_row=31;
- display_flag=1;
- break;
- }
- case 13:
- {
- if(store_row>=1)
- store_row--;
- else
- store_row=0;
- display_flag=1;
- break;
- }
- case 14://界面切换按钮
- {
- if(interface_flag==0)
- {
- LCD12864_WriteCmd(0x01);
- interface_flag=1;
- store_line=0;
- store_row=0;
- display_flag=1;
- key_num=1;
- }
- else if(interface_flag==1)
- {
- for(i=0;i<32;i++)
- {
- write_24cxx(0x00+4*i,table+i,sizeof(table[0]));
- }
- LCD12864_WriteCmd(0x01);
- display_flag=1;
- interface_flag=2;
- store_line=0;
- store_row=1;
- key_num=1;
- }
- else if(interface_flag==2)
- {
- LCD12864_WriteCmd(0x01);
- for(i=0;i<sizeof(ds1302_buff)/sizeof(ds1302_buff[0]);i++)
- {
- ds1302_buff[i]-=0x30;
- }
- for(i=0;i<sizeof(ds1302_buff)/sizeof(ds1302_buff[0]);i++)
- {
- temp[i]=(ds1302_buff[2*i]<<4)+ds1302_buff[2*i+1];
- }
- for(i=0;i<sizeof(temp)/sizeof(temp[0])/2;i++)
- {
- t=temp[i];
- temp[i]=temp[sizeof(temp)-1-i];
- temp[sizeof(temp)-1-i]=t;
- }
- Ds1302Init(temp);
- display_flag=1;
- interface_flag=0;
- }
- else
- {
- while(1);
- }
- break;
- }
- case 15:
- {
- table[store_row][0]=~table[store_row][0];
- display_flag=1;
- break;
- }
- default:
- break;
- }
- }
- /*
- biref 主要界面显示
- param 无
- return 无
- */
- void major_interface(void)
- {
- if(interface_flag==0&&ds1302_receive_flag==1)
- {
- ds1302_receive_flag=0;
- LCD12864_WriteCmd(0x0c);
- Ds1302ReadTime();
- data_pro(ds1302_buff,TIME,sizeof(TIME)/sizeof(TIME[0]));
- 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);
- lcd_display(3,display_buff,8);
- bcd_to_ascii(ds1302_buff,sizeof(ds1302_buff)/sizeof(ds1302_buff[0]));
- sprintf(display_buff,"20%2.2s年%2.2s月%2.2s日",ds1302_buff,ds1302_buff+4,ds1302_buff+6);
- lcd_display(0,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
- sprintf(display_buff," 星期%2.2s ",ds1302_buff+2);
- lcd_display(1,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
- sprintf(display_buff," %2.2s时%2.2s分%2.2s秒 ",ds1302_buff+8,ds1302_buff+10,ds1302_buff+12);
- lcd_display(2,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
- }
- }
- /*
- biref 存储界面
- param 无
- return 无
- */
- void store_interface(void)
- {
- unsigned char i;
- if(interface_flag==1)
- {
- if(display_flag==1)
- {
- for(i=0;i<4;i++)
- {
- data_pro(temp,table+4*(store_row/4)+i,sizeof(table[0]));
- bcd_to_ascii(temp,sizeof(temp)/sizeof(temp[0]));
- if(temp[7]=='1')
- {
- sprintf(display_buff,"%6.2s--%2.2s--%2.2s开",temp,temp+2,temp+4);
- display_buff[0]=(store_row/4*4+i)/10+0x30;
- display_buff[1]=(store_row/4*4+i)%10+0x30;
- lcd_display(i,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
- }
- else
- {
- sprintf(display_buff,"%6.2s--%2.2s--%2.2s关",temp,temp+2,temp+4);
- display_buff[0]=(store_row/4*4+i)/10+0x30;
- display_buff[1]=(store_row/4*4+i)%10+0x30;
- lcd_display(i,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
- }
- }
- display_flag=0;
- }
- LCD12864_WriteCmd(0x0f);
- switch(store_line)
- {
- case 0:
- LCD12864_SetWindow(store_row%4,2);
- break;
- case 1:
- LCD12864_SetWindow(store_row%4,4);
- break;
- case 2:
- LCD12864_SetWindow(store_row%4,6);
- break;
- case 3:
- LCD12864_SetWindow(store_row%4,7);
- break;
- default:
- break;
- }
-
- }
- }
- /*
- biref 时间调节界面
- param 无
- return 无
- */
- void time_interface(void)
- {
- unsigned char str[]="更改时间界面";
- if(interface_flag==2)
- {
- if(display_flag==1)
- {
- lcd_display(0,str,sizeof(str));
- sprintf(display_buff,"20%2.2s年%2.2s月%2.2s日",ds1302_buff,ds1302_buff+4,ds1302_buff+6);
- lcd_display(1,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
- sprintf(display_buff," 星期%2.2s ",ds1302_buff+2);
- lcd_display(2,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
- sprintf(display_buff," %2.2s时%2.2s分%2.2s秒 ",ds1302_buff+8,ds1302_buff+10,ds1302_buff+12);
- lcd_display(3,display_buff,sizeof(display_buff)/sizeof(display_buff[0])-14);
- display_flag=0;
- }
-
- LCD12864_WriteCmd(0x0f);
- switch(store_line)
- {
- case 0:
- LCD12864_SetWindow(1,1);
- break;
- case 1:
- LCD12864_SetWindow(2,4);
- break;
- case 2:
- LCD12864_SetWindow(1,3);
- break;
- case 3:
- LCD12864_SetWindow(1,5);
- break;
- case 4:
- LCD12864_SetWindow(3,1);
- break;
- case 5:
- LCD12864_SetWindow(3,3);
- break;
- case 6:
- LCD12864_SetWindow(3,5);
- break;
- default:
- break;
- }
- }
- }
复制代码
所有资料51hei提供下载:
电子万年历.rar
(141.26 KB, 下载次数: 317)
|