以AT89C51單片機為核心的控制器,以DS18B20為溫度傳感器的溫度控制器。
首先,通過對元器件的選擇,設(shè)計控制器的硬件電路;然后,設(shè)計相關(guān)應(yīng)用程序;最后,通過仿真,對整個系統(tǒng)進行調(diào)試、分析。最終實現(xiàn)溫度采集、顯示、控制等功能。。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #include<reg51.h>
- #include<stdio.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit ds=P3^2; //溫度傳感器信號線
- sbit RS=P1^0;
- sbit RW=P1^1;
- sbit E=P1^2;
- sbit beep=P1^5;
- sbit man=P1^6;
- sbit woman=P1^7;
- uint temp;
- uint count=0;
- uchar f_temp;
- unsigned int A,W,C;
- data unsigned char SET[15]={"settemp: "};
- data unsigned char REAL[15]={"realtemp: "};
- char code tab[3][4]={ {'1','2','3','4'},
- {'5','6','7','8'},
- {'9','0',' ',' '}}; //0到F的16個鍵植
-
- void delay(uint z) //延時函數(shù)
- { uint x,y;
- for (x=z;x>0;x--)
- for (y=110;y>0;y--);
- }
-
-
- //以下是DS18B20的相關(guān)程序
- void dsreset(void) //DS18B20復(fù)位初始化函數(shù)
- { uint i;
- ds=0;
- i=103;
- while(i>0)i--;
- ds=1;
- i=4;
- while(i>0)i--;
- }
-
- bit tempreadbit(void) //讀一位數(shù)據(jù)函數(shù)
- { uint i;
- bit dat;
- ds=0;
- i++; //i++起延時作用
- ds=1;
- i++;
- i++;
- dat=ds;
- i=8;
- while(i>0)i--;
- return(dat);
- }
-
- uchar tempread(void) //讀1個字節(jié)數(shù)據(jù)函數(shù)
- { uchar i,j,dat;
- dat=0;
- for(i=1;i<=8;i++)
- { j=tempreadbit();
- dat=(j<<7)|(dat>>1);
- }
- return(dat);
- }
-
- void tempwritebyte(uchar dat) //向DS18B20寫一個字節(jié)數(shù)據(jù)函數(shù)
- { uint i;
- uchar j;
- bit testb;
- for (j=1;j<=8;j++)
- { testb=dat&0x01;
- dat=dat>>1;
- if (testb) //寫1
- { ds=0;
- i++;
- i++;
- ds=1;
- i=8;
- while(i>0)i--;
- }
- else
- { ds=0; //寫0
- i=8;
- while(i>0)i--;
- ds=1;
- i++;
- i++;
- }
- }
- }
-
- void tempchange(void) //DS18B20開始獲取溫度并進行轉(zhuǎn)換
- { dsreset(); //復(fù)位
- delay(1); //延時
- tempwritebyte(0xcc); //寫跳過讀ROM指令
- tempwritebyte(0x44); //寫溫度轉(zhuǎn)換指令
- }
-
- uint get_temp() //讀寄存器中的溫度
- {
- uchar m,n;
- dsreset(); //復(fù)位
- delay(5);
- tempwritebyte(0xcc);
- tempwritebyte(0xbe);
- m=tempread(); //讀低8位
- n=tempread(); //讀高8位
- temp=n;
- temp<<=8;
- temp=temp|m;
- f_temp=temp*0.0625;
- temp=f_temp*10+0.5;
- f_temp=f_temp+0.05;
- return temp; //temp是整型
- }
- //以下是鍵盤程序
- char kbscan() //鍵盤掃描
- {
- unsigned char hang,lie,key;
- P2=0x0f;
- if(P2!=0x0f)
- delay(1);
- if(P2!=0x0f)
- {
- switch(P2&0x0f)
- {
- case 0x0e:lie=0;break;
- case 0x0d:lie=1;break;
- case 0x0b:lie=2;break;
- case 0x07:lie=3;break;
- }
- P2=0xf0;
- P2=0xf0;
- switch(P2&0xf0)
- {
-
- case 0xd0:hang=1;break;
- case 0xb0:hang=2;break;
- case 0xe0:hang=0;break;
- }
- P2=0x0f;
- while(P2!=0x0f);
- key=tab[hang][lie];
- }
- else
- key=0;
- return (key);
- }
- //以下是lm016l的顯示程序
- void cls(unsigned char da) //LCD清屏
- {
- delay(1); //用延時代替檢測忙信號
- RS=0;
- RW=0;
-
- P0=da;
- E=1;
- E=0;
- }
-
- void write_com(unsigned char c) //寫入控制命令的子程序
- {
- int i;
- for(i=80;i>0;i--); //用延時代替忙檢測
- RS=0; //選擇寫命令模式
- RW=0; //選擇寫模式
- E=0;
- P0=c; //要寫的數(shù)據(jù)
- E=1; //給使能端一個高脈沖
- E=0;
- }
-
- void write_data(unsigned char d) //寫入數(shù)據(jù)的子程序
- {
- int i;
- for(i=80;i>0;i--);
- RS=1; //選擇讀命令模式
- RW=0; //選擇寫模式
- E=0;
- P0=d;
- E=1;
- E=0;
- }
-
- void realtemp(te)
- { uchar k;
- k=te/10;
- REAL[9]=k/10+48;
- REAL[10]=k%10+48;
- return;
- }
-
- void sett()
- {
- if(count==1)
- {
- SET[13]=kbscan();
- }
- else if(count==2)
- { SET[9]=kbscan();
- }
- else if(count==3)
- { SET[10]=kbscan();
- }
- else if(count==4)
- { SET[12]=kbscan();
- }
- SET[11]='-';
- return;
- }
- //主程序
- void main()
- {
- int i;
- char a,b;
-
- write_com(0X01); //顯示清零數(shù)據(jù)指針清零
- write_com(0X38); //設(shè)置16*2顯示5*7點陣8位數(shù)據(jù)接口
- write_com(0X0C); //設(shè)置開顯示不顯示光標
- write_com(0X06); //寫一個字符后地址指針自動加1
- cls(1); //初始化
-
- while(1)
- { tempchange(); //溫度轉(zhuǎn)換函數(shù)
-
- write_com(0x80); //顯示第一排
- if(P2!=0x0f)
- {
- if(count==4)
- { count=1;}
-
- else count=count+1;
- sett();
- }
- for(i=0;i<15;i++)
- {
- a=SET[i];
- write_data(a);
- }
-
- write_com(0xC0); //顯示第二排
- realtemp(get_temp());
- for(i=0;i<15;i++)
- { b=REAL[i];
- write_data(b);
- }
- if(A>C||C>W)
- {
- beep=1;
-
- }
- A=SET[9]*10+SET[10];
- W=SET[12]*10+SET[13];
- C=REAL[9]*10+REAL[10];
- if(A<C&&C<W) {beep=0;man=1;woman=1;}
- if(C<W){man=0;}
- else if(C>W){man=1;}
- if(C>A){woman=0;}
- else if(C<A){woman=1;}
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
原理圖及代碼.rar
(26.88 KB, 下載次數(shù): 154)
2018-4-28 20:54 上傳
點擊文件名下載附件
|