DelayMS(1); state=P0;
//从P0口读LCD状态
EN = 0;DelayMS(1); return state; }
//-----------忙等待------------------// void LCD_Busy_Wait() {
while((Read_LCD_State()&0x80)==0x80); DelayMS(5); }
//-----------向LCD写数据------------------// void Write_LCD_Data(uchar dat) {
LCD_Busy_Wait(); RS=1;EN=0;RW=0;
//写数据,EN为高脉冲,
P0=dat;EN=1;DelayMS(1);EN=0; }
//-------------写LCD指令-------------------// void Write_LCD_Command(uchar cmd) {
LCD_Busy_Wait();
RS=0;EN=0; RW=0; //写指令,EN高脉冲,输出:D0~D7=数据 P0=cmd;EN=1;DelayMS(1);EN=0; }
16 / 23
//-------------LCD初始化-------------------// void Init_LCD() {
Write_LCD_Command(0x38); //设置16*2显示,5*7点阵,8位数据接口 DelayMS(1);
Write_LCD_Command(0x01); //显示清零,数据指针清零 DelayMS(1);
Write_LCD_Command(0x06); //写一个字符后地址指针自动加1 DelayMS(1);
Write_LCD_Command(0x0c); //设置开显示,不显示光标 DelayMS(1); }
//------------------------------------------ //设置液晶显示位置
//------------------------------------------ void Set_LCD_POS(uchar p){
Write_LCD_Command(p|0x80);//相当于在0x80基础上加入位置量 }
//----在LCD上显示字符串---------// void Display_LCD_String(uchar p,uchar *s) {
uchar i;
Set_LCD_POS(p); for(i=0;i<16;i++) {
Write_LCD_Data(s[i]); //在固定位置显示时间日期 DelayMS(1);
17 / 23
} }
//---------日期与时间值转换为数字字符----------------// void Format_DateTime(uchar d,uchar *a) {
a[0]=d/10+'0'; a[1]=d+'0'; }
//判断是否为闰年
uchar isLeapYear(uint y)
{ return (y%4==0&&y0!=0)||(y@0==0);} //求自2000.1.1开始的任何一天是星期几 //函数没有通过,求出总天数后再求星期几 //因为求总天数可能会超出uint的范围 void RefreshWeekDay() { uint i,d,w=5;
//已知1999.12.31是周五
for(i=2000;i<2000+DateTime[6];i++) { } d=0;
for(i=1;i d+=MonthsDays[i]; } d=isLeapYear(i)?366:365; w=(w+d)%7; d+=DateTime[3]; //保存星期,0~6表示星期日,星期一,二,...,六,为了与DS1302的星 18 / 23 期格式匹配,返回值需要加1 DateTime[5]=(w+d)%7+1; } //*****年月日时分++/--********// void DateTime_Adjust(char x) { { switch(Adjust_Index) case 6: //年00-99 if(x==1&&DateTime[6]<99) DateTime[6]++; if(x==-1&&DateTime[6]>0) DateTime[6]--; //获取2月天数 MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28; //如果年份变化后当前月份的天数大于上限则设为上限 if(DateTime[3]>MonthsDays[DateTime[4]]) { DateTime[3]=MonthsDays[DateTime[4]];} RefreshWeekDay(); //刷新星期 break; //月01-12 case 4: if(x==1&&DateTime[4]<12) DateTime[4]++; if(x==-1&&DateTime[4]>1) DateTime[4]--; MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28; if(DateTime[3]>MonthsDays[DateTime[4]]) { DateTime[3]=MonthsDays[DateTime[4]];} RefreshWeekDay(); break; //日00-28、29、30、31,调节之前首先根据年份得 19 / 23 case 3: 出该年中断二月 天数 DateTime[3]++; } } //---定时器0每秒刷新LCD显示----// void T0_INT() interrupt 1 { TH0=-50000/256; TL0=-50000%6; if(++tCount !=2) return; tCount=0; //按指定格式生成待显示的日期时间串 20 / 23 MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28; //根据当前月份决定调节日期的上限 if(x==1&&DateTime[3] if(x==-1&&DateTime[3]>0) DateTime[3]--; RefreshWeekDay(); break; //时 case 2: if(x==1&&DateTime[2]<23) DateTime[2]++; if(x==-1&&DateTime[2]>0) DateTime[2]--; break; //分 case 1: if(x==1&&DateTime[1]<59) DateTime[1]++; if(x==-1&&DateTime[1]>0) DateTime[1]--; break;