|
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (17.66 KB, 下載次數(shù): 67)
下載附件
2018-10-16 01:44 上傳
0.png (44.59 KB, 下載次數(shù): 66)
下載附件
2018-10-16 01:44 上傳
單片機(jī)源程序如下:
- // 辛苦了 幾天總算好了,呵呵
- #include <reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define LCD_DATA P0
- sbit RST=P1^4; //ds1302復(fù)位引腳,高電平有效
- sbit IO=P1^3; //ds1302數(shù)據(jù)輸入輸出
- sbit SCLK=P1^2; //ds1302串行時(shí)鐘
- sbit LCD_RS=P2^5;
- sbit LCD_RW=P2^6;
- sbit LCD_E =P2^7;
- sbit DQ=P3^4;
- sbit baojing=P3^5;
- bit add,dec,changett,ok=0;
- uchar wendu,flag ,temp2[7],HH,LL;//功能標(biāo)志
- uchar code zidiyi[]={0x08,0x0F,0x12,0x0F,0x0A,0x1F,0x02,0x02, //年字點(diǎn)陣
- 0x0F,0x09,0x0F,0x09,0x0F,0x09,0x11,0x10, //月字點(diǎn)陣
- 0x0F,0x09,0x09,0x0F,0x09,0x09,0x0F,0x00, //日字點(diǎn)陣
- 0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00} ; //℃點(diǎn)陣
- uchar idata buffer[3]={0X00,0X00,0X03};//定義兩段緩沖區(qū)
- uchar code week[]={"MonTueWedThuFriSatSun"};//星期
- uchar code wradd[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //ds1302寫地址,秒、分、時(shí)、日、月、星期、年
- uchar code rdadd[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //ds1302讀地址
- uchar idata temp[]={0x30,0x30,0x12,0x29,0x06,0x07,0x10};
- uchar h_time[7],l_time[7]; //溫度個(gè)位,十位分別存放
- uchar H=31,L=21; //溫度上下限
- //void LCD_Init(void);
- void LCD_Write_Data(uchar dat);
- void LCD_Write_Cmd(uchar cmd,BusyC);
- //uchar LCD_Read_Data(void);
- void LCD_Delay(uint ms);
- uchar LCD_Check_Busy(void);
- //void writetab(void);
- //***********由于實(shí)驗(yàn)時(shí)電路板1602高低位數(shù)據(jù)接反,所以在向1602讀寫數(shù)據(jù)時(shí)調(diào)用此函數(shù)進(jìn)行高低位調(diào)整***********//
- uchar Convert (uchar In_Date)
- {
- uchar i, Out_Date, temp;
- for(i=0; i<8; i++)
- {
- temp = (In_Date >> i) & 0x01;
- Out_Date |= (temp << (7 - i));
- }
- return Out_Date;
- }
- //*******毫秒級(jí)延時(shí)********//
- void delayus(uint x)
- {
- while(x--);
- }
- //********** 將自定義點(diǎn)陣輸入庫**********//
- void ziding(void)
- {uchar i;
- LCD_Write_Cmd(0x40,1);// 自定義存儲(chǔ)地址從0X40開始
- for(i=0;i<32;i++)
- LCD_Write_Data(zidiyi[i]);
- }
- /*初始化lcd1602 */
- /*******************************************************************/
- void LCD_Init(void)
- {
- LCD_DATA=0;
- LCD_Write_Cmd(0x38,1); //顯示模式設(shè)置,開始要求檢測(cè)忙信號(hào):8位、2行、5X7點(diǎn)陣
- LCD_Write_Cmd(0x08,1); //關(guān)閉顯示
- LCD_Write_Cmd(0x01,1); //清屏
- LCD_Write_Cmd(0x06,1); //顯示光標(biāo)移動(dòng)設(shè)置:文字不動(dòng),光標(biāo)自動(dòng)右移
- LCD_Write_Cmd(0x0C,1); //顯示開及光標(biāo)設(shè)置:光標(biāo)關(guān)、光標(biāo)不閃爍
- ziding();
- }
- //************lcd寫數(shù)據(jù)***************//
- void LCD_Write_Data(uchar dat)
- {
- LCD_Check_Busy();
- LCD_DATA=Convert(dat);
- LCD_RS=1;
- LCD_RW=0;
- LCD_E=0;
- LCD_Delay(5);
- LCD_E=1;
- }
- //*****************LCD寫命令******************//
- void LCD_Write_Cmd(uchar cmd,BusyC)
- {
- if(BusyC) LCD_Check_Busy();
- LCD_DATA=Convert(cmd);
- LCD_RS=0;
- LCD_RW=0;
- LCD_E=0;
- LCD_Delay(5);
- LCD_E=1;
- }
- //***************lcd測(cè)忙*******************//
- uchar LCD_Check_Busy(void)
- {
- LCD_DATA=0xFF;
- LCD_RS=0;
- LCD_RW=1;
- LCD_E=0;
- LCD_Delay(5);
- LCD_E=1;
- while(LCD_DATA & 0x01);
- return(LCD_DATA);
- }
-
- //*****************************ms級(jí)延時(shí)函數(shù)*************************************//
- void LCD_Delay(uint ms)
- {
- uchar i;
- while(--ms)
- {
- for(i=0;i<123;i++);
- }
- }
-
- //***************************設(shè)置顯示位置 ****************************************//
- void LCD_Position(uchar pos)
- {
- pos|=0x80;
- LCD_Write_Cmd(pos,0); //數(shù)據(jù)指針=80+地址變量
- }
- //************顯示十位個(gè)位**********//
- void displayshige(uchar a ,uchar b, uchar adress)
- {
- LCD_Write_Cmd(adress,1);
- delayus(2);
- LCD_Write_Data(a);
- delayus(2);
- LCD_Write_Data(b);
- delayus(2);
- }
- //....................ds18B20溫度檢測(cè)..........................//
- void init18b20(void) //ds18b20初始化
- {
- uchar x;
- DQ=1;
- delayus(5);
- DQ=0;
- delayus(80);
- DQ=1;
- delayus(10);
- x=DQ;
- delayus(10);
- }
- void write18b20(uchar dat) //寫數(shù)據(jù)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DQ=0;
- DQ=dat&0x01;
- delayus(5);
- DQ=1;
- dat>>=1;
- }
- delayus(5);
- }
- uchar read18b20(void) //讀數(shù)據(jù)
- {
- uchar dat=0;
- uchar i;
- for(i=0;i<8;i++)
- {
- DQ=0;
- dat>>=1;
- DQ=1;
- if(DQ) dat|=0x80;
- delayus(5);
- }
- return(dat);
- }
- void readtmp(void) //讀溫度
- { uchar a,b,c;
- uint aa;
- init18b20();
- write18b20(0xcc);//跳過讀序列號(hào)
- write18b20(0x44);//開始轉(zhuǎn)換
- init18b20();
- write18b20(0xcc);//跳過讀序列號(hào)
- write18b20(0xbe);//讀取溫度
- a=read18b20();
- b=read18b20();
- c=a&0x0f;//分離出小數(shù)部分
- b=(b&0x0f)<<4;
- b|=(a&0xf0)>>4;//b里放整數(shù)
- wendu=b;
- aa=625*c;//可以直接用移位
- displayshige(aa/1000+0x30,0x03, 0x83);
- aa=0;
- displayshige(b/10+0x30 ,b%10+0x30, 0x80);
- LCD_Write_Data('.');
- }
- //****************DS1302寫 一字節(jié)數(shù)據(jù)*********//
- void writebyte(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- SCLK=0;
- delayus(2);
- IO=dat&0x01;
- dat>>=1;
- SCLK=1;
- delayus(2);
- }
- }
- //****************DS1302 寫 一字節(jié)數(shù)據(jù)*********//
- void write1302(uchar addr,uchar dat) //傳遞地址與要寫的數(shù)據(jù)
- {
- RST=0;
- delayus(2);
- SCLK=0;
- delayus(2);
- RST=1;
- delayus(2);
- writebyte(addr);
- writebyte(dat);
- RST=0;
- delayus(2);
- }
- //****************DS1302讀 一字節(jié)數(shù)據(jù)*********//
- uchar read(uchar addr)
- {
- uchar i,dat=0;
- RST=0;
- delayus(2);
- SCLK=0;
- delayus(2);
- RST=1;
- delayus(2);
- writebyte(addr);
- for(i=0;i<8;i++)
- {
- dat>>=1;
- SCLK=1;
- delayus(2);
- SCLK=0;
- delayus(2);
- if(IO) dat|=0x80;
- }
- RST=0;
- delayus(2);
- return(dat);
- }
- //*************1302初始化***************//
- void init1302(void)
- {
- uchar i;
- write1302(0x8e,0x00);//禁止寫保護(hù)?
- for(i=0;i<7;i++)
- {
- write1302(wradd[i],temp[i]);
- }
- write1302(0x8e,0x80);// 寫保護(hù)
- }
- //*********** 讀出所有的數(shù)據(jù)***********//
- void read1302(void)
- {
- uchar i;
- for(i=0;i<7;i++)
- {
- temp[i]=read(rdadd[i]);
- }
- }
- //**************將十位個(gè)位分離************//
- void chang(void)
- {
- uchar i;
- for(i=0;i<7;i++)
- {if(i!=5)
- {h_time[i]=temp[i]/16+0x30;
- l_time[i]=temp[i]%16+0x30;}
- else
- {l_time[i]=temp[i]%16;}
- }
- }
-
-
- //************顯示時(shí)間和日期、溫度**********//
- void display(void)
- {uchar i;
- displayshige(h_time[6],l_time[6], 0xc0) ;//年
- LCD_Write_Data(0);
- displayshige(h_time[4],l_time[4], 0xc3) ;//月
- LCD_Write_Data(1);
- displayshige(h_time[3],l_time[3], 0xc6);//日
- LCD_Write_Data(2);
- displayshige(h_time[2],l_time[2], 0x85);//時(shí)
- LCD_Write_Data(':');
- displayshige(h_time[1],l_time[1], 0x88);//分
- LCD_Write_Data(':');
- displayshige(h_time[0],l_time[0], 0x8b);//秒
-
- i=(l_time[5]-1)*3; //星期的顯示,先選出數(shù)組中的第幾位
- LCD_Write_Cmd(0x8d,1); //顯示星期
- LCD_Write_Data(week[i]);
- LCD_Delay(2);
- i++;
- LCD_Write_Data(week[i]);
- LCD_Delay(2);
- i++;
- LCD_Write_Data(week[i]); //顯示星期數(shù)
- LCD_Delay(2);
- if(!changett)//如果要修改時(shí)間,則不執(zhí)行下面高低溫度顯示
- {LCD_Write_Cmd(0xca,1);
- LCD_Write_Data('H');
- displayshige(H/10+0x30,H%10+0x30, 0xcb);
- LCD_Write_Cmd(0xcd,1);
- LCD_Write_Data('L');
- displayshige(L/10+0x30,L%10+0x30, 0xce);
- }
- }
- //*********鍵掃描并確定功能********//
- void keyscan(void)
- {
- uchar scode,recode,key,t;
- P1=0xf0;
- if((P1 & 0xf0)!=0xf0)
- {
- LCD_Delay(10);
- if((P1 & 0xf0)!=0xf0)
- {scode=0xfe;
- while((scode &0x10)!=0)
- {P1=scode;
- if ((P1 & 0xf0)!=0xf0)
- {
- recode=(P1 & 0xf0)| 0x0f;
- key=(~scode)+(~recode);
- switch(key)
- {case 0x11:changett=0; break;
- case 0x21:if(changett)flag=1; break;//年
- case 0x41:if(changett)flag=2; break;//月
- case 0x81:if(changett)flag=3; break;//日
- case 0x12:if(changett)flag=4; break;//時(shí)
- case 0x22:if(changett)flag=5; break;//分
- case 0x42:if(changett)flag=6; break;//秒
- case 0x82:if(changett)flag=7; break;//周
- case 0x14:if(changett)flag=8; break;//H
- case 0x24:if(changett)flag=9; break;//L
- case 0x44:if(flag>=1&&flag<=9){add=1; dec=0;}break;//加
- case 0x84:if(flag>=1&&flag<=9){add=0; dec=1;}break;//減
- case 0x18:break;//保存溫度
- case 0x28:changett=1;for(t=0;t<7;t++)
- temp2[t]=temp[t];HH=H;LL=L;;break;//改變時(shí)間,溫度
- case 0x48:if(changett)ok=1;break;//確定設(shè)置的時(shí)間,溫度
-
- }
- }
- else scode=(scode<<1)|0x01;
- }
- }
- }
- }
- //***********設(shè)置時(shí)間和上下限溫度**********//
- void timechange()
- {
- uchar num;
- if(flag==1) //年
- {
- num=temp2[6]%16+(temp2[6]>>4)*10;
- if(add)
- {num++;add=0;}
- if(dec)
- { num--;dec=0;}
- temp[6]=num/10*16+num%10;
- temp2[6]=temp[6];
- }
- if(flag==2) //月
- {
- num=temp2[4]%16+(temp2[4]>>4)*10;
- if(add)
- {num++;add=0;}
- if(num==13) num=1;
- if(dec)
- { num--;dec=0;}
- if(num==00) num=12;
-
- temp[4]=num/10*16+num%10;
- temp2[4]=temp[4];
- }
- if(flag==3) //日
- {
- num=temp2[3]%16+(temp2[3]>>4)*10;
- delayus(2);
- if(add)
- {num++;add=0;}
- if(num==32) num=1;
- if(dec)
- { num--;dec=0;}
- if(num==00) num=31;
- temp[3]=num/10*16+num%10;
- temp2[3]=temp[3];
- }
- if(flag==4) //時(shí)
- {
- num=temp[2]%16+(temp2[2]>>4)*10;
-
- if(add)
- {num++;add=0;}
- if(num==24) num=00;
- if(dec)
- { num--;dec=0;}
- if(num==-1) num=23;
- temp[2]=num/10*16+num%10;
- temp2[2]=temp[2];
- }
-
- if(flag==5) //分
- {
- num=temp2[1]%16+(temp2[1]>>4)*10;
- if(add)
- {num++;add=0;}
- if(num==60) num=00;
- if(dec)
- { num--;dec=0;}
-
- if(num==-1) num=59;
-
- temp[1]=num/10*16+num%10;
- temp2[1]=temp[1];
- }
- if(flag==6) //秒
- {
- num=temp2[0]%16+(temp2[0]>>4)*10;
-
- if(add)
- {num++;add=0;}
- if(num==60) num=00;
- if(dec)
- { num--;dec=0;}
- if(num==-1) num=59;
- temp[0]=num/10*16+num%10;
- temp2[0]=temp[0];
- }
-
- if(flag==7) //周
- {
- num=temp2[5]%16;
-
- if(add)
- {num++;add=0;}
- if(num==0x08) num=1;
- if(dec)
- { num--;dec=0;}
- if(num==0x0) num=7;
-
- temp[5]=num%10;
- temp2[5]=temp[5];
- }
- if(flag==8) //H
- {
- if(add)
- {HH++;add=0;}
- if(dec)
- { HH--;dec=0;}
-
- }
- displayshige(0x20,'H', 0xc8);//高溫顯示
- displayshige(HH/10+0x30,HH%10+0x30, 0xca);
- if(flag==9) //L
- {
-
-
- if(add)
- {LL++;add=0;}
- if(dec)
- { LL--;dec=0;}
- }
- displayshige(0x20,'L', 0xcc);//高溫顯示
- displayshige(LL/10+0x30,LL%10+0x30, 0xce);
-
- }
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
51的lcd1602 ds18b20 ds1302熱水器控制,軟硬件.rar
(48.75 KB, 下載次數(shù): 89)
2018-10-15 21:06 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|