简单电子钟无时钟芯片.doc
/*液晶显示ST7920自建字库*/文件名:LCD_12864.C/日期:2012/11/9/版本:00/作者:JLM/程序参数说明:/晶振:11.0592M/功能:/*/#include <reg52.h>#define uchar unsigned char#define uint unsigned int/*定义变量*/#define LCD_data P0uchar flag_1s;ucharflag_50ms;uchar sec,min,hour,week,day,yue;uchar year_H,year_L; /定义年月日 时分秒uchar time_hour,time_min,time_sec;uchar key_counter;/模式按键按下次数uchar key_clock_counter;uchar key_mode_num_flag;/*位定义*/sbit LCD_EN=P27; /液晶使能sbit LCD_RD=P26; /RD=0为命令;RD=1为数据sbit LCD_RW=P25; /RW=0为读状态;RW=1为写状态sbit LCD_PSB=P32; /选择并行或者是串行sbit LCD_RST=P37; /液晶复位sbitKey_Mode=P14;/模式按键sbitKey_Add=P15;/加数据按键sbitKey_Sub=P16;/减数据按键sbitKey_clock=P17;/向上调试按键/sbitKey_Down=P18;/向下调试按键uchar code NUM=0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x00,0x2d;/密码数字uchar code HanZi_3=0xc1,0xfa,0xc4,0xea,0xb4,0xf3,0xbc,0xaa;/龙年大吉uchar code HanZi_4=0xc4,0xea,0xd4,0xc2,0xc8,0xd5,0xca,0xb1,0xb7,0xd6,0xc3,0xeb,0xa1,0xaa;/年月日 时分秒 -/*函数声明*/void delay_us(uint us);void delay_ms(uint ms);void TIME_PAGE0(void);void Scan_key(void);void Scan_key_add(void);void Scan_key_sub(void);void ININT_DAT(void);void TIME_0();void TIME_PAGE0(void);void TIME_PAGE1(void);void Clock_PAGE2(void);/*判忙程序*/原函数:void read_LCDbus(void)/功能:判断液晶是否在传输数据 /时间:/入口参数:/出口参数:/*/void read_LCDbus(void)LCD_data=0x00;/先清空数据LCD_RD=0;/选择命令LCD_RW=1;LCD_EN=0; /写 while(LCD_data&0x80); /判断液晶工作LCD_EN=1; /开使能delay_us(10);LCD_EN=0; /关使能;/*写指令*/原函数:void Write_Comd(uchar value)/功能:写指令/时间:/入口参数:/出口参数:/*/void Write_Comd(uchar value)read_LCDbus();/读忙标志LCD_RD=0;/选择指令LCD_RW=0;/选择写方式delay_us(10); LCD_data=value; /写入Value指令值LCD_EN=1;/使能位置一delay_us(1); LCD_EN=0;/*写数据*/原函数:void Write_LcdData(uchar D_value)/功能:写指令/时间:/入口参数:/出口参数:/*/void Write_LcdData(uchar D_value)read_LCDbus();/读忙标志LCD_RD=1;/选择数据LCD_RW=0;/选择写方式delay_us(10); LCD_data=D_value; /写入Value指令值LCD_EN=1;/使能位置一delay_us(1);LCD_EN=0;/*读RAM数据*/原函数:uchar Read_LcdData(void)/功能:写指令/时间:/入口参数:/出口参数:/*/uchar Read_LcdData()/ /*初始化LCD*/原函数:void INIT_LCD(void)/功能:写指令/时间:/入口参数:/出口参数:/*/void INIT_LCD(void)delay_ms(10);LCD_PSB=1; /选择并行口LCD_RST=0;/复位delay_us(1);LCD_RST=1;/复位开Write_Comd(0x30);/功能字控制delay_us(10);Write_Comd(0x30);delay_us(10);Write_Comd(0x02);/地址归为delay_us(10);Write_Comd(0x0C);/开显示与游标delay_us(10);Write_Comd(0x01); /清显示delay_us(100);Write_Comd(0x80);/设置DDRAM地址起始地址/*清零LCD*/原函数:void ClearLCD(void)/功能:清屏LCD/时间:/入口参数:/出口参数:/*/void ClearLCD(void)/*显示无字库汉字*/原函数:void Write_LcdHz(void)/功能:写指令/时间:/入口参数:x 数组suxcol; xaddr=显示的地址/出口参数:/*/*显示字库汉字*/原函数:/功能:/时间:/入口参数:定义形参数组uchar s,显示地址XADDR,数组指针N/出口参数:/*/*显示数字或者字符单个字节*/显示单个字符/*void WriteLcd_Displaybits(uchar s,uchar xaddr,uchar n)Write_Comd(xaddr); /输入显示地址Write_LcdData(*(s+n); /*(s+n)=sn;delay_us(10); */显示双个字符void WriteLcd_Display_2bits(uchar s,uchar xaddr,uchar n1,uchar n2)Write_Comd(xaddr); /输入显示地址Write_LcdData(*(s+n1); /*(s+n)=sn;delay_us(500);Write_LcdData(*(s+n2); /*(s+n)=sn;delay_us(500);/*显示汉字2个字节*/显示单个汉字void LCD_Display_HZ(uchar s,uchar xaddr,uchar n)uchar i; Write_Comd(xaddr); for(i=0;i<n;i+) s+; s+; Write_LcdData(*(s+); /指向数组的S Write_LcdData(*s); /指向数组的S+1delay_us(500); /显示单个汉字 /*void LCD_DisplayHanZi(uchar s,uchar xaddr,uchar n1)uchar i; Write_Comd(xaddr); for(i=0;i<n1;i+) Write_LcdData(*(s+); /指向数组的SWrite_LcdData(*(s+); /指向数组S */*按键模式扫描*/原函数:void Scan_key_mode(void)/功能:按键模式扫描/时间:/入口参数:Key_Mode=P11;/出口参数:/*/void Scan_key(void)if(Key_Mode=0) /模式按键扫描 delay_us(2500);while(!Key_Mode);delay_us(2500);TR0=0;key_counter+;TIME_PAGE0();/调用调整时间界while(1)if(Key_Mode=0)delay_us(2500); while(!Key_Mode);delay_us(2500);key_counter+;TIME_PAGE0();/调用调整时间界switch(key_counter)case 1:WriteLcd_Display_2bits(NUM,0x91,year_H/10,year_H%10);/20Write_Comd(0x10); /光标返回delay_ms(100);Scan_key_add();Scan_key_sub();break;case 2:WriteLcd_Display_2bits(NUM,0x92,year_L/10,year_L%10);/20Write_Comd(0x10);delay_ms(100);Scan_key_add();Scan_key_sub();break;case 3:WriteLcd_Display_2bits(NUM,0x94,yue/10,yue%10);/12Write_Comd(0x10);delay_ms(100);Scan_key_add();Scan_key_sub();break;/月份case 4:WriteLcd_Display_2bits(NUM,0x96,day/10,day%10);/12Write_Comd(0x10);delay_ms(100);Scan_key_add();Scan_key_sub();break;/日case 5:WriteLcd_Display_2bits(NUM,0x89,hour/10,hour%10);/12Write_Comd(0x10);delay_ms(100);Scan_key_add();Scan_key_sub();break;/时case 6:WriteLcd_Display_2bits(NUM,0x8b,min/10,min%10);/12Write_Comd(0x10);delay_ms(100);Scan_key_add();Scan_key_sub();break;/分case 7:WriteLcd_Display_2bits(NUM,0x8d,sec/10,sec%10);/12Write_Comd(0x10);delay_ms(100);Scan_key_add();Scan_key_sub();break;/秒case 8:key_counter=0;Write_Comd(0x0c);/关闭游标显示反白Write_Comd(0x01); /清LCD显示TR0=1;/启动定时器 break; if(key_counter=0)Write_Comd(0x0c);/关闭游标显示反白Write_Comd(0x01);/清LCDflag_1s=0;break;flag_1s=0; /*加按键扫描*/原函数:void Scan_key_add(void)/功能:加按键扫描/时间:/入口参数:Key_Add=P1.4/出口参数:/*/void Scan_key_add(void) if(Key_Add=0)delay_us(1500);while(!Key_Add);delay_us(1500);if(key_counter=1)/判断是不是年修改year_H+;if(year_H=99)year_H=0;if(key_counter=2)/判断是不是年修改year_L+;if(year_L=99)year_L=0;if(key_counter=3)/判断是不是月修改yue+;if(yue=13)yue=0;if(key_counter=4)/判断是不是日修改day+;if(day=32)day=1;if(key_counter=5)/判断是不是时修改hour+;if(hour=25)hour=0;if(key_counter=6)/判断是不是分修改min+;if(min=60)min=0;if(key_counter=7)/判断是不是秒修改sec+;if(sec=60)sec=0; /*减按键扫描*/原函数:void Scan_key_sub(void)/功能:减按键扫描/时间:/入口参数:/出口参数:/*/void Scan_key_sub(void) if(Key_Sub=0)delay_us(2500);while(!Key_Sub);if(key_counter=1)/判断是不是年修改if(year_H>0)year_H-;if(year_H=0)year_H=99;if(key_counter=2)/判断是不是年修改if(year_L>0)year_L-;if(year_L=0)year_L=99;if(key_counter=3)/判断是不是月修改if(yue>0)yue-;if(yue=0)yue=12;if(key_counter=4)/判断是不是日修改if(day>0)day-; if(day=0) day=31;if(key_counter=5)/判断是不是时修改if(hour>0)hour-;if(hour=0)hour=24;if(key_counter=6)/判断是不是分修改if(min>0)min-;if(min=0)min=59;if(key_counter=7)/判断是不是秒修改if(sec>0)sec-;if(sec=0)sec=59; /*初始时钟页面*/原函数:void TIME_PAGE0(void)/功能:时钟显示页/时间:/入口参数:/出口参数:/*/void TIME_PAGE()Write_Comd(0x01); /清LCD显示delay_us(100);LCD_Display_HZ(HanZi_3,0x82,0);/龙LCD_Display_HZ(HanZi_3,0x83,1);/年LCD_Display_HZ(HanZi_3,0x84,2);/大LCD_Display_HZ(HanZi_3,0x85,3);/吉Write_Comd(0x01); /清LCD显示Write_Comd(0x0c); /关闭游标显示反白delay_us(100);/*可调时钟页面*/原函数:void TIME_PAGE0(void)/功能:时钟显示页/时间:/入口参数:/出口参数:/*/void TIME_PAGE0(void)Write_Comd(0x01); /清LCD显示delay_us(100);WriteLcd_Display_2bits(NUM,0x91,year_H/10,year_H%10);/20WriteLcd_Display_2bits(NUM,0x92,year_L/10,year_L%10);/20 WriteLcd_Display_2bits(NUM,0x93,11,11);/-WriteLcd_Display_2bits(NUM,0x94,yue/10,yue%10);/12 WriteLcd_Display_2bits(NUM,0x95,11,11);/-WriteLcd_Display_2bits(NUM,0x96,day/10,day%10);/12WriteLcd_Display_2bits(NUM,0x89,hour/10,hour%10);/12LCD_Display_HZ(HanZi_4,0x8a,3);/时WriteLcd_Display_2bits(NUM,0x8b,min/10,min%10);/00LCD_Display_HZ(HanZi_4,0x8c,4);/分WriteLcd_Display_2bits(NUM,0x8d,sec/10,sec%10);/00LCD_Display_HZ(HanZi_4,0x8e,5);/秒Write_Comd(0x0f);/游标显示Write_Comd(0x80);/ /*时钟显示页面*/原函数:void TIME_PAGE1(void)/功能:时钟显示页/时间:/入口参数:/出口参数:/*/void TIME_PAGE1(void)LCD_Display_HZ(HanZi_3,0x9a,0);/龙LCD_Display_HZ(HanZi_3,0x9b,1);/年LCD_Display_HZ(HanZi_3,0x9c,2);/大LCD_Display_HZ(HanZi_3,0x9d,3);/吉WriteLcd_Display_2bits(NUM,0x91,year_H/10,year_H%10);/20WriteLcd_Display_2bits(NUM,0x92,year_L/10,year_L%10);/20 WriteLcd_Display_2bits(NUM,0x93,11,11);/-WriteLcd_Display_2bits(NUM,0x94,yue/10,yue%10);/12 WriteLcd_Display_2bits(NUM,0x95,11,11);/-WriteLcd_Display_2bits(NUM,0x96,day/10,day%10);/12WriteLcd_Display_2bits(NUM,0x89,hour/10,hour%10);/12LCD_Display_HZ(HanZi_4,0x8a,3);/时WriteLcd_Display_2bits(NUM,0x8b,min/10,min%10);/00LCD_Display_HZ(HanZi_4,0x8c,4);/分WriteLcd_Display_2bits(NUM,0x8d,sec/10,sec%10);/00LCD_Display_HZ(HanZi_4,0x8e,5);/秒Write_Comd(0x0c);/关闭游标显示反白 delay_us(10); /*闹钟调整页面*/原函数:void Clock_PAGE2(void)/功能:时钟显示页/时间:/入口参数:/出口参数:/*/void Clock_PAGE2(void)Write_Comd(0x01); /清LCD显示delay_us(100);WriteLcd_Display_2bits(NUM,0x89,hour/10,hour%10);/12LCD_Display_HZ(HanZi_4,0x8a,3);/时WriteLcd_Display_2bits(NUM,0x8b,min/10,min%10);/00LCD_Display_HZ(HanZi_4,0x8c,4);/分WriteLcd_Display_2bits(NUM,0x8d,sec/10,sec%10);/00LCD_Display_HZ(HanZi_4,0x8e,5);/秒Write_Comd(0x0f);/游标显示Write_Comd(0x80);/*时间程序*/原函数:void Auto_time(void)/功能:时间自动调整/时间:/入口参数:/出口参数:/*/void Auto_time(void)if(flag_1s)flag_1s=0;sec+;if(sec>59)sec=0;min+;if(min>59)min=0;hour+;if(hour>23)hour=0;week+;if(week=7)week=1;day+;/2013年有7个月为31天=1.3.5.7.8.10.12if(yue=1|yue=3|yue=5|yue=7|yue=8|yue=10|yue=12)&&(day=31)yue+; /月份加一判断是否为大月或者为小月day=1;/如果其中一个月到,并且天数达到31天就返回重新开始计数/4个月是30天=4,6,9,11else if(yue=4|yue=6|yue=9|yue=11)&&(day=30)yue+;day=1;/1个月是28天=2else if(yue=2)&&(day=28)yue+;day=1;/判断年数if(yue=12) /等于12个月了就重新开始从第一个月开始yue=1;year_L+;if(year_L=99)year_L=12;year_H+;if(year_H=99)year_H=20; /*定时闹钟程序*/原函数:void time_clock(void)/功能:闹钟程序/时间:/入口参数:/出口参数:/*/void time_clock(void)if(Key_clock=0)delay_us(2500);while(!Key_clock);delay_us(2500);key_clock_counter+;Clock_PAGE2();while(1)if(Key_clock=0)delay_us(2500);while(!Key_clock);delay_us(2500);Clock_PAGE2();switch(key_clock_counter)case 1: WriteLcd_Display_2bits(NUM,0x89,time_hour/10,time_hour%10);/12Write_Comd(0x10);delay_ms(100);Scan_key_add();Scan_key_sub(); break;case 2:WriteLcd_Display_2bits(NUM,0x8b,time_min/10,time_min%10);/12Write_Comd(0x10);delay_ms(100);Scan_key_add();Scan_key_sub();break;case 3:WriteLcd_Display_2bits(NUM,0x8d,time_sec/10,time_sec%10);/12Write_Comd(0x10);delay_ms(100);Scan_key_add();Scan_key_sub();break;/秒case 4:key_clock_counter=0;Write_Comd(0x0c);/关闭游标显示反白Write_Comd(0x01); /清LCD显示/TR0=1;/启动定时器 break;if(key_clock_counter=0)Write_Comd(0x0c);/关闭游标显示反白Write_Comd(0x01);/清LCDflag_1s=0;