基于51单片机的温度甲烷监测报警串口上报proteus仿真原理图PCB
生活随笔
收集整理的這篇文章主要介紹了
基于51单片机的温度甲烷监测报警串口上报proteus仿真原理图PCB
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
功能介紹:
0.本系統采用STC89C52作為單片機
1.LCD1602液晶實時顯示當前溫度和甲烷濃度
2.超過甲烷濃度閾值,蜂鳴器報警
3.按鍵可更改甲烷濃度閾值上限和啟動/暫停檢測
4.0`20%濃度,綠色LED點亮
20%~閾值上限,黃色LED點亮,電機啟動
超過閾值上限,紅色LED點亮,電機啟動,蜂鳴器報警
5.每隔2天,電機轉動10分鐘(為了方便演示,演示視頻為間隔20秒)
6.采用DC002作為電源接口可直接輸入5V給整個系統供電
原理圖:
PCB :
主程序:
#include <reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義 #include <stdio.h> #include "18b20.h" #include "tlc0832.h" #include "lcd1602.h" #include "delay.h"sbit KEY_SUB = P3^6; sbit KEY_ADD = P3^4; sbit KEY_ALARM = P3^5;sbit BUZZER = P2^2; sbit MOTOR = P3^7;sbit LED_RED = P1^5; sbit LED_YELLOW = P1^4; sbit LED_GREEN = P1^3;#define ON 0 #define OFF 1#define BUZZER_ON (BUZZER = 0) #define BUZZER_OFF (BUZZER = 1)#define MOTOR_ON (MOTOR = 0) #define MOTOR_OFF (MOTOR = 1)unsigned char dispFlag = 0; //更新顯示標志 bit setFlag = 0; //設置參數標志 bit sendFlag = 0; //串口發送標志 bit alarmSwitch = 1; //報警開關 bit alarmFlag = 1; //報警標志 bit motorFlag = 0; //報警開啟電機標志 bit motorFlag1 = 1; //定時開啟電機標志 unsigned int second = 0; unsigned char hour = 0;int tempBuf = 0; //讀取溫度值 float temperature; //實際溫度值 int temperatureMax = 50; //溫度閾值 bit readTempFlag = 0; //定義讀溫度標志int Conc = 0; unsigned int ConcMax = 50;char dis0[18]; //定義顯示區域臨時存儲數組void SendData(void); void CheckKey(void); void Timer0_Init(void); //定時器初始化 void UART_Init(void); //串口初始化 void UART_SendByte(unsigned char dat); //串口發送單字節數據 void UART_SendStr(unsigned char *s, unsigned char length); //發送定長度字符串void main(void) {bit ack = 0;Timer0_Init();LCD_Init(); //初始化液晶DelayMs(200); //延時有助于穩定LCD_Clear(); //清屏LCD_DispStr(0, 0, "T: C S: %");LCD_DispOneChar(7, 0, 0xdf); //寫入溫度右上角點sprintf(dis0, "SS:%3d%%", ConcMax); //打印溫度值LCD_DispStr(0, 1, dis0); //顯示第二行UART_Init(); //初始化串口while (1) //主循環{CheckKey(); //檢測按鍵if (readTempFlag == 1) //讀取溫度標志{readTempFlag = 0;DS18B20_Start();ack = DS18B20_GetTemp(&tempBuf);if (ack == 1){temperature = (float)tempBuf * 0.0625; //溫度值轉換}else {temperature = 0;}}if (dispFlag == 1){dispFlag = 0;sprintf(dis0, "%5.1f", temperature); //打印溫度值LCD_DispStr(2, 0, dis0); //顯示第二行Conc = ReadADC(AIN0_GND);if (Conc <= 29){Conc = 29;}Conc = (100 * (Conc - 29)) / 227; //計算有害氣體濃度百分比sprintf(dis0, "%3d", Conc); //打印溫度值LCD_DispStr(12, 0, dis0); //顯示第二行if (alarmSwitch){if (Conc > ConcMax) //濃度超過最大設定則報警{BUZZER_ON;motorFlag = 1;LED_RED = ON;LED_YELLOW = OFF;LED_GREEN = OFF;alarmFlag = 1;}else if (Conc > 20 && Conc <= ConcMax) //濃度處于中間范圍{BUZZER_OFF;motorFlag = 1;LED_RED = OFF;LED_YELLOW = ON;LED_GREEN = OFF;alarmFlag = 0;}else //濃度正常范圍{BUZZER_OFF;motorFlag = 0;LED_RED = OFF;LED_YELLOW = OFF;LED_GREEN = ON;alarmFlag = 0;}}if (motorFlag == 1 || motorFlag1 == 1){MOTOR_ON;}else{MOTOR_OFF;}}if (sendFlag == 1){sendFlag = 0;SendData();}} }/************************* 串口發送數據 *************************/ void SendData(void) {sprintf(dis0, "T:%5.1f'C S:%3d%%\r\n", temperature, Conc); //串口發送UART_SendStr(dis0, 18); //發送數據DelayMs(100);if (alarmFlag == 1){UART_SendStr("Warning!!!\r\n", 12); //發送數據DelayMs(100);} }void CheckKey(void) {if (KEY_SUB == 0) //減鍵按下{DelayMs(200);if (KEY_SUB == 0) //減鍵按下{if (ConcMax > 20){ConcMax = ConcMax - 1;}sprintf(dis0, "SS:%3d%%", ConcMax);LCD_DispStr(0, 1, dis0);}}if (KEY_ADD == 0) //加鍵按下{DelayMs(200);if (KEY_ADD == 0) //加鍵按下{if (ConcMax < 99){ConcMax = ConcMax + 1;}sprintf(dis0, "SS:%3d%%", ConcMax);LCD_DispStr(0, 1, dis0);}}if (KEY_ALARM == 0) //取消報警按鍵{DelayMs(20);if (KEY_ALARM == 0) //取消報警按鍵{if (alarmSwitch){alarmSwitch = 0;BUZZER_OFF;LED_RED = OFF;LED_YELLOW = OFF;LED_GREEN = OFF;}else{alarmSwitch = 1;}}while (KEY_ALARM == 0);} }/*------------------------------------------------定時器初始化子程序 ------------------------------------------------*/ void Timer0_Init(void) {TMOD |= 0x01; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響TH0 = (65536 - 18432) / 256; //重新賦值 20msTL0 = (65536 - 18432) % 256;EA = 1; //總中斷打開ET0 = 1; //定時器中斷打開TR0 = 1; //定時器開關打開 } /*------------------------------------------------定時器中斷子程序 ------------------------------------------------*/ void Timer0_Interrupt(void) interrupt 1 {static unsigned char time20ms = 0;TH0 = (65536 - 18432) / 256; //重新賦值 20msTL0 = (65536 - 18432) % 256;time20ms++;if (time20ms > 50){time20ms = 0;readTempFlag = 1; //讀標志位置1sendFlag = 1;if (motorFlag1 == 0) //電機停止狀態{if (second >= 20 - 1) //1小時{second = 0;hour++;if (hour >= 2 - 1) //48小時{hour = 0;motorFlag1 = 1; //電機啟動標志}}else{second++;}}else{if (second >= 20 - 1) //10分鐘{second = 0;motorFlag1 = 0;}else{second++;}}}if (time20ms % 10 == 0){dispFlag = 1;} }/************************* 串口配置 *************************/ void UART_Init(void) {SCON = 0x50;TH2 = 0xFF;TL2 = 0xFD;RCAP2H = 0xFF; //(65536-(FOSC/32/BAUD)) BAUD = 115200 FOSC = 11059200RCAP2L = 0xFD;/*****************/TCLK = 1;RCLK = 1;C_T2 = 0;EXEN2 = 0;/*****************/TR2 = 1;ES = 0; //關閉串口中斷EA = 1; //打開總中斷}/************************* 串口發送字節 *************************/ void UART_SendByte(unsigned char dat) //串口發送單字節數據 {unsigned char time_out;time_out = 0;SBUF = dat; //將數據放入SBUF中while ((!TI) && (time_out < 100)) //檢測是否發送出去{time_out++;DelayUs10x(2);} //未發送出去 進行短暫延時TI = 0; //清除ti標志 }/************************* 串口發送字符串 *************************/ void UART_SendStr(unsigned char *s, unsigned char length) {unsigned char num;num = 0x00;while (num < length) //發送長度對比{UART_SendByte(*s); //放松單字節數據s++; //指針++num++; //下一個++} }仿真演示視頻:
https://www.bilibili.com/video/BV1514y1h7eT/
實物演示視頻:
https://www.bilibili.com/video/BV1uN4y1A7B5/
總結
以上是生活随笔為你收集整理的基于51单片机的温度甲烷监测报警串口上报proteus仿真原理图PCB的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 嵌入式设备的通讯--秉火STM32学习笔
- 下一篇: c语言阶乘编程题,C语言编程题:阶乘计算