用1602LCD與DS18B20設計的溫度報警器仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #include <reg51.h>//頭文件,52單片機改為52
- #include <intrins.h>
- #define LCD_DATA P0
- sbit LCD_RS = P2^0;
- sbit LCD_RW = P2^1;
- sbit LCD_EN = P2^2;
- unsigned char dispBuff0[16]={'T','E','M',
- 'P',':',' ',' ',' ',' ',' ',' ','C',' ',' ',' ',};//LCD第一行顯示
- unsigned char dispBuff1[16]={'D','E','N',
- 'S',':',' ',' ','%',' ',' ',' ',' ',' ',' ',' ',};//LCD第二行顯示
- sbit DQ=P2^3; //DS18B20數據端
- unsigned int temperature=0;//溫度
- unsigned char fuhao=0;//溫度的正負符號
- //AD0809的IO口以及變量定義
- sbit OE=P2^7;
- //sbit ALE=P3^0;
- sbit EOC=P2^6;
- sbit START=P3^0;
- unsigned char density=0;//濃度
- //LED報警指示的IO口以及變量定義
- sbit LED1=P2^4;//溫度報警指示
- sbit LED2=P2^5;//濃度報警指示
- #define off 1 //高電平時燈為關閉狀態
- #define on 0 //低電平時燈為開啟狀態
- sbit speaker=P3^1;//蜂鳴器
- void Delay20ms() ;
- void LCD_WriteDat(unsigned char lcd_dat);
- void LCD_WriteCmd(unsigned char lcd_cmd);
- unsigned char LCD_ReadStatus(void);
- void LCD_Goto(unsigned char x,unsigned char y);
- void LCD_Display(unsigned char row,unsigned char *str);
- void delay(unsigned int x)//延時公用程序
- {
- unsigned char j;
- while(x--)
- {
- for(j=0;j<125;j++);
- }
- }
- /*1、LCD模塊子函數*/
- void LCD_Init(void)
- {
- Delay20ms();
- /*************************************************
- 功能設置: DB5=1;DB6...=0;
- DB4=1:8位接口; 0:4位接口;
- DB3=1:雙行顯示;0:單行顯示;
- DB3=1:5×10點陣;0:5×7點陣;
- *************************************************/
- LCD_WriteCmd(0x38); //8位機接口、雙行顯示、5×7字符點陣;
- /*************************************************
- 顯示控制:DB3=1;DB4...=0;
- DB2=1:開啟顯示;0:關閉LCD顯示;
- DB1=1:顯示光標;0:光標隱藏;
- DB0=1:光標閃爍;0:光標閃爍關閉;
- *************************************************/
- LCD_WriteCmd(0x0c); //顯示開啟、光標不顯示也不閃爍;
- /*************************************************
- 清屏指令:DB0=1;DB1...=0;
- *************************************************/
- LCD_WriteCmd(0x01); //清屏;
- /****************************************************************
- 訪問模式:DB2=1;DB3...=0;
- DB1=1:對內部Ram讀寫后AC自增,否則自減;
- DB0=1:與DB1設置有關,對DD RAM寫時同時整屏移動1位;
- *****************************************************************/
- LCD_WriteCmd(0x06); //光標右移一位、整屏不移動;
-
- LCD_Goto(0,0);
- }
- void LCD_WriteDat(unsigned char lcd_dat)
- {
- unsigned char tmp;
- tmp = LCD_ReadStatus(); //讀狀態;
- while((tmp & 0x80)) //是否忙 ?
- {
- tmp = LCD_ReadStatus();
- }
-
- LCD_RS = 1;
- LCD_RW = 0;
- LCD_DATA = lcd_dat;
- _nop_();
- LCD_EN = 0;
- _nop_();
- _nop_();
- LCD_EN = 1;
-
- }
- void LCD_WriteCmd(unsigned char lcd_cmd)
- {
- unsigned char tmp;
- tmp = LCD_ReadStatus();
- while((tmp & 0x80))
- {
- tmp = LCD_ReadStatus();
- }
-
- LCD_RS = 0;
- LCD_RW = 0;
- LCD_DATA = lcd_cmd;
- _nop_();
- LCD_EN = 0;
- _nop_();
- _nop_();
- LCD_EN = 1;
- }
- unsigned char LCD_ReadStatus(void)
- {
- unsigned char tmp;
- #if 0
- LCD_RS = 0;
- LCD_RW = 1;
- LCD_EN = 1;
- tmp = LCD_DATA;
- LCD_EN = 0;
- #endif
- LCD_DATA = 0xff;
- LCD_RS = 0;
- LCD_RW = 1;
- LCD_EN = 0;
- _nop_();
- _nop_();
- LCD_EN = 1;
- tmp = LCD_DATA;
- return tmp;
- }
- void LCD_Goto(unsigned char x,unsigned char y)
- {
- unsigned char tmp;
- if(y) //若是第二行;
- {
- tmp = 0xc0 + x;
- LCD_WriteCmd(tmp);
- }
- else
- {
- tmp = 0x80 + x;
- LCD_WriteCmd(tmp);
- }
- }
-
- void LCD_Display(unsigned char row,unsigned char *str)
- {
- if(row)
- {
- LCD_Goto(0,1);
- }
- else
- {
- LCD_Goto(0,0);
- }
- while(*str != '\0')
- {
- LCD_WriteDat(*str++);
- }
- }
- void Delay20ms() //粗略延時;
- {
- unsigned int tmp = 50000;
- while(tmp--);
- }
-
- /*2、DS18B2模塊*/
- void delay_18B20(unsigned int i)
- {
- while(i--);
- }
- /**********ds18b20初始化函數**********************/
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1; //DQ復位
- delay_18B20(2); //稍做延時
- DQ = 0; //單片機將DQ拉低
- delay_18B20(60); //精確延時 大于 480us
- DQ = 1; //拉高總線
- delay_18B20(2);
- x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
- delay_18B20(15);
- }
- /***********ds18b20讀一個字節**************/
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 給脈沖信號
- dat>>=1;
- DQ = 1; // 給脈沖信號
- if(DQ)
- dat |=0x80;
- delay_18B20(4);
- }
- return(dat);
- }
- /*************ds18b20寫一個字節****************/
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay_18B20(2);
- DQ = 1;
- dat>>=1;
- }
- }
- void ReadTemperature(void)
- {unsigned char readdata[2]={0,0};
- fuhao=0;
- temperature=0;
- delay_18B20(40); // this message is very important
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳過讀序號列號的操作
- WriteOneChar(0x44); // 啟動溫度轉換
- delay_18B20(40); // this message is wery important
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
- delay_18B20(40);
- readdata[0]=ReadOneChar(); //讀取溫度值低位
- readdata[1]=ReadOneChar(); //讀取溫度值高位
- if (readdata[1]>127)
- {readdata[0]^=0xff;//求補碼
- readdata[1]^=0xff;
- fuhao=1;//符號為“-”
- }
- temperature =readdata[1]*256+readdata[0] ;
- temperature =temperature*0.625+0.5 ;//放大了10倍
- }
- /*3、AD模塊*/
- void AD0809()//0809轉換數據
- {
- START=0;_nop_();
- START=1;_nop_();
- START=0;_nop_();
- while(EOC==0);
- OE=1;_nop_();
- density=P1;_nop_();
- OE=0;
- }
- void timer0() interrupt 1 //這里輸出蜂鳴器信號
- {TH0=254;//頻率為1600hz時計時器初值
- TL0=200;
- speaker=!speaker;
- }
- void main()
- {unsigned char DEN=0;
- LCD_Init();//初始化LCD
- /*計時器0設置*/
- TMOD=0x11;//定時器1、2工作于方式1
- TH0=254;//頻率為1600hz時計時器初值
- TL0=200;
- ET0=1;
- EA=1;
- speaker=1;
- while(1)
- {
- /*LCD第一行顯示溫度*/
- ReadTemperature();//讀取溫度值
-
- if (fuhao)
- {dispBuff0[5]='-';}
- else
- {dispBuff0[5]='+';}
- dispBuff0[6]=(temperature/1000)%10+'0';//溫度值百位
- dispBuff0[7]=(temperature/100)%10+'0';//溫度值十位
- dispBuff0[8]=(temperature/10)%10+'0';//溫度值個位
- dispBuff0[9]='.';
- dispBuff0[10]=(temperature)%10+'0';//溫度值小數點后一位;
- /*LCD第2行顯示濃度*/
- AD0809();//ad轉換,濃度
- DEN=(density*100/256);
- dispBuff1[5]=(DEN/10)%10+'0';//濃度值十位
- dispBuff1[6]=(DEN/1)%10+'0';//濃度值個位
- LCD_Display(0,dispBuff0);//LCD第一行顯示
- LCD_Display(1,dispBuff1);//LCD第二行顯示
- delay(20);
- /*報警程序*/
- if (temperature>=400 && !fuhao)//溫度大于40攝氏度
- {LED1=on;}
- else
- {LED1=off;}
- if (density>=50)//濃度大于50
- {LED2=on;}
- else
- {LED2=off;}
- if (temperature>=400 && !fuhao && DEN>=50)//響蜂鳴器
- {TR0=1;}
- else
- {TR0=0;}
- }//while
- }//main
復制代碼
所有資料51hei提供下載:
DS18B20溫度傳感器和MQ2煙霧傳感器的火災報警器設計.rar
(95.25 KB, 下載次數: 169)
2018-11-28 20:11 上傳
點擊文件名下載附件
|