|
最近花了近一個(gè)星期做了個(gè)時(shí)鐘,又花了近半月寫(xiě)了個(gè)程序代碼,但還不是很完美,等待再一次升級(jí)。MCU采用AT89S52,clock采用DS12887,LCD12864自定義大數(shù)字顯示字符,溫度傳感器DS18B20,無(wú)農(nóng)歷顯示。完整程序代碼如下:
- #include<reg52.h>
- #include<intrins.h> //庫(kù)文件,_nop_指令用
- #define uint unsigned int
- #define uchar unsigned char
- #define lcddata P0 //宏定義lcddata為P0口數(shù)據(jù)
- sbit busy=P0^7;
- sbit rs=P2^7; //定義數(shù)據(jù),命令端
- sbit rw=P2^6; //定義讀寫(xiě)端
- sbit en=P2^5; //定義使能端
- sbit scl=P2^2;
- sbit sda=P2^1;
- sbit dscs=P2^0; //DS12887
- sbit dsas=P2^1;
- sbit dsrw=P2^2;
- sbit dsds=P2^3;
- sbit dq=P3^1;
- sbit set=P3^2;
- sbit jia=P3^3;
- sbit jian=P3^4;
- sbit enter=P3^5;
- uchar miao,fen,shi,nian,yue,ri,week,bw,sw,gw,xiao,num1,m1,f1,s1;
- uchar a1,a2,a3,a4,baiw,shiw,gew;
- bit bdata flag,flag1,flag2;
- uchar code tab0[]=//自定義數(shù)字0
- {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x0F,0xF0,0x1F,0xF0,0x3F,0xF8,0x3E,0xF8,
- 0x3E,0x7C,0x3C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7E,0x7C,0x3E,0x7C,0x3E,
- 0x7C,0x3E,0x7C,0x3E,0x7C,0x3E,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x3C,0x7C,
- 0x3E,0x7C,0x3E,0xF8,0x1F,0xF8,0x0F,0xF0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,};
- uchar code tab1[]=//自定義數(shù)字1
- {0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xF0,0x03,0xF0,0x07,0xF0,0x0F,0xF0,0x1F,0xF0,
- 0x1F,0xF0,0x1F,0xF0,0x1D,0xF0,0x19,0xF0,0x01,0xF0,0x01,0xF0,0x01,0xF0,0x01,0xF0,
- 0x01,0xF0,0x01,0xF0,0x01,0xF0,0x01,0xF0,0x01,0xF0,0x01,0xF0,0x01,0xF0,0x01,0xF0,
- 0x01,0xF0,0x01,0xF0,0x01,0xF0,0x01,0xF0,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,};
- uchar code tab2[]=//自定義數(shù)字2
- {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF0,0x1F,0xF8,0x3F,0xFC,0x3F,0xFE,0x7E,0x7E,
- 0x7E,0x3E,0x7C,0x3E,0x00,0x3E,0x00,0x3E,0x00,0x7E,0x00,0x7E,0x00,0xFC,0x01,0xFC,
- 0x01,0xF8,0x03,0xF0,0x07,0xF0,0x0F,0xE0,0x1F,0xC0,0x1F,0x80,0x3F,0x00,0x7E,0x00,
- 0x7C,0x00,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,};
- uchar code tab3[]=//自定義數(shù)字3
- {0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x1F,0xF8,0x3F,0xFC,0x3F,0xFC,0x7E,0x7E,
- 0x7C,0x3E,0x7C,0x3E,0x00,0x3E,0x00,0x3E,0x00,0x7C,0x00,0xFC,0x07,0xF8,0x07,0xF0,
- 0x07,0xF8,0x07,0xFC,0x00,0xFC,0x00,0x7E,0x00,0x3E,0x00,0x3E,0x7C,0x3E,0x7C,0x3E,
- 0x7E,0x7E,0x7E,0xFC,0x3F,0xFC,0x3F,0xF8,0x0F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,};
- uchar code tab4[]=//自定義數(shù)字4
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0xF0,0x01,0xF0,0x03,0xF0,0x03,0xF0,
- 0x07,0xF0,0x07,0xF0,0x0F,0xF0,0x0F,0xF0,0x1F,0xF0,0x1E,0xF0,0x3E,0xF0,0x3C,0xF0,
- 0x7C,0xF0,0x78,0xF0,0xF8,0xF0,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0x00,0xF0,
- 0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,};
- uchar code tab5[]=//自定義數(shù)字5
- {0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7C,0x00,
- 0x7C,0x00,0x7C,0x00,0x7C,0x00,0x7C,0x00,0x7F,0xF0,0x7F,0xF8,0x7F,0xFC,0x7F,0xFE,
- 0x7E,0x7E,0x7C,0x3E,0x3C,0x3E,0x00,0x3E,0x00,0x3E,0x00,0x3E,0x00,0x3E,0x7C,0x3E,
- 0x7E,0x7E,0x7E,0xFC,0x3F,0xFC,0x1F,0xF8,0x0F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,};
- uchar code tab6[]=//自定義數(shù)字6
- {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x0F,0xF8,0x1F,0xFC,0x1F,0xFC,0x3E,0x7C,
- 0x3E,0x7C,0x3C,0x3C,0x7C,0x00,0x7C,0x00,0x7D,0xC0,0x7F,0xF0,0x7F,0xF8,0x7F,0xFC,
- 0x7E,0xFC,0x7E,0x7E,0x7C,0x3E,0x7C,0x3E,0x7C,0x3E,0x7C,0x3E,0x7C,0x3E,0x7C,0x3E,
- 0x3E,0x7C,0x3E,0xFC,0x3F,0xF8,0x1F,0xF8,0x0F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,};
- uchar code tab7[]=//自定義數(shù)字7
- {0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,
- 0x00,0x7C,0x00,0xF8,0x00,0xF8,0x00,0xF8,0x00,0xF0,0x01,0xF0,0x01,0xF0,0x01,0xF0,
- 0x01,0xE0,0x03,0xE0,0x03,0xE0,0x03,0xE0,0x07,0xC0,0x07,0xC0,0x07,0xC0,0x07,0x80,
- 0x0F,0x80,0x0F,0x80,0x0F,0x80,0x0F,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
- uchar code tab8[]=//自定義數(shù)字8
- {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x1F,0xF8,0x3F,0xF8,0x3F,0xFC,0x7C,0x7C,
- 0x7C,0x3C,0x7C,0x3E,0x7C,0x3C,0x7C,0x3C,0x3C,0x7C,0x3F,0xF8,0x1F,0xF8,0x0F,0xE0,
- 0x1F,0xF8,0x3F,0xFC,0x7E,0x7C,0x7C,0x7C,0x7C,0x3E,0x7C,0x3E,0x7C,0x3E,0x7C,0x3E,
- 0x7C,0x7C,0x7E,0xFC,0x3F,0xF8,0x1F,0xF8,0x0F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,};
- uchar code tab9[]=//自定義數(shù)字9
- {0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x1F,0xF0,0x3F,0xF8,0x3F,0xF8,0x7C,0x7C,
- 0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7F,0xFC,
- 0x3F,0xFC,0x3F,0xFC,0x0F,0xFC,0x00,0x7C,0x00,0x7C,0x00,0x7C,0x00,0x7C,0x7C,0x7C,
- 0x7C,0x78,0x7E,0xF8,0x3F,0xF8,0x3F,0xF0,0x1F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,};
- uchar code tab10[]=//自定義攝氏度圖標(biāo)圖標(biāo)
- {0x00,0x00,0x00,0x30,0x00,0x48,0x00,0x58,0x00,0x48,0x00,0x58,0x00,0x48,0x00,0x58,
- 0x00,0x48,0x00,0xFC,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x00,0xFC,0x00,0x78,};
- uchar code tab11[]=//自定義攝氏度
- {0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x3E,0x12,0x60,0x12,0xC0,0x0C,0xC0,0x00,0xC0,
- 0x00,0xC0,0x00,0xC0,0x00,0x60,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- uchar code tabm[]=//自定義:號(hào)
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x0F,0xC0,
- 0x1F,0xE0,0x1F,0xE0,0x1F,0xE0,0x1F,0xE0,0x0F,0xC0,0x07,0x80,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x07,0x80,0x0F,0xC0,0x1F,0xE0,0x1F,0xE0,0x1F,0xE0,0x1F,0xE0,
- 0x0F,0xC0,0x07,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
- void delay(uint aa)//延時(shí)
- {
- uchar bb;
- while(aa--)
- {
- for(bb=0;bb<115;bb++) //1ms基準(zhǔn)延時(shí)程序
- {;}
- }
- }
- void dsdelay(uint t) //1us基準(zhǔn)延時(shí)程序
- {
- for (;t>0;t--);
- }
- void lcd_busy(void)//查忙子程序
- {
- busy=1; //把忙標(biāo)志位置1
- en=0; //把使能端置0
- rs=0; //把rs端置0,為指令操作
- rw=1; //為讀操作
- en=1; //拉高使能端
- _nop_(); //等待
- while(busy==1); //檢測(cè)忙標(biāo)志位,
- en=0; //忙標(biāo)志位為0,則把使能拉低
- }
- void lcd_addr(addr)//寫(xiě)入地址及命令
- {
- lcd_busy(); //忙標(biāo)志檢測(cè)
- rs=0; //指令操作
- rw=0; //寫(xiě)入操作
- en=1; //拉高使能端
- lcddata=addr; //放上數(shù)據(jù)
- _nop_(); //等待
- en=0; //拉低使能端,數(shù)據(jù)寫(xiě)入液晶
- }
- void lcd_data(dat)//寫(xiě)入要顯示的數(shù)據(jù)
- {
- lcd_busy(); //忙標(biāo)志檢測(cè)
- rs=1; //數(shù)據(jù)操作
- rw=0; //寫(xiě)入操作
- en=1; //拉高使能端
- lcddata=dat; //放上數(shù)據(jù)
- _nop_(); //等待
- en=0; //拉低使能端,數(shù)據(jù)寫(xiě)入液晶
- }
- void lcd_init(void)//LCD初始化
- {
- lcd_addr(0x30); //基本指令集
- delay(1);
- lcd_addr(0x01); //清屏,地址指針指向00H
- delay(20); //等待>10ms
- lcd_addr(0x06); //光標(biāo)右移,整體不移
- delay(1);
- lcd_addr(0x0c); //開(kāi)顯示,關(guān)游標(biāo),關(guān)游標(biāo)位置
- delay(1);
- }
- void lcd_clear()//清除GDROM,否則花屏
- {
- uchar a,b,c;
- lcd_addr(0x34);//擴(kuò)充指令集
- for(a=0;a<2;a++)//分上下兩屏寫(xiě)入
- {
- for(b=0;b<32;b++)//每半屏32行
- {
- lcd_addr(0x80+b);//寫(xiě)y坐標(biāo)
- if(a==0) //寫(xiě)x坐標(biāo)
- lcd_addr(0x80); //上半屏
- else
- lcd_addr(0x88);//下半屏
- for(c=0;c<16;c++)//一整行
- lcd_data(0x00); //寫(xiě)入0,清除GDROM
- }
- }
- lcd_addr(0x30);//基本指令集
- }
- //LCD12864顯示自定義字符程序(字符顯示在屏中間兩行,每個(gè)字符16*32點(diǎn)陣)
- void lcd_disp(uchar add1,uchar add2,uchar add3,uchar add4,uchar code *P)
- {
- uchar j,k;
- lcd_addr(0x34);//擴(kuò)充指令集
- lcd_addr(0x36);//打開(kāi)繪圖
- for(j=0;j<16;j++) //顯示上16行,字符上半截顯示
- {
- lcd_addr(add2+j);//寫(xiě)y坐標(biāo)
- lcd_addr(add1); //寫(xiě)x坐標(biāo)
- for(k=0;k<2;k++)//每行顯示二個(gè)字節(jié)
- {lcd_data(*P++);} //寫(xiě)入編碼數(shù)據(jù)
- }
- for(j=0;j<16;j++) //顯示下16行,字符下半截顯示
- {
- lcd_addr(add4+j);//寫(xiě)y坐標(biāo)
- lcd_addr(add3); //寫(xiě)x坐標(biāo)
- for(k=0;k<2;k++)//每行顯示二個(gè)字節(jié)
- {lcd_data(*P++);} //寫(xiě)入編碼數(shù)據(jù)
- }
- lcd_addr(0x30);//基本指令集
- }
- /****************DS18B20復(fù)位函數(shù)************************/
- void ds1820_int()
- {
- uchar ds_flag=1;
- while(ds_flag)
- {
- dq=1;
- _nop_();
- _nop_();
-
- dq=0; //從高拉倒低
- dsdelay(50); //550 us
- dq=1;
- dsdelay(6); //66 us
- ds_flag=dq; //ds_flag=0 復(fù)位成功,繼續(xù)下一步
- }
- dsdelay(45); //延時(shí)500 us
- ds_flag=~dq;
- dq=1; //拉高電平
- }
-
- /****************DS18B20寫(xiě)命令函數(shù)************************/
- //向1-WIRE 總線(xiàn)上寫(xiě)1個(gè)字節(jié)
- void write_byte(uchar val)
- {
- uchar i;
- for(i=8;i>0;i--)
- {
- dq=1;
- _nop_();
- _nop_(); //從高拉倒低
- dq=0;
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //5 us
- dq=val&0x01; //寫(xiě)入一位數(shù)據(jù)
- dsdelay(6); //66 us
- val=val/2; //右移1位
- }
- dq=1;
- dsdelay(1);
- }
- /****************DS18B20讀1字節(jié)函數(shù)************************/
- //從總線(xiàn)上取1個(gè)字節(jié)
- uchar read_byte()
- {
- uchar i;
- uchar num2=0;
- for(i=8;i>0;i--)
- {
- dq=1;
- _nop_();
- _nop_();
- num2>>=1;
- dq=0;
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //4 us
- dq=1 ; //釋放總線(xiàn)
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //4 us
- if(dq) //如果dq=1;則把num的最高位置1
- {
- num2|=0x80; //如果dq=0;則越過(guò)num|=0x80執(zhí)行延時(shí)
- }
- dsdelay(6); //66 us
- }
- dq=1;
- return(num2); //讀出的原始值
- }
-
- /****讀出DS18B20溫度數(shù)據(jù)并轉(zhuǎn)換成顯示用的BCD碼*********/
- void read_temp()
- {
- uchar tem,num,low,high;
- uint temp;
- ds1820_int();
- dsdelay(1);
- write_byte(0xcc); //跳過(guò)ROM命令
- write_byte(0xbe); //讀18B20暫存器命令(0xBE)
- low=read_byte(); //讀溫度值的低字節(jié)
- high=read_byte(); //讀溫度值的高字節(jié)
- tem=high&0xf8; //分離出溫度符號(hào)
- temp=high;
- temp<<=8; //把高八位左移到高位
- temp=temp|low; //分離出16位的溫度數(shù)據(jù)(包括符號(hào)及小數(shù))
- flag=0; //符號(hào)標(biāo)志位清0
- if(tem>16) //符號(hào)判斷
- {
- temp=65536-temp;//負(fù)溫度求補(bǔ)碼
- flag=1; //符號(hào)標(biāo)志位置1 (表示是負(fù)數(shù))
- }
- num=temp&0x0f; //分離出小數(shù)
- num=num*6; //小數(shù)乘系數(shù)
- xiao=num/10; //分離并保存小數(shù)第一個(gè)字符
- num=num%10; //分離并保存小數(shù)第二個(gè)字符
- if(num>5) //小數(shù)進(jìn)行四舍五入
- {
- xiao++; //小數(shù)第二位如大于5就加1
- }
- temp=temp>>4; //右移四位,得到溫度整數(shù)部分?jǐn)?shù)據(jù)
- baiw=temp/100; //分離出百位
- shiw=temp%100/10;//分離出十位
- gew=temp%10; //分離出個(gè)位
- }
- void temp_disp()//溫度顯示程序
- {
- read_temp() ;//讀出溫度數(shù)據(jù)并轉(zhuǎn)換成顯示數(shù)據(jù)
- if(flag==1)//如為1表示是負(fù)溫度值,在百位顯示負(fù)號(hào)
- {
- lcd_addr(0x9c);
- lcd_data(0x20);//顯示空白
- lcd_data(0x2d);//顯示負(fù)號(hào)
- }
- if(flag==0)//如為0表示是正溫度值,顯示百位溫度
- {
- lcd_addr(0x9c);//百位地址
- lcd_data(0x20);//顯示百位
- lcd_data(0x30+baiw);
- }
- lcd_addr(0x9d);
- lcd_data(0x30+shiw);
- lcd_data(0x30+gew);
-
- lcd_addr(0x9e);
- lcd_data(0x2e);
- lcd_data(0x30+xiao);
- }
- //******************DS12887讀寫(xiě)程序*************************************
- void write_ds(uchar add,uchar date)//往DS12887內(nèi)寫(xiě)數(shù)據(jù)(add地址,date數(shù)據(jù))
- {
- dscs=0;
- dsas=1;
- dsds=1;
- dsrw=1;
- P1=add; //先送地址
- dsas=0;
- dsrw=0;
- P1=date; //后寫(xiě)入數(shù)據(jù)
- dsrw=1;
- dsas=1;
- dscs=1;
- }
- uchar read_ds(uchar add)//讀DS12887內(nèi)部數(shù)據(jù)(帶返回值的)
- {
- uchar ds_date;
- dsas=1;
- dsds=1;
- dsrw=1;
- dscs=0;
- P1=add; //先送地址
- dsas=0;
- dsds=0;
- P1=0xff;
- ds_date=P1;//后讀出數(shù)據(jù)
- dsds=1;
- dsas=1;
- dscs=1;
- return ds_date;//帶返回值語(yǔ)句
- }
- void ds_init() //DS12887初始化
- {
- dscs=0;
- write_ds(0x0a,0x20);//啟動(dòng)DS12887
- write_ds(0x0b,0x86);//禁止更新,接下來(lái)初始化數(shù)據(jù),即寫(xiě)入時(shí)間,日期等
- write_ds(0x0b,0x06);//正常更新,二進(jìn)制格式,24進(jìn)制小時(shí)
-
- }
- //***************數(shù)據(jù)轉(zhuǎn)換及顯示程序**************************************
- void lcd_disdata(uchar bcd)//送顯示地址及顯示數(shù)據(jù)
- {
- switch(bcd)//a1,a2,a3,a4為自定義字符上半截XY及下半截XY地址,tab*為自定義字符碼
- {
- case 0:lcd_disp(a1,a2,a3,a4,tab0);//把地址及字符數(shù)據(jù)送到LCD顯示程序
- break;
- case 1:lcd_disp(a1,a2,a3,a4,tab1);
- break;
- case 2:lcd_disp(a1,a2,a3,a4,tab2);
- break;
- case 3:lcd_disp(a1,a2,a3,a4,tab3);
- break;
- case 4:lcd_disp(a1,a2,a3,a4,tab4);
- break;
- case 5:lcd_disp(a1,a2,a3,a4,tab5);
- break;
- case 6:lcd_disp(a1,a2,a3,a4,tab6);
- break;
- case 7:lcd_disp(a1,a2,a3,a4,tab7);
- break;
- case 8:lcd_disp(a1,a2,a3,a4,tab8);
- break;
- case 9:lcd_disp(a1,a2,a3,a4,tab9);
- break;
- default://lcd_disp(a1,a2,a3,a4,tab0);
- break;
- }
- }
- //分離個(gè)位和十位子程序
- void datafl(uchar dafl)
- {
- gw=dafl%10;//取余
- sw=dafl/10;//取模
- }
- void sfm_data()//讀出DS12887數(shù)據(jù)及LCD12864顯示地址賦值
- {
- a2=0x90;//自定義字符上半截Y軸地址(因?yàn)閅地址固定不變,所以先寫(xiě)入)
- a4=0x80;//自定義字符下半截Y軸地址(因?yàn)閅地址固定不變,所以先寫(xiě)入)
- if(flag1==0)
- {
- miao=read_ds(0);//指定DS12887秒地址,讀出秒的值
- fen=read_ds(2); //指定DS12887分地址,讀出分的值
- shi=read_ds(4); //指定DS12887時(shí)地址,讀出時(shí)的值
- week=read_ds(6); //指定DS12887周地址,讀出周的值
- ri=read_ds(7); //指定DS12887日地址,讀出日的值
- yue=read_ds(8); //指定DS12887月地址,讀出月的值
- nian=read_ds(9); //指定DS12887年地址,讀出年的值
- }
- datafl(miao); //把DS12887讀出的數(shù)據(jù)分離出個(gè)位和十位
- if(miao!=m1) //如秒值變化就進(jìn)入刷新顯示
- {
- m1=miao;
- a1=0x97;//自定義字符(秒個(gè)位)上半截X軸地址
- a3=0x8f;//自定義秒字符(秒個(gè)位)下半截X軸地址
- lcd_disdata(gw);//秒個(gè)位送地址轉(zhuǎn)換再送LCD顯示
- a1=0x96;//自定義字符(秒十位)上半截X軸地址
- a3=0x8e;//自定義字符(秒十位)下半截X軸地址
- lcd_disdata(sw);//秒十位送地址轉(zhuǎn)換再送LCD顯示
- }
- if(fen!=f1)////如分值變化就進(jìn)入刷新顯示
- {
- f1=fen;
- datafl(fen); //把DS12887讀出的數(shù)據(jù)分離出個(gè)位和十位
- a1=0x94;
- a3=0x8c;
- lcd_disdata(gw);//分個(gè)位送地址轉(zhuǎn)換再送LCD顯示
- a1=0x93;
- a3=0x8b;
- lcd_disdata(sw);//分十位送地址轉(zhuǎn)換再送LCD顯示
- }
- if(shi!=s1)////如時(shí)值變化就進(jìn)入刷新顯示
- {
- s1=shi;
- datafl(shi); //把DS12887讀出的數(shù)據(jù)分離出個(gè)位和十位
- a1=0x91;
- a3=0x89;
- lcd_disdata(gw);//時(shí)個(gè)位送地址轉(zhuǎn)換再送LCD顯示
- a1=0x90;
- a3=0x88;
- lcd_disdata(sw);//時(shí)十位送地址轉(zhuǎn)換再送LCD顯示
- }
- }
-
- void xstb(uchar code *p1,uchar code *p2)//自定義圖標(biāo)及符號(hào)顯示程序(16*16點(diǎn)陣)
- {
- uchar j,k;
- lcd_addr(0x34);//擴(kuò)充指令集
- lcd_addr(0x36);//打開(kāi)繪圖
- for(j=0;j<16;j++)
- {
- lcd_addr(0x90+j);
- lcd_addr(0x9b);
- for(k=0;k<2;k++)//每行顯示二個(gè)字節(jié)
- {lcd_data(*p1++);} //寫(xiě)入編碼數(shù)據(jù)
- }
- for(j=0;j<16;j++)
- {
- lcd_addr(0x90+j);
- lcd_addr(0x9f);
- for(k=0;k<2;k++)//每行顯示二個(gè)字節(jié)
- {lcd_data(*p2++);} //寫(xiě)入編碼數(shù)據(jù)
- }
-
- }
-
- void nyrhz()//固定年月日周漢字顯示
- {
- uchar *p;
- p="20 年 月 日";
- lcd_addr(0x80);
- while(*p!='\0')
- {
- lcd_data(*p);
- p++;
- }
- p="星期";
- lcd_addr(0x98);
- while(*p!='\0')
- {
- lcd_data(*p);
- p++;
- }
- xstb(tab10,tab11);
- }
- void week_disp()
- {
- lcd_addr(0x9a);//周地址
- switch(week)
- {
- case 1:lcd_data(0xd2);lcd_data(0xbb);//顯示一
- break;
- case 2:lcd_data(0xb6);lcd_data(0xfe);//顯示二
- break;
- case 3:lcd_data(0xc8);lcd_data(0xfd);//顯示三
- break;
- case 4:lcd_data(0xcb);lcd_data(0xc4);//顯示四
- break;
- case 5:lcd_data(0xce);lcd_data(0xe5);//顯示五
- break;
- case 6:lcd_data(0xc1);lcd_data(0xf9);//顯示六
- break;
- case 7:lcd_data(0xc8);lcd_data(0xd5);//顯示日
- break;
- default://lcd_data(0xb4);lcd_data(0xed);//顯示錯(cuò)
- break;
- }
- }
- void lyr_disp()//年月日周數(shù)據(jù)處理及顯示程序
- {
- uchar n1,y1,r1;
-
- datafl(nian);//年顯示數(shù)據(jù)分離成個(gè)位和十位
- if(nian!=n1)
- {
- n1=nian;
- datafl(nian);
- lcd_addr(0x81); //指定年的顯示地址
- lcd_data(0x30+sw);
- lcd_data(0x30+gw);
- }
- if(yue!=y1)
- {
- y1=yue;
- datafl(yue);
- lcd_addr(0x83);
- lcd_data(0x30+sw);
- lcd_data(0x30+gw);
- }
- if(ri!=r1)
- {
- r1=ri;
- datafl(ri);
- lcd_addr(0x85);
- lcd_data(0x30+sw);
- lcd_data(0x30+gw);
- }
- week_disp();//周數(shù)據(jù)處理及顯示
- }
- void sfm_rst(uchar add1,uchar add2,uchar add3,uchar add4)//時(shí)分秒清零程序
- {//在時(shí)分秒調(diào)整時(shí)自定義字符會(huì)閃爍就會(huì)調(diào)用此程序
- uchar j,k;
- lcd_addr(0x34);//擴(kuò)充指令集
- lcd_addr(0x36);//打開(kāi)繪圖
- for(j=0;j<16;j++) //顯示上16行,字符上半截顯示
- {
- lcd_addr(add2+j);//寫(xiě)y坐標(biāo)
- lcd_addr(add1); //寫(xiě)x坐標(biāo)
- for(k=0;k<2;k++)//每行顯示二個(gè)字節(jié)
- {lcd_data(0);} //寫(xiě)入編碼數(shù)據(jù)
- }
- for(j=0;j<16;j++) //顯示下16行,字符下半截顯示
- {
- lcd_addr(add4+j);//寫(xiě)y坐標(biāo)
- lcd_addr(add3); //寫(xiě)x坐標(biāo)
- for(k=0;k<2;k++)//每行顯示二個(gè)字節(jié)
- {lcd_data(0);} //寫(xiě)入編碼數(shù)據(jù)
- }
- }
-
- void jiajian()
- {
- if(num1!=0) //如果不等于0表示有鍵按下進(jìn)入程序
- {
- if(jia==0) //加鍵按下進(jìn)入
- {
- delay(5);
- if(jia==0) //再次確認(rèn)加鍵按下進(jìn)入
- {
- while(!jia); //松手進(jìn)入
- if(num1==1) //如果=1就表明光標(biāo)在秒的位置
- {
- miao++; //秒+1
- if(miao>59)//秒加到60進(jìn)入
- miao=0; //秒清0
-
- }
- if(num1==2) //確定光標(biāo)在分位置進(jìn)入
- {
- fen++; //
- if(fen>59)
- fen=0;
-
- }
- if(num1==3) //確定光標(biāo)在時(shí)位置進(jìn)入
- {
- shi++;
- if(shi>23)
- shi=0;
- }
-
- if(num1==4) //確定光標(biāo)在日位置進(jìn)入
- {
- ri++;
- if(ri>31)
- ri=1;
- }
- if(num1==5) //確定光標(biāo)在月位置進(jìn)入
- {
- yue++;
- if(yue>12)
- yue=1;
- }
- if(num1==6) //確定光標(biāo)在年位置進(jìn)入
- {
- nian++;
- if(nian>99)
- nian=0;
- }
- if(num1==7) //確定光標(biāo)在周位置進(jìn)入
- {
- week++;
- if(week>7)
- week=1;
- }
- }
- }
- if(jian==0) //減鍵按下進(jìn)入
- {
- delay(5);
- if(jian==0)
- {
- while(!jian);
- if(num1==1)
- {
- miao--;
- if(miao==-1)
- miao=59;
-
- }
- if(num1==2)
- {
- fen--;
- if(fen==-1)
- fen=59;
- }
- if(num1==3)
- {
- shi--;
- if(shi==-1)
- shi=23;
- }
- if(num1==4)
- {
- ri--;
- if(ri<1)
- ri=31;
- }
- if(num1==5) //
- {
- yue--;
- if(yue<1)
- yue=12;
- }
- if(num1==6)
- {
- nian--;
- if(nian<0)
- nian=99;
- }
- if(num1==7)
- {
- week--;
- if(week<1)
- week=7;
- }
- }
- }
- }
- }
-
- /**********************按鍵掃描程序******************************/
- void key()//按鍵掃描程序
- {
- uchar n1,n2;
- if(set==0)
- {
- num1++;
- flag1=1;
- }
- if(flag1==1)
- {
- if(num1==1)//秒閃爍
- {
- sfm_rst(0x97,0x90,0x8f,0x80); //清除秒位置字符
- sfm_rst(0x96,0x90,0x8e,0x80);
- for(n1=0;n1<250;n1++)
- {
- delay(1);
- jiajian();
- }
-
- datafl(miao);
- a1=0x96;
- a3=0x8e;
- lcd_disdata(sw);
- a1=0x97;
- a3=0x8f;
- lcd_disdata(gw);
- for(n2=0;n2<250;n2++)
- {
- delay(1);
- jiajian();
- }
- }
- if(num1==2)//分閃爍
- {
- sfm_rst(0x94,0x90,0x8c,0x80);
- sfm_rst(0x93,0x90,0x8b,0x80);
- for(n1=0;n1<250;n1++)
- {
- delay(1);
- jiajian();
- }
-
- datafl(fen);
- a1=0x93;
- a3=0x8b;
- lcd_disdata(sw);
- a1=0x94;
- a3=0x8c;
- lcd_disdata(gw);
- for(n2=0;n2<250;n2++)
- {
- delay(1);
- jiajian();
- }
- }
- if(num1==3)//時(shí)閃爍
- {
- sfm_rst(0x91,0x90,0x89,0x80);
- sfm_rst(0x90,0x90,0x88,0x80);
- for(n1=0;n1<250;n1++)
- {
- delay(1);
- jiajian();
- }
-
- datafl(shi);
- a1=0x90;
- a3=0x88;
- lcd_disdata(sw);
- a1=0x91;
- a3=0x89;
- lcd_disdata(gw);
- for(n2=0;n2<250;n2++)
- {
- delay(1);
- jiajian();
- }
- }
-
- if(num1==4)//日閃爍
- {
- lcd_addr(0x85);
- lcd_data(0xa1);
- lcd_data(0xa0);
- for(n1=0;n1<250;n1++)
- {
- delay(1);
- jiajian();
- }
-
- datafl(ri);
- lcd_addr(0x85);
- lcd_data(0x30+sw);
- lcd_data(0x30+gw);
- for(n2=0;n2<250;n2++)
- {
- delay(1);
- jiajian();
- }
- }
- if(num1==5)//月閃爍
- {
- lcd_addr(0x83);
- lcd_data(0xa1);
- lcd_data(0xa0);
- for(n1=0;n1<250;n1++)
- {
- delay(1);
- jiajian();
- }
-
- datafl(yue);
- lcd_addr(0x83);
- lcd_data(0x30+sw);
- lcd_data(0x30+gw);
- for(n2=0;n2<250;n2++)
- {
- delay(1);
- jiajian();
- }
- }
- if(num1==6)//年閃爍
- {
- lcd_addr(0x81);
- lcd_data(0xa1);
- lcd_data(0xa0);
- for(n1=0;n1<250;n1++)
- {
- delay(1);
- jiajian();
- }
-
- datafl(nian);
- lcd_addr(0x81);
- lcd_data(0x30+sw);
- lcd_data(0x30+gw);
- for(n2=0;n2<250;n2++)
- {
- delay(1);
- jiajian();
- }
- }
- if(num1==7)//周閃爍
- {
- lcd_addr(0x9a);
- lcd_data(0xa1);
- lcd_data(0xa0);
- for(n1=0;n1<250;n1++)
- {
- delay(1);
- jiajian();
- }
-
- datafl(week);
- week_disp();
- for(n2=0;n2<250;n2++)
- {
- delay(1);
- jiajian();
- }
- }
- if(num1>7)
- {
- if(set==1)
- {
- write_ds(0,miao); //秒數(shù)據(jù)寫(xiě)入DS12887
- write_ds(2,fen); //分?jǐn)?shù)據(jù)寫(xiě)入DS12887
- write_ds(4,shi); //時(shí)數(shù)據(jù)寫(xiě)入DS12887
- write_ds(6,week);
-
- write_ds(7,ri);
- write_ds(8,yue);
- write_ds(9,nian);
- num1=0;
- flag1=0;
- }
- }
- }
- }
-
- void main(void)//主程序入口
- {
- lcd_init(); //LCD初始化
- lcd_clear(); //清除LCD繪圖寄存器,解決花屏。
- ds_init(); //DS12887初始化
- lcd_disp(0x92,0x90,0x8a,0x80,tabm);//顯示分前面的:號(hào)
- lcd_disp(0x95,0x90,0x8d,0x80,tabm);//顯示分后面的:號(hào)
- nyrhz();//固定年月日漢字及自定義圖標(biāo)顯示
- while(1)//調(diào)用顯示
- {
- sfm_data();//調(diào)用時(shí)分秒數(shù)據(jù)處理及顯示
- lyr_disp();//調(diào)用年月日周數(shù)據(jù)處理及顯示
- ds1820_int(); //18B20初始化
- write_byte(0xcc);//寫(xiě)入跳過(guò)ROM指令(0xcc)
- write_byte(0x44); //發(fā)轉(zhuǎn)換命令
- temp_disp();//讀取溫度值進(jìn)行轉(zhuǎn)換再顯示程序
- key();//設(shè)置按鍵掃描
- }
- }
復(fù)制代碼
|
|