|
- /*****************************************************************
- 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]//讀數(shù)據(jù)寄存器
- #define LCD_WD XBYTE[0x1d00]//寫數(shù)據(jù)寄存器
- /********************************************************************/
- #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工作狀態(tài)函數(shù)
- void LCD_en_dat(unsigned char temp);//寫數(shù)據(jù)函數(shù)
- void LCD_set_xy( unsigned char x, unsigned char y );//設置LCD顯示地址函數(shù)
- void LCD_write_char( unsigned x,unsigned char y,unsigned char dat);//寫字符函數(shù)
- void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s);//寫字符串函數(shù)
- void LCD_init(void);//初如化LCD函數(shù)
- void WaitIdle(void);//檢測LCD忙則等待函數(shù)
- /*****************************************************************************/
- void Read_calendar(void);//讀取系統(tǒng)時間
- void Start_calendar(void);//啟動時鐘
- void Display_calendar(void);//顯示時間
- void Set_calendar(void);//設置系統(tǒng)時間
- /*****************************************************************************/
- void delayms(unsigned char i);//延時程序
- bit scan_key(void);//按鍵掃描,讀取按鍵狀態(tài)到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)//寫命令函數(shù)
- {
- WaitIdle();
- LCD_WL=command;
- }
-
- void LCD_en_dat(unsigned char dat)//寫數(shù)據(jù)函數(shù)
- {
- WaitIdle();
- LCD_WD=dat;
- }
-
- void LCD_set_xy( unsigned char x, unsigned char y ) //設置地址函數(shù)
- {
- 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)//寫字符函數(shù)
- {
- LCD_set_xy( x, y );
- LCD_en_dat(dat);
- }
-
- void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)//寫字符串函數(shù)
- {
- LCD_set_xy( X, Y ); //寫地址
- while (*s) // 寫顯示字符
- {
- LCD_en_dat(*s);
- s ++;
- }
- }
-
- void LCD_init(void)//初始化子函數(shù)
- {
- CLEARSCREEN;//清屏
- LCD_en_command(0x38);//設置8位串數(shù)據(jù)格式
- 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) //設置系統(tǒng)時間
- {
- 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) //讀取系統(tǒng)時間
- {
- 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()) //調(diào)用按鍵掃描,讀取按鍵的狀態(tài),如果有按鍵變化,則delay 10ms去抖動
- { delayms(10) ;//去抖動
- if(scan_key())//再掃描,如果仍然有鍵,才進入按鍵處理
- {key_v = key_s ;//保存按鍵狀態(tài)
- proc_key() ;//按鍵處理
- }
- }
- }
-
- bit key(void)//返回是否按下鍵
- {
- if(scan_key()) //調(diào)用按鍵掃描,讀取按鍵的狀態(tài),如果有按鍵變化,則delay 10ms去抖動
- { delayms(10) ;//去抖動
- if(scan_key())//再掃描,如果仍然有鍵,才進入按鍵處理
- {key_v = key_s ;//保存按鍵狀態(tài)
- return 1;//確定有鍵按下返回1
- }
- }
- }
-
- bit scan_key(void)//按鍵掃描,讀取按鍵狀態(tài)到key_s
- {
- key_s =(~P1)&0x1F;
- return(key_s ^ key_v) ; //如果新舊狀態(tài)不一樣,則返回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;
- }
復制代碼
|
|