沒有仿真,但是程序跑實物運行了,可以借鑒部分代碼測試哦,附帶原理圖
1. 整體設計 設計由stm32f103c8t6單片機為控制核心
2. 液晶顯示 單片機通過iic接口(pa6、pa7)與oled12864的液晶顯示屏(scl、sda)連接,驅動液晶數據和閾值。
3. Ds18b20溫度傳感器 Ds18b20溫度傳感器是單總線接口,把數據端接到單片機的pb9管腳,通過傳感器協議讀取溫度值。
4. Mq2煙霧傳感器 Mq2傳感器輸出模電壓會隨著煙霧濃度的增大而增大。單片機通過模擬量采集管腳PA0采集mq2傳感器輸出的電壓值,然后單片機通過計算把0-vcc電壓轉化成0-100%煙霧濃度。
5. 火焰傳感器傳感器 火焰傳感器是數字量do輸出,當檢測到有明火時輸出低電平0,無明火時輸出高電平1。單片機通過io口pa6讀取火焰傳感器狀態。
6. 蜂鳴器驅動控制 如果蜂鳴器接電源3.3v和地,蜂鳴器有電就會發聲。1k電阻是限流電阻。單片機通過控制pa7管腳輸出高低電平,從而達到控制風扇轉動的效果。單片機輸出高電平1時,三極管導通,蜂鳴器接地,蜂鳴器響。輸出低電平0時,三極管截至不導通,蜂鳴器沒有接地,蜂鳴器不響。
7. 按鍵 單片機io口接按鍵,按鍵按下的接地。Io口讀取到低電平0,按鍵松開時,由于單片機有內置上拉電阻,Io口讀取到高電平1。其他兩個按鍵原理一樣。
8. Gsm短信模塊 Sim900a gsm短信模塊是通過串口通訊的,將單片機串口1發送端pa9接到gsm模塊的接收端rxd,然后單片機通過at指令控制gsm模塊發送短信。
9. Esp8266wifi模塊  8266是串口控制得模塊,單片機通過串口1(pa9和pa10)與wifi模塊通訊,從而控制wifi模塊工作。首先wifi模塊上電自動連接熱點,然后連接onenet云平臺得ip地址,通過mqtt協議登錄云平臺設備,訂閱app(訂閱了才能接收到app下發得信息)。單片機會定時上傳數據(以mcu得身份發布數據)到onenet云平臺,在app訂閱了mcu設備得前提下,云平臺接收到單片機上傳得數據后會自動轉發到app顯示。反之app下發數據過程也一樣。
單片機源程序如下:
- #include "stm32f10x.h" //頭文件
- #include "./usart/bsp_usart1.h"
- #include "./OLED_I2C/OLED_I2C.h"
- #include "./delay/delay.h"
- #include "adc.h"
- #include "string.h"
- #include "bsp_ds18b20.h"
- #include "./TIMER/timer.h"
-
- #define Speaker PAout(7)//pa7接蜂鳴器
- #define Key1 PBin(12)//按鍵
- #define Key2 PBin(13)//按鍵
- #define Key3 PBin(14)//按鍵
- #define HY PAin(6)//火焰傳感器
-
- TIM_TimeBaseInitTypeDef TIM3_TimeBaseStructure;
- TIM_OCInitTypeDef TIM3_OCInitStructure;
-
- void DelayStm32(__IO u32 nCount)
- {
- for(; nCount != 0; nCount--);
- }
- u16 Time_1MS=0;
- u16 TX_10MS=0;
- u16 A0Value = 0; //煙霧值
- u16 Ds18b20Value; //溫度
- u16 Cnt=0;
- u8 AlarmT=35; //溫度閾值
- u8 AlarmM=60; //煙霧閾值
- char dispBuff[10];
- u8 FlagUpData = 0;
- u8 FlagFS = 0; //風扇手動標志位
- u8 FlagDelayA = 0; //繼電器手動標志位
- u8 StateDelayA = 0; //繼電器狀態
- u8 StateFS = 0; //風扇狀態
- u8 Stm32[17];
- u16 KeyCnt = 0;
- u8 FlagSet=0; //按鍵設置標志位
- u8 FlagAlarm=0; //告警標志位
- u8 RxBuf1[32];
- u8 RxBuf2[32];
- u8 RxBuf3[32]; //串口3數據緩存
- u8 pass[11];
- /**********************MQTTdata***********************/
- char MqttDataDL[37]=
- {
- 0x10, 0x23, 0x00, 0x04, 0x4D, 0x51, 0x54, 0x54, 0x04, 0xC0,
- 0x00, 0x78, 0x00, 0x0A, 0x31, 0x30, 0x36, 0x35, 0x36, 0x30,
- 0x31, 0x35, 0x35, 0x39, 0x00, 0x06, 0x35, 0x38, 0x39, 0x35,
- 0x35, 0x34, 0x00, 0x03, 0x6D, 0x63, 0x75
-
- };//mqtt登錄數組
- char MqttDataDY[10]=
- {
- 0x82, 0x08, 0x00, 0x02, 0x00, 0x03, 'a', 'p', 'p', 0x00
- };//mqtt訂閱數組
- char MqttDataFB[24]=
- {
- 0x30, 0x16, 0x00, 0x03, 0x6D, 0x63, 0x75, 0x06, 0x06, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
- };//mqtt發布數組
- void SendASC1(u8 d) //串口1發送一個字節
- {
- USART_SendData(USART1, d);
- while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
- }
-
- void SendASC2(u8 d) //串口2發送一個字節
- {
- USART_SendData(USART2, d);
- while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
- }
- void SendASC3(u8 d)
- {
- USART_SendData(USART3, d);
- while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
- }
- void DengLu(void) //mqtt登錄函數
- {
- u8 k=0;
- printf("AT+CIPSEND=37\r\n");
- DelayS(1);
- for(k=0; k<37; k++)
- {
- SendASC1(MqttDataDL[k]);
- }
- }
- void DingYue(void) //mqtt訂閱函數
- {
- u8 k=0;
- printf("AT+CIPSEND=10\r\n");
- DelayS(1);
- for(k=0; k<10; k++)
- {
- SendASC1(MqttDataDY[k]);
- }
- }
- void FaBu(void) //mqtt發布函數
- {
- u8 k=0;
- printf("AT+CIPSEND=24\r\n");
- DelayS(1);
- for(k=0; k<24; k++)
- {
- SendASC1(MqttDataFB[k]);
- }
- }
- /*************************************************/
- void GPIO_Config(void) //io口配置
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- /* GPIOA and GPIOA clock enable */ //pb8、pb12、pb13、pb14設置為輸入
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
- GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8 |GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
-
- /* GPIOA and GPIOA clock enable */ //pa6設置為輸入
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
-
- /* GPIOA and GPIOA clock enable */ //pa7.pa4配置為推免輸出
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- /* GPIOA and GPIOA clock enable */ //pc13配置為推免輸出
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
-
- }
-
- void DispOled(void)//液晶顯示函數
- {
- //顯示溫度和閾值
- sprintf(dispBuff,"WenDu=%d%d.%dC %d%dC", Ds18b20Value %1000/100, Ds18b20Value%100/10, Ds18b20Value%10, AlarmT%100/10, AlarmT%10);
- OLED_ShowStr(0,0,dispBuff,2);
- //顯示煙霧和閾值
- sprintf(dispBuff,"YanWu = %0.2d%% %0.2d%%",A0Value,AlarmM);
- OLED_ShowStr(0,2,dispBuff,2);
- //顯示接收短信的號
- sprintf(dispBuff,"%d%d%d%d%d%d%d%d%d%d%d",pass[10],pass[9],pass[8],pass[7],pass[6],pass[5],pass[4],pass[3],pass[2],pass[1],pass[0]);
- OLED_ShowStr(0,6,dispBuff,2);
-
- }
- void SendDx(void) //發送短信函數
- {
- Uart3_printf("AT+CSCS=\"GSM\"\r\n");
- DelayS(1);
- Uart3_printf("AT+CMGF=1\r\n");
- DelayS(1);
- /*******************************************************/
- //printf("AT+CMGS=\"18xxxxxxxx\"\r\n");
- Uart3_printf("AT+CMGS=\""); //按設置的號碼發送短信
- SendASC3(pass[10]+0x30);
- SendASC3(pass[9]+0x30);
- SendASC3(pass[8]+0x30);
- SendASC3(pass[7]+0x30);
- SendASC3(pass[6]+0x30);
- SendASC3(pass[5]+0x30);
- SendASC3(pass[4]+0x30);
- SendASC3(pass[3]+0x30);
- SendASC3(pass[2]+0x30);
- SendASC3(pass[1]+0x30);
- SendASC3(pass[0]+0x30);
- Uart3_printf("\"\r\n");
- /*******************************************************/
- DelayS(1);
- Uart3_printf("Have a Fire!!!"); //發送短信的內容
- DelayS(1);
- SendASC3(0x1A); //啟動發送短信
- DelayS(1);
- }
- int main(void) //主函數
- {
- USART1_Config(); //串口初始化
- GPIO_Config();//io口初始化
- Adc_Init();//ad初始化
- DelayInit(); //定時函數初始化
- Speaker = 0;//關閉輸出設備
- I2C_Configuration();//iic初始化
- OLED_Init();//液晶初始化
- OLED_Fill(0xFF);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- printf("AT\r\n");
- DelayS(1);
- printf("AT\r\n");
- DelayS(1);
- printf("AT\r\n");
- DelayS(1);
- printf("AT+CWMODE=3\r\n"); //8266設置為模式3
- DelayS(1);
- printf("AT+CWJAP=\"win\",\"123123123\"\r\n"); //連接熱點
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- while(DS18B20_Init()); //溫度初始化
- DelayS(1);
- Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10); //上電連續讀取幾次溫度值使其穩定
- DelayStm32(0xFFFFF);
- Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10);
- DelayStm32(0xFFFFF);
- Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10);
- DelayStm32(0xFFFFF);
- Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10);
- DelayStm32(0xFFFFF);
- Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10);
- DelayStm32(0xFFFFF);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- /*******************************************************/
- printf("AT+CIPSTART=\"TCP\",\"183.230.x.x\",6002\r\n"); //連接云平臺ip和端口號
- /*******************************************************/
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DengLu(); //調用mqtt登錄函數
- DelayS(1);
- DelayS(1);
- DelayS(1);
- DingYue(); //調用mqtt訂閱函數
- DelayStm32(0xFFFFF);
- OLED_Fill(0x00);
- DelayStm32(0xFFFFF);
- TIM4_Int_Init(9,7199); //定時器初始化
- while(1)
- {
- Ds18b20Value = (u16)(DS18B20_GetTemp_SkipRom ( )*10);//讀取穩定
- A0Value = (Get_Adc_Average(0,20)*100/4096);//讀取煙霧
- DispOled(); //調用顯示函數
- MqttDataFB[10] = Ds18b20Value/100; //把要上傳得數據填進mqtt發布數據
- MqttDataFB[11] = Ds18b20Value%100/10;
- MqttDataFB[12] = Ds18b20Value%10;
- MqttDataFB[13] = A0Value;
- MqttDataFB[14] = 0;
- MqttDataFB[15] = 0;
- MqttDataFB[16] = FlagAlarm;
-
- if(FlagUpData==1) //上傳數據時間到,上傳數據
- {
- FlagUpData = 0;
- FaBu(); //發布數據
- }
-
-
- if( (Ds18b20Value>(AlarmT*10))||(A0Value>AlarmM)||(HY) ) //如果溫度或者煙霧大于閾值或者有火焰
- {
- Speaker = 1; //蜂鳴器響
- if(FlagAlarm==0) //每個告警值發送一次短信
- {
- SendDx(); //調用發送短信函數
- }
- FlagAlarm = 1;
- }
- else
- {
- FlagAlarm = 0;
- Speaker = 0;
- }
-
-
- if(!Key1) //按鍵1
- {
- while(!Key1);
- pass[0]++;
- if(pass[0]>=10) pass[0]=0;
- }
-
- if(!Key2)//按鍵2
- {
- while(!Key2);
- pass[10] = pass[9];
- pass[9] = pass[8];
- pass[8] = pass[7];
- pass[7] = pass[6];
- pass[6] = pass[5];
- pass[5] = pass[4];
- pass[4] = pass[3];
- pass[3] = pass[2];
- pass[2] = pass[1];
- pass[1] = pass[0];
- pass[0] = 0;
-
- }
-
-
- /**************************************************************************************/
- /**************************************************************************************/
- }
- }
- void TIM4_IRQHandler(void) //定時中斷每1ms中斷一次
- {
- if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//?????
- {
- TIM_ClearITPendingBit(TIM4, TIM_IT_Update ); //??TIM4??????
-
- TX_10MS++;
- if(TX_10MS>=5000)
- {
- TX_10MS = 0;
- FlagUpData = 1;
- }
-
-
-
-
-
- }
- }
- void USART1_IRQHandler(void)
- {
- uint8_t ucTemp;
- if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
- {
- ucTemp = USART_ReceiveData(USART1);
- RxBuf1[0] = RxBuf1[1];
- RxBuf1[1] = RxBuf1[2];
- RxBuf1[2] = RxBuf1[3];
- RxBuf1[3] = ucTemp;
- if( (RxBuf1[0]=='F')&&(RxBuf1[1]=='t') ) //Ftxx 設置溫度閾值
- {
- AlarmT = (RxBuf1[2]-0x30)*10 + (RxBuf1[3]-0x30);
- }
- else if( (RxBuf1[0]=='F')&&(RxBuf1[1]=='m') ) //Fmxx 設置煙霧閾值
- {
- AlarmM = (RxBuf1[2]-0x30)*10 + (RxBuf1[3]-0x30);
- }
- }
- }
- void USART2_IRQHandler(void)
- {
- uint8_t ucTemp2;
- if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
- {
- ucTemp2= USART_ReceiveData(USART2);
- RxBuf2[0] = RxBuf2[1];
- RxBuf2[1] = RxBuf2[2];
- RxBuf2[2] = RxBuf2[3];
- RxBuf2[3] = ucTemp2;
- if( (RxBuf2[0]=='F')&&(RxBuf2[1]=='T') )
- {
- }
-
- }
- }
- void USART3_IRQHandler(void)
- {
- uint8_t ucTemp3;
- if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)
- {
- ucTemp3= USART_ReceiveData(USART3);
- RxBuf3[0] = RxBuf3[1];
- RxBuf3[1] = RxBuf3[2];
- RxBuf3[2] = RxBuf3[3];
- RxBuf3[3] = ucTemp3;
-
- }
-
- }
復制代碼
所有資料51hei附件下載:
Keil代碼原理圖.7z
(2.73 MB, 下載次數: 247)
2023-5-15 19:39 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|