项目记录 / 基于AT89C51的环境检测系统
目錄
1,設計功能
2,硬件部分
3,軟件部分
4,成果展示
1,設計功能
1)設計的系統包括檢測模塊、主控模塊、顯示模塊、通信模塊和手機端。
2)檢測模塊為各傳感器,傳感器能對溫度、濕度、光照等因素進行檢測。
3)主控模塊負責對檢測模塊測得的數據進行處理和分析。
4)顯示模塊能實時顯示經主控處理分析后的數據信息。
5)通信模塊將主控處理分析后的數據信息傳輸至手機端。
2,硬件部分
2.1 總體框架
2.2 硬件選擇
2.2.1?溫濕度傳感器模塊
該系統在對環境進行實時檢測時,需同時實現對溫度與濕度的測量,此時,我們選用溫濕度傳感器會更為簡潔。在溫濕度傳感器中,我們選用了DHT11這款芯片,DHT11具有體積小、功耗低、響應速度快、抗干擾能力強、控制簡單、性價比高等優點,能夠廣泛應用于各個領域。
2.2.2?光敏傳感器模塊
在選用光敏電阻傳感器時,我們組傾向于選用能夠輸出開關量的器件,在本次設計中,我們選用的這款傳感器能夠通過調節電位器以改變閾值,且既能輸出數字量也可輸出模擬量。
2.2.3?液晶顯示屏模塊
在本次設計中,我們需要液晶顯示屏輸出更多的中文,所以為了更好的輸出中文,相較于LCD1602,我們更傾向于LCD12864。與LCD1602相比,LCD12864功耗更低,顯示內容更多,能更好的顯示漢字。
2.2.4?藍牙模塊
相較于zigbee,藍牙更易與手機進行通信。HC-05是主從一體式藍牙模塊,可執行指令多,操作簡單。
3,軟件部分
3.1 溫濕度傳感器
1)一次完整的數據傳輸為40bit,高位先出。
2)數據格式: 8bit濕度整數數據 + 8bit濕度小數數據 + 8bit溫度整數數據+8bit溫度小數數據 + 8bit校驗和。
3)數據傳送正確時,校驗和數據等于“8bit濕度整數數據 + 8bit濕度小數數據 + 8bit溫度整數數據 + 8bit溫度小數數據”所得結果的末8位。
主控發送一次開始信號后, DHT11從低功耗模式轉換到高速模式,等待主機開始信號結束后,DHT11發送響應信號,送出40bit的數據,并觸發一次信號采集,可選擇讀取部分數據。從模式下,DHT11接收到開始信號觸發一次溫濕度采集,如果沒有接收到主機發送開始信號,DHT11不會主動進行溫濕度采集。采集數據后轉換到低速模式。
DHT11的程序流程圖如下:
代碼:
//接收一個字節數據函數: uchar get_onebyte() {uchar j;uchar temp=0x00; //temp存放字節數據//每次讀1位,一共8位for(j=0;j<8;j++){temp<<=1; //讀完后左移1位,因為是從高位讀起while(dht11 == 0); //等待50us結束,開始收數據Delay_10us();Delay_10us();Delay_10us();if(dht11 == 1) //過了30us還為高電平,則該位為1{temp=temp+1;while(dht11 == 1); //等高電平的70us結束}//過了30us為低電平,則該位為0}return temp; //返回一個字節數據 }//接收全部數據函數: void get_data() {uchar i;//一共有5個字節數據for(i=0;i<5;i++){value[i]=get_onebyte(); //調用函數讀一個字節數據//累加前四個字節數據,為校驗做準備if(i != 4){check_value+=value[i];}}dht11=1; //拉高總線,進入空閑狀態//校驗,若前四個字節的累加數據不等于最后一個字節數據,則數據錯誤if(check_value != value[4]){RIGHT_DATA = 0; //令狀態變量為0} } //測量并讀取數據函數: void measure() {dht11=1; //空閑狀態Delay_1ms(1000);RIGHT_DATA = 1; //每次測量前狀態變量置1check_value=0x00; //每次測量前校驗數據清零dht11=0; //起始信號Delay_1ms(20); //拉低總線20ms啟動測量dht11=1; //釋放總線Delay_10us();Delay_10us();Delay_10us();Delay_10us(); //等待40us,檢查是否響應//總線未拉低,表示未響應if(dht11 == 1){humidity=0; //給全局變量寫0temperature=0;}//成功響應else {while(dht11 == 0); //等響應80us低電平while(dht11 == 1); //再等80us高電平,之后開始傳數據get_data(); //獲取數據//狀態變量為0,表示數據錯誤if(RIGHT_DATA == 0){humidity=1; 給全局變量寫1temperature=1;}//數據正常else{humidity=value[0]; //第一個字節為整數濕度數據temperature=value[2]; //第三個字節為整數溫度數據}}?3.2 光敏傳感器
光敏傳感器在環境光線亮度達不到設定閾值時,DO端輸出高電平,當外界環境光線亮度超過設定閾值時,DO 端輸出低電平。DO輸出端與單片機直接相連,通過單片機來檢測高低電平,由此來檢測環境的光線亮度改變,可以通過調節電位器來調節閾值。
光敏傳感器的程序流程圖如下:
光敏傳感器無單獨函數,在LCD函數和藍牙函數中的實現如下:
LCD//********光照********//light接收到高電平,表示光照正常,顯示Light_normalif(light == 1){dis_light(Light_normal);}//light接收到低電平,表示光照異常,顯示Light_dangerouselse{dis_light(Light_dangerous);} }藍牙//***********發送光照信息***********//先發送符號:LIGHT:for(cnt=0; cnt<7; cnt++){transmit_char((uchar)light_dat[cnt]);}//若light接收到高電平,表示光照正常,發送normal_datif(light == 1){for(cnt=0; cnt<8; cnt++){transmit_char((uchar)normal_dat[cnt]);}}//若light接收到低電平,表示光照異常,發送dangerous_datelse{for(cnt=0; cnt<16; cnt++){transmit_char((uchar)dangerous_dat[cnt]);}} }?3.3 液晶顯示模塊
寫時序:
讀時序:
?LCD12864程序流程圖如下:
代碼:
//LCD寫指令函數 void write_cmd(uchar cmd) {EN = 0; //使能為0RS = 0; //令RS=0,選擇寫指令功能RW = 0; //令RW=0,選擇寫LCD功能LCD_DATA = cmd; //把字節數據傳給LCD_DATA(P0)EN = 1; //使能為1,給LCD寫數據EN = 0;delay(5); } //LCD寫數據函數 void write_data(uchar dat) {EN = 0; //使能為0RS = 1; //令RS=1,選擇寫數據功能RW = 0; //令RW=0,選擇寫LCD功能LCD_DATA = dat; //把字節數據傳給LCD_DATA(P0)EN = 1; //使能為1,給LCD寫數據EN = 0;delay(5); } //LCD初始化函數 void lcd_init() {PSB = 1; //令PSB = 1,并行傳輸RST =0; //復位delay(250);delay(250);delay(250);delay(250);RST =1; //恢復正常delay(250);delay(250);delay(250);delay(250);//寫一系列指令,完成清屏等操作write_cmd(0x30); write_cmd(0x30); write_cmd(0x06); write_cmd(0x08); write_cmd(0x34); write_cmd(0x34); write_cmd(0x03); } //溫濕度測量未響應時,顯示“XXXXX”函數 void dis_wrong(uchar code *WRONG) {uchar cnt;//標準化操作write_cmd(0x30); write_cmd(0x30); write_cmd(0x0C); //寫LCD第一行write_cmd(0x80);for(cnt=0;cnt<14;cnt++){write_data((uchar)*WRONG);WRONG++; //指針加一}//寫LCD第二行write_cmd(0x90);for(cnt=0;cnt<14;cnt++){write_data((uchar)*WRONG);WRONG++; //指針加一} } //溫濕度數據正常時,顯示Hum_Tem函數 void dis_hum_tem(uchar code *Hum_Tem) {uchar cnt;//標準化操作write_cmd(0x30); write_cmd(0x30); write_cmd(0x0C); //寫LCD第一行write_cmd(0x80);for(cnt=0;cnt<10;cnt++){write_data((uchar)*Hum_Tem);Hum_Tem++; //指針加一}//寫濕度數據write_data(hum_ten); write_data(hum_bit);//寫濕度單位write_data((uchar)*Hum_Tem); Hum_Tem++;//寫LCD第二行write_cmd(0x90);for(cnt=0;cnt<10;cnt++){write_data((uchar)*Hum_Tem);Hum_Tem++;}//寫溫度數據write_data(tem_ten); write_data(tem_bit);//寫溫度單位write_data((uchar)*Hum_Tem); Hum_Tem++;write_data((uchar)*Hum_Tem); } //顯示光照信息函數 void dis_light(uchar code *Light_) {uchar cnt;//寫LCD第三行write_cmd(0x88);for(cnt=0;cnt<14;cnt++){write_data((uchar)*Light_);Light_++; //指針加一} } //顯示收到的數據函數 void dis_receive(uchar code *Receive_) {uchar cnt;//寫LCD第四行write_cmd(0x98);for(cnt=0;cnt<10;cnt++){write_data((uchar)*Receive_);Receive_++; //指針加一} } //傳入溫濕度數據,調用上述函數顯示在LCD上 void display(uint HUM, uint TEM) {//*******濕度和溫度********//HUM和TEM為0,表示測量響應失敗if(HUM == 0 && TEM == 0){CRAM_OFF();dis_error(ERROR);}//HUM和TEM為1,表示測量數據錯誤else if(HUM == 1 && TEM == 1){CRAM_OFF();dis_wrong(WRONG);}//數據正常else{hum_ten = HUM/10 + 0x30; //濕度十位數hum_bit = HUM%10 + 0x30; //濕度個位數tem_ten = TEM/10 + 0x30; //溫度十位數tem_bit = TEM%10 + 0x30; //溫度個位數CRAM_OFF();dis_hum_tem(Hum_Tem);}//********光照********//light接收到高電平,表示光照正常,顯示Light_normalif(light == 1){dis_light(Light_normal);}//light接收到低電平,表示光照異常,顯示Light_dangerouselse{dis_light(Light_dangerous);} } //傳入收到的數據,顯示在LCD上 函數 void display_receive(uchar NULL, uchar RECEIVE) {//先顯示標題:“收到”dis_receive(Receive_);//有收到數據,顯示數據if(NULL == 0){write_data(RECEIVE);}//未收到數據,顯示“無”else{write_data(Receive_[10]);write_data(Receive_[11]);} }?3.4 藍牙模塊
藍牙模塊共有兩種模式,第一種是AT指令模式:藍牙RX和TX連接芯片的RX和TX;
第二種是普通模式:藍牙RX和TX連接芯片的TX和RX。我們設置波特率為9600。
寫SBUF,發送數據;讀SBUF,接收數據。根據TI和RI判斷數據收發情況。然后根據ASCII碼表來收發數據。一次發送或者接收一個字節(8位)數據。
藍牙HC-05程序流程圖如下:
代碼:
//串口初始化 void uart_init() {SCON=0x50; //設置串口為工作方式1(UART)TMOD=0x20; //設置定時器1為工作方式2(8位自動重裝載定時器)PCON=0x00; //波特率不加倍TH1=0xfd; //定時器1初始值設置,波特率為9600TL1=0xfd;TR1=1; //打開定時器 } //發送一個字節 void transmit_char(uchar character) {TI=0; //令TI=0,給發送數據做準備SBUF=character; //將數據寫給SBUFwhile(!TI); //等待發送結束TI=0; //給TI置零,為下一次發送做準備 } //將濕度、溫度、光照信息通過串口發給藍牙,手機接收函數 void transmit(uint HUM, uint TEM) {uchar cnt;//***********發送濕度和溫度***********//HUM和TEM為0,表示測量響應失敗,發送error_datif(HUM == 0 && TEM == 0){for(cnt=0; cnt<12; cnt++){transmit_char((uchar)error_dat[cnt]);}}//HUM和TEM為1,表示測量數據有誤,發送wrong_datelse if(HUM == 1 && TEM == 1){for(cnt=0; cnt<12; cnt++){transmit_char((uchar)wrong_dat[cnt]);}}//數據正常,發送數據else{transmit_char('R');transmit_char('H');transmit_char(':');transmit_char(' ');transmit_char(hum_ten); //LCD文件的全局變量hum_ten和hum_bittransmit_char(hum_bit);transmit_char('%');transmit_char(' ');transmit_char(' ');Delay_1ms(100);transmit_char('T');transmit_char(':');transmit_char(' ');transmit_char(tem_ten); //LCD文件的全局變量tem_ten和tem_bittransmit_char(tem_bit);transmit_char(' ');transmit_char(' ');}Delay_1ms(100);//***********發送光照信息***********//先發送符號:LIGHT:for(cnt=0; cnt<7; cnt++){transmit_char((uchar)light_dat[cnt]);}//若light接收到高電平,表示光照正常,發送normal_datif(light == 1){for(cnt=0; cnt<8; cnt++){transmit_char((uchar)normal_dat[cnt]);}}//若light接收到低電平,表示光照異常,發送dangerous_datelse{for(cnt=0; cnt<16; cnt++){transmit_char((uchar)dangerous_dat[cnt]);}} } //接收手機發來的字節數據函數 void receive() {uchar None = 0; //None為0表示收到數據,為1表示無數據uchar receive_dat = 0; //receive_dat保存接收的字節數據//接收到數據if(RI == 1){receive_dat = SBUF; //讀SBUF接收到的數據Delay_10us(); //延時等待接收結束RI = 0; //給RI置零,為下一次接收做準備}//未接收到數據else{None = 1; //令None=1}display_receive(None, receive_dat); //調用LCD顯示 }?
4,成果展示
?
?接收:
總結
以上是生活随笔為你收集整理的项目记录 / 基于AT89C51的环境检测系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS内存管理—MRC
- 下一篇: 7-6 数据结构实验之链表七:单链表中重