|
- /*****************************************************************
- 20*4LCD液晶屏与DS12c887时钟芯片电子钟v1.10
- *****************************************************************/
- #include <REG52.H>
- #include <INTRINS.H>
- #include <ABSACC.H>
- /*****************定义LCD寄存器***************************************/
- #define LCD_RL XBYTE[0x1e00]//读指令寄存器
- #define LCD_WL XBYTE[0x1c00]//写指令寄存器
- #define LCD_RD XBYTE[0x1f00]//读数据寄存器
- #define LCD_WD XBYTE[0x1d00]//写数据寄存器
- /********************************************************************/
- #define LINE1 1
- #define LINE2 2
- #define LINE3 3
- #define LINE4 4
- #define CLEARSCREEN LCD_en_command(0x01)//清屏
- /*******************************************************************/
- #define REG_A XBYTE[0x800a]//DS12887A寄存器A
- #define REG_B XBYTE[0x800b]//DS12887A寄存器B
- unsigned char code at[8]={9,8,7,6,4,2,0,50};// 年、月、日、星期、时、分、秒、世纪
- unsigned char xdata *calendar_address=0x8000;//DS12887片选
- unsigned char calendar_time[8];
- unsigned char key_s,key_v=0,sect1,sect2;
- /*******************************************************************/
-
- void LCD_en_command(unsigned char command);//设置LCD工作状态函数
- void LCD_en_dat(unsigned char temp);//写数据函数
- void LCD_set_xy( unsigned char x, unsigned char y );//设置LCD显示地址函数
- void LCD_write_char( unsigned x,unsigned char y,unsigned char dat);//写字符函数
- void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s);//写字符串函数
- void LCD_init(void);//初如化LCD函数
- void WaitIdle(void);//检测LCD忙则等待函数
- /*****************************************************************************/
- void Read_calendar(void);//读取系统时间
- void Start_calendar(void);//启动时钟
- void Display_calendar(void);//显示时间
- void Set_calendar(void);//设置系统时间
- /*****************************************************************************/
- void delayms(unsigned char i);//延时程序
- bit scan_key(void);//按键扫描,读取按键状态到key_s
- void proc_key(void);//按键主程序
- void scan_main_key(void);//按键判断
- bit key(void);//返回是否按下键
- void set_date();//修改时间日期
- /******************************************************************************/
- void start_stopt2(bit x);//启动停止定时器2
- /******************************************************************************/
- void main(void)
- {
- LCD_init();
- Start_calendar();
- while(1)
- {
- Read_calendar();
- Display_calendar();
- scan_main_key();
- }
- }
-
- /*********************************************************************/
- void LCD_en_command(unsigned char command)//写命令函数
- {
- WaitIdle();
- LCD_WL=command;
- }
-
- void LCD_en_dat(unsigned char dat)//写数据函数
- {
- WaitIdle();
- LCD_WD=dat;
- }
-
- void LCD_set_xy( unsigned char x, unsigned char y ) //设置地址函数
- {
- unsigned char address;
- switch(y){
- case 1:
- address = 0x80 + x;break;
- case 2:
- address = 0xc0 + x;break;
- case 3:
- address = 0x94 + x;break;
- case 4:
- address = 0xd4 + x;break;
- }
- LCD_en_command(address);
-
- }
-
- void LCD_write_char( unsigned x,unsigned char y,unsigned char dat)//写字符函数
- {
- LCD_set_xy( x, y );
- LCD_en_dat(dat);
- }
-
- void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)//写字符串函数
- {
- LCD_set_xy( X, Y ); //写地址
- while (*s) // 写显示字符
- {
- LCD_en_dat(*s);
- s ++;
- }
- }
-
- void LCD_init(void)//初始化子函数
- {
- CLEARSCREEN;//清屏
- LCD_en_command(0x38);//设置8位串数据格式
- LCD_en_command(0x0c);//开显示器
- CLEARSCREEN;//清屏
- }
-
- void WaitIdle(void)//检测LCD忙则等待
- {
- unsigned char tmp;
- _nop_();
- while(1)
- { tmp=LCD_RL;
- tmp&=0x80;
- if(tmp==0)
- break;
- }
- }
- /**************************************************************/
- void Display_calendar(void)//显示时间
- {LCD_write_string(0x04,LINE1,"GZJWD_SG_JKS");
- LCD_write_char(0x05,LINE2,(calendar_time[7]/10)|0x30);//世纪十位
- LCD_write_char(0x06,LINE2,(calendar_time[7]%10)|0x30);//世纪个位
- LCD_write_char(0x07,LINE2,(calendar_time[0]/10)|0x30);//年十位
- LCD_write_char(0x08,LINE2,(calendar_time[0]%10)|0x30);//年个位
- LCD_write_string(0x09,LINE2,"/");
- LCD_write_char(0x0a,LINE2,(calendar_time[1]/10)|0x30);//月十位
- LCD_write_char(0x0b,LINE2,(calendar_time[1]%10)|0x30);//月个位
- LCD_write_string(0x0c,LINE2,"/");
- LCD_write_char(0x0d,LINE2,(calendar_time[2]/10)|0x30);//日十位
- LCD_write_char(0x0e,LINE2,(calendar_time[2]%10)|0x30);//日个位
- if(calendar_time[3]==1)
- {
- LCD_write_string(0x07,LINE3,"Mon_");
- LCD_write_char(0x0b,LINE3,(calendar_time[3]%10)|0x30);//星期
- }
- if(calendar_time[3]==2)
- {
- LCD_write_string(0x07,LINE3,"Tue_");
- LCD_write_char(0x0b,LINE3,(calendar_time[3]%10)|0x30);//星期
- }
- if(calendar_time[3]==3)
- {
- LCD_write_string(0x07,LINE3,"Wen_");
- LCD_write_char(0x0b,LINE3,(calendar_time[3]%10)|0x30);//星期
- }
- if(calendar_time[3]==4)
- {
- LCD_write_string(0x07,LINE3,"Thu_");
- LCD_write_char(0x0b,LINE3,(calendar_time[3]%10)|0x30);//星期
- }
- if(calendar_time[3]==5)
- {
- LCD_write_string(0x07,LINE3,"Fri_");
- LCD_write_char(0x0b,LINE3,(calendar_time[3]%10)|0x30);//星期
- }
- if(calendar_time[3]==6)
- {
- LCD_write_string(0x07,LINE3,"Sat_");
- LCD_write_char(0x0b,LINE3,(calendar_time[3]%10)|0x30);//星期
- }
- if(calendar_time[3]==7)
- {
- LCD_write_string(0x07,LINE3,"Sun_");
- LCD_write_char(0x0b,LINE3,(calendar_time[3]%10)|0x30);//星期
- }
- LCD_write_char(0x06,LINE4,(calendar_time[4]/10)|0x30);//小时十位
- LCD_write_char(0x07,LINE4,(calendar_time[4]%10)|0x30);//小时个位
- LCD_write_string(0x08,LINE4,":");
- LCD_write_char(0x09,LINE4,(calendar_time[5]/10)|0x30);//分钟十位
- LCD_write_char(0x0a,LINE4,(calendar_time[5]%10)|0x30);//分钟个位
- LCD_write_string(0x0b,LINE4,":");
- LCD_write_char(0x0c,LINE4,(calendar_time[6]/10)|0x30);//秒十位
- LCD_write_char(0x0d,LINE4,(calendar_time[6]%10)|0x30);//秒个位
- }
-
- void Set_calendar(void) //设置系统时间
- {
- unsigned char i;
- REG_B=0x80;
- for(i=0;i<8;i++)
- *(calendar_address+at[i])=calendar_time[i];
- Start_calendar();
- }
-
- void Start_calendar(void) //启动时钟
- {
- REG_A=0x20;//晶体振荡器开启并保存时钟运行
- REG_B=0x06;//24小时制,hex输出
- }
-
- void Read_calendar(void) //读取系统时间
- {
- unsigned char temp,i;
- REG_B=0x06;//24小时制,hex输出
- do{ temp=REG_A;}
- while(temp&0x80);
- for(i=0;i<8;i++)
- calendar_time[i]=*(calendar_address+at[i]);
- }
-
- void set_int12887(void)//初始化时钟
- {
- unsigned char i;
- unsigned char calendar[]={06,12,19,2,16,30,30,20};
- for(i=0;i<8;i++)
- calendar_time[i]=calendar[i];
- Set_calendar();
- }
- /*************************************************************************/
- void scan_main_key(void)//按键判断
- {
- if(scan_key()) //调用按键扫描,读取按键的状态,如果有按键变化,则delay 10ms去抖动
- { delayms(10) ;//去抖动
- if(scan_key())//再扫描,如果仍然有键,才进入按键处理
- {key_v = key_s ;//保存按键状态
- proc_key() ;//按键处理
- }
- }
- }
-
- bit key(void)//返回是否按下键
- {
- if(scan_key()) //调用按键扫描,读取按键的状态,如果有按键变化,则delay 10ms去抖动
- { delayms(10) ;//去抖动
- if(scan_key())//再扫描,如果仍然有键,才进入按键处理
- {key_v = key_s ;//保存按键状态
- return 1;//确定有键按下返回1
- }
- }
- }
-
- bit scan_key(void)//按键扫描,读取按键状态到key_s
- {
- key_s =(~P1)&0x1F;
- return(key_s ^ key_v) ; //如果新旧状态不一样,则返回1,表示有按键变化。否则返回0
- }
-
- void proc_key(void)//按键主程序
- {
- switch(key_v)
- {
- case 0x01:// ok键
- set_date();
- break;
- case 0x02:// <-键
- break;
- case 0x04:// ->键
- break;
- case 0x08:// + 键
- break;
- case 0x10:// - 键
- break;
- case 0x18:
- set_int12887();
- break;
- default:
- break;
- }
- }
-
- void delayms(unsigned char i)//延时程序
- {
- unsigned char j;
- for(;i>0;i--)
- for(j=0;j++;j<250);
- }
-
- void set_date(void)
- {unsigned char address[]={0xc8,0xcb,0xce,0x9f,0xdb,0xde,0xe1};
- unsigned char i=4;
- while(1)
- {
- LCD_en_command(address[i]); //写地址
- LCD_en_command(0x0f);//开显示器,光标闪烁
- if(key())
- {if(key_v==0x08) //按下+键
- calendar_time[i]++;
- if(key_v==0x10) //按下-键
- calendar_time[i]--;
-
- if(calendar_time[0]==100)
- {calendar_time[0]=0;calendar_time[7]++;}
- if(calendar_time[0]==255)
- {calendar_time[0]=99;calendar_time[7]--;}
- if(calendar_time[1]==13)
- calendar_time[1]=1;
- if(calendar_time[1]==0)
- calendar_time[1]=12;
- if(calendar_time[2]==32)
- calendar_time[2]=1;
- if(calendar_time[2]==0)
- calendar_time[2]=31;
- if(calendar_time[4]==24)
- calendar_time[4]=0;
- if(calendar_time[4]==255)
- calendar_time[4]=23;
- if(calendar_time[5]==60)
- calendar_time[5]=0;
- if(calendar_time[5]==255)
- calendar_time[5]=59;
- if(calendar_time[6]==60)
- calendar_time[6]=0;
- if(calendar_time[6]==255)
- calendar_time[6]=59;
- if(calendar_time[3]==8)
- calendar_time[3]=1;
- if(calendar_time[3]==0)
- calendar_time[3]=7;
-
- if(key_v==0x04)//按下->键
- i++;
- if(key_v==0x02)//按下<-键
- i--;
- if(i==255)i=6;
- if(i==7)i=0;
- if(key_v==0x01)//按下确认键
- {Set_calendar();//设置日期
- LCD_en_command(0x0c);//开显示器,取消光标闪烁
- break;
- }
- Display_calendar();//显示时间
- }
- }
- }
-
- /**************************************************************************************/
- timer2() interrupt 5//溢出一次50ms
- {
- static unsigned char t;
- TF2=0;//清溢出标志
- t++;
- if(t==20)//20约一秒
- {t=0;sect1++;}
- }
- void start_stopt2(bit x)//启动停止定时器2
- {
- RCAP2H=0x50;
- RCAP2L=0x00;
- TR2=x;
- ET2=x;
- EA=x;
- }
复制代码
|
|