【小项目】STM32环境监测 | MQ2可燃气体传感器+雨滴传感器+DHT11温湿度传感器+OLED屏幕
目錄
- 概述
- 固件編寫
- DHT11溫濕度傳感器
- 概述
- 代碼
- MQ2可燃氣體傳感器和雨滴傳感器
- 概述
- ADC外設
- 代碼
- OLED屏幕
- 概述
- 代碼
- main.c文件
- 概述
- 代碼
- 總結
- 項目代碼下載
概述
前些陣子參加了廣東省電賽,因為疫情的原因比賽不能在線下進行,甚至連回學校調試也不行,于是乎就水了一個省三。
備賽的時候,隊長給我布置了這個小項目,說有可能會用在比賽的作品中,但實際就不知道了,所以在這里分享一下代碼。
固件編寫
這個需求對性能要求不高,像人見人愛、人手一個的STM32F103C8T6也能勝任,但因為我沒帶回家,所以用了野火的霸道V2開發板。
這塊開發板用的是STM32F103ZET6芯片。
DHT11溫濕度傳感器
概述
溫濕度傳感器玩過單片機的小伙伴都應該特別熟悉了,在這里就不再贅述了。但還是放幾張時序圖解釋一下。
總體來說DHT11是串行通信,只用一根數據線進行通信,通信的形式有點像IIC,都是先給一個響應信號,然后傳感器應答后開始傳輸數據,直到從機或主機發送結束信號。
下面是主機發送響應信號的時序。
從機接收到主機的響應信號后會按以下時序產生應答信號,表示接受響應。
實際發送的數據都是以一低一高的形式表示,“0”和“1”的區別在于高電平的持續時間,利用這一點主機可以區分“0”和“1”比特。
代碼
下面是接收一個字節和接收溫濕度數據的代碼:
/* * 從DHT11讀取一個字節,MSB先行*/ static uint8_t DHT11_ReadByte ( void ) {uint8_t i, temp=0;for(i=0;i<8;i++) { /*每bit以50us低電平標置開始,輪詢直到從機發出 的50us 低電平 結束*/ while(DHT11_Dout_IN() == RESET);/*DHT11 以26~28us的高電平表示“0”,以70us高電平表示“1”,*通過檢測 x us后的電平即可區別這兩個狀 ,x 即下面的延時 */DHT11_DELAY_10US(4); //延時x us 這個延時需要大于數據0持續的時間即可 if(DHT11_Dout_IN() == SET)/* x us后仍為高電平表示數據“1” */{/* 等待數據1的高電平結束 */while(DHT11_Dout_IN() == SET);temp|=(uint8_t)(0x01<<(7-i)); //把第7-i位置1,MSB先行 }else // x us后為低電平表示數據“0”{ temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行}}return temp;}/** 一次完整的數據傳輸為40bit,高位先出* 8bit 濕度整數 + 8bit 濕度小數 + 8bit 溫度整數 + 8bit 溫度小數 + 8bit 校驗和 */ uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data) { /*輸出模式*/DHT11_Mode_Out_PP();/*主機拉低*/DHT11_Dout_0;/*延時18ms*/DHT11_DELAY_MS(18);/*總線拉高 主機延時30us*/DHT11_Dout_1; DHT11_DELAY_10US(3); //延時30us/*主機設為輸入 判斷從機響應信號*/ DHT11_Mode_IPU();/*判斷從機是否有低電平響應信號 如不響應則跳出,響應則向下運行*/ if(DHT11_Dout_IN() == RESET) {/*輪詢直到從機發出 的80us 低電平 響應信號結束*/ while(DHT11_Dout_IN() == RESET);/*輪詢直到從機發出的 80us 高電平 標置信號結束*/while(DHT11_Dout_IN() == SET);/*開始接收數據*/ DHT11_Data->humi_int= DHT11_ReadByte();DHT11_Data->humi_deci= DHT11_ReadByte();DHT11_Data->temp_int= DHT11_ReadByte();DHT11_Data->temp_deci= DHT11_ReadByte();DHT11_Data->check_sum= DHT11_ReadByte();/*讀取結束,引腳改為輸出模式*/DHT11_Mode_Out_PP();/*主機拉高*/DHT11_Dout_1;/*檢查讀取的數據是否正確*/if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)return SUCCESS;else return ERROR;}elsereturn ERROR;}MQ2可燃氣體傳感器和雨滴傳感器
概述
因為可燃氣體檢測和雨滴感應的傳感器原理較相似,所以放到一起講了。
可燃氣體傳感器用的是MQ2。
下面是雨滴模塊的樣子(簡單到連名字都沒有)
兩個模塊都是用模擬信號通信,所以使用STM32的ADC外設就可以輕松讀取數據。
ADC外設
根據STM32的用戶手冊知道我們使用的這款芯片有3個ADC外設,為了讓單片機能更快處理轉換模擬信號,所以使用了雙ADC模式;為了讓我們能隨時調整采樣的時間,我還使用了ADC外設的外部觸發功能;為了保證數據傳輸的效率我還使用了DMA進行傳輸。
解釋一下雙ADC模式,通俗講就是正常是一個ADC處理2個模擬信號的轉換,現在2個ADC分別負責2個模擬信號的轉換,并且是硬件控制同時開始轉換的,因此效率會高很多。
STM32支持的雙ADC模式有好幾個,具體可參考用戶文檔,在這里我們使用最常用的同步規則模式即可。
但需要注意的是雙ADC模式只能使用ADC1和ADC2外設
代碼
接下來放核心代碼吧,對于STM32的ADC玩法還挺多的,計劃在另外寫一篇文章來講一下。
adc.c文件:
adc.h文件:
/* 相關配置 */ #define CONV_TIME 100 // 采樣周期,單位ms/* 其他宏定義 */ #define TIM_PERIOD_VAL (CONV_TIME * 2 - 1)/* 管腳宏定義 */ #define TIM_PORT TIM3 #define TIM_PERI_CLK_PORT RCC_APB1Periph_TIM3#define DMA_PERI_CLK_PORT RCC_AHBPeriph_DMA1 #define ADC1_DR_Address ((uint32_t)0x4001244C) #define ADC_DMA_CHAL DMA1_Channel1void ADC_Config(void); uint16_t ADC_GetMQ2RawData(void); uint16_t ADC_GetWaterSensorRawData(void);OLED屏幕
概述
OLED屏幕應該也有很多小伙伴玩過了。
這個屏幕的通信方式有挺多種的,比如說8080時序、IIC、SPI,具體是哪種通信方式要看買的時候商家的說明。
我買的這個是IIC的接口,我使用了硬件IIC對其通信。
代碼
簡單貼一下代碼:
礙于篇幅就只放初始化和傳輸一個字節的代碼吧。
main.c文件
概述
應隊長的要求這個小項目用了FreeRTOS系統,但實際上除了用到最基本的任務調度外,其他的功能都沒有用到。
至于FreeRTOS系統的移植網上都有好多的教程了,這里就不贅述了。
簡單說主任務做的就是一段時間后切換OLED屏幕的顯示內容(因為一塊OLED屏幕顯示不了所有傳感器的數據)
代碼
簡單貼一下代碼:
static void MainTask(void* params) {uint8_t status = 0;while(1){if (status){DHT11_Read_TempAndHumidity(&dht11_data);OLED_ShowTempAndHumi(dht11_data.temp_int, dht11_data.temp_deci, dht11_data.humi_int, dht11_data.humi_deci);printf("Displaying temperature and humidity\n");}else{OLED_ShowPpmAndWaterLevel(MQ2_GetPPM(), WaterSensor_GetWaterLevel());printf("Displaying PPM and water level\n");}status = !status;vTaskDelay(2000);} }static void AppInitTask(void* params) {taskENTER_CRITICAL(); // 進入臨界段NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);USART_Config();MQ2_Init();WaterSensor_Init();ADC_Config();TIMER_Init();DHT11_Init();OLED_Init();printf("Init completed\n");vTaskDelay(100);xTaskCreate(MainTask, "MainTask", 1024, NULL, 5, NULL);printf("Main task created\n");vTaskDelete(NULL); // 刪除這個任務taskEXIT_CRITICAL(); // 退出臨界段 }/*** @brief 主函數* @param None* @retval None*/ int main(void) {BaseType_t xReturn = pdPASS;xReturn = xTaskCreate(AppInitTask, "AppInitTask", 1024, NULL, 5, NULL);if (xReturn == pdPASS) vTaskStartScheduler(); // 開啟任務調度else while(1); }總結
總的來說,這個項目還是蠻適合對STM32已經入門然后想進階的小伙伴。
項目包含了對各種常見模塊的代碼撰寫,每種模塊對應的通信協議、用到的外設也不盡相同;項目還涉及了對FreeRTOS系統的基本移植和使用,對于想進階STM32的小伙伴是非常好的。
項目代碼下載
鏈接:https://download.csdn.net/download/JackieCoo/86506760
總結
以上是生活随笔為你收集整理的【小项目】STM32环境监测 | MQ2可燃气体传感器+雨滴传感器+DHT11温湿度传感器+OLED屏幕的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MSP430F5529 DriverLi
- 下一篇: ThinkPad X220i 刷白名单B