STM32应用(八)数字温度传感器DS18B20、数字温湿度传感器DHT11(软件模拟I2C)
文章目錄
- 1.DS18B20 數(shù)字溫度傳感器實(shí)驗(yàn)
- 1.1 DS18B20簡(jiǎn)介
- 1.2 硬件與IO口配置
- 1.3 實(shí)物圖與接線(xiàn)
- 1.4 工程配置
- 1.5 驅(qū)動(dòng)和檢測(cè)代碼編寫(xiě)
- 1.5.1 ds18b20.c
- 1.5.2 ds18b20.h
- 1.5.3 main測(cè)試
- 1.6 測(cè)試結(jié)果
- 2.DHT11 數(shù)字溫濕度傳感器實(shí)驗(yàn)
- 2.1 DHT11簡(jiǎn)介和接線(xiàn)
- 2.2 通信時(shí)序簡(jiǎn)述
- 2.2.1 數(shù)據(jù)格式
- 2.2.2 通訊時(shí)序
- 2.3.2 數(shù)字信號(hào)0/1表示方式
- 2.3工程配置
- 2.2.1 輸出GPIO_PG_11
- 2.2.2 打開(kāi)串口USART1
- 2.2.3 開(kāi)啟TIM7,與1.4相同
- 2.4 編寫(xiě)代碼
- 2.4.1 初始化、封裝IO的輸入輸出
- 2.4.2 復(fù)位和響應(yīng)模塊
- 2.4.3 數(shù)據(jù)的解算
- 2.4.4 測(cè)試代碼
- 2.5 測(cè)試結(jié)果
這兩個(gè)傳感器F4的開(kāi)發(fā)板上都沒(méi)有,如果要閱讀此博客,請(qǐng)先買(mǎi)好傳感器喲(^U^)ノYO
1.DS18B20 數(shù)字溫度傳感器實(shí)驗(yàn)
1.1 DS18B20簡(jiǎn)介
1.2 硬件與IO口配置
將 DS18B20 傳感器插入到這個(gè)上面就可以通過(guò) STM32 來(lái)讀取 DS18B20 的溫度了。
1.3 實(shí)物圖與接線(xiàn)
1.4 工程配置
1.開(kāi)啟GPIOG_9
2.開(kāi)啟串口
3.開(kāi)啟TIMX,實(shí)現(xiàn)us級(jí)定時(shí)
在tim.c文件中加入:
1.5 驅(qū)動(dòng)和檢測(cè)代碼編寫(xiě)
驅(qū)動(dòng)代碼移植原子哥。驅(qū)動(dòng)代碼有很多,可以自行修改。
1.5.1 ds18b20.c
#include "ds18b20.h"void DS18B20_IO_IN(void) {GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.Pin = GPIO_PIN_9;GPIO_InitStructure.Mode = GPIO_MODE_INPUT;HAL_GPIO_Init(GPIOG,&GPIO_InitStructure); }void DS18B20_IO_OUT(void) {GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.Pin = GPIO_PIN_9;GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOG,&GPIO_InitStructure); } //復(fù)位DS18B20 void DS18B20_Rst(void) {DS18B20_IO_OUT();DS18B20_DQ_OUT_LOW;delay_us(750);DS18B20_DQ_OUT_HIGH;delay_us(15); } //等待DS18B20的回應(yīng) //返回1:未檢測(cè)到DS18B20的存在 //返回0:存在 uint8_t DS18B20_Check(void) {uint8_t retry = 0;DS18B20_IO_IN();while(DS18B20_DQ_IN && retry < 200){retry++;delay_us(1);}if(retry >= 200)return 1;elseretry = 0;while(!DS18B20_DQ_IN && retry < 240){retry++;delay_us(1);}if(retry >= 240)return 1;return 0; } //從DS18B20讀取一個(gè)位 //返回值:1/0 uint8_t DS18B20_Read_Bit(void) {uint8_t data;DS18B20_IO_OUT();DS18B20_DQ_OUT_LOW;delay_us(2);DS18B20_DQ_OUT_HIGH;DS18B20_IO_IN();delay_us(12);if(DS18B20_DQ_IN)data = 1;elsedata = 0;delay_us(50);return data; } //從DS18B20讀取一個(gè)字節(jié) //返回值:讀到的數(shù)據(jù) uint8_t DS18B20_Read_Byte(void) {uint8_t i,j,data;data = 0;for(i=1;i<=8;i++){j = DS18B20_Read_Bit();data = (j<<7)|(data>>1);}return data; } //寫(xiě)一個(gè)字節(jié)到DS18B20 //dat:要寫(xiě)入的字節(jié) void DS18B20_Write_Byte(uint8_t data) {uint8_t j;uint8_t testb;DS18B20_IO_OUT();for(j=1;j<=8;j++){testb=data&0x01;data=data>>1;if(testb){DS18B20_DQ_OUT_LOW;delay_us(2);DS18B20_DQ_OUT_HIGH;delay_us(60);}else{DS18B20_DQ_OUT_LOW;delay_us(60);DS18B20_DQ_OUT_HIGH;delay_us(2);}} } //開(kāi)始溫度轉(zhuǎn)換 void DS18B20_Start(void) {DS18B20_Rst();DS18B20_Check();DS18B20_Write_Byte(0xcc);DS18B20_Write_Byte(0x44); }uint8_t DS18B20_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.Pin = GPIO_PIN_9;GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStructure.Pull = GPIO_PULLUP;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);DS18B20_Rst();return DS18B20_Check(); } //初始化DS18B20的IO口 DQ 同時(shí)檢測(cè)DS的存在 //返回1:不存在 //返回0:存在 short DS18B20_Get_Temperature(void) {uint8_t t;uint8_t TL,TH;short temperature;DS18B20_Start();DS18B20_Rst();DS18B20_Check();DS18B20_Write_Byte(0xcc);DS18B20_Write_Byte(0xbe);TL = DS18B20_Read_Byte();TH = DS18B20_Read_Byte();if(TH>7){TH = ~TH;TL = ~TL;t = 0;}elset = 1;temperature = TH;temperature <<= 8;temperature += TL;temperature = (short)temperature*0.625;if(temperature)return temperature;elsereturn -temperature; }DS18B20讀取溫度需要發(fā)送一些命令,
溫度轉(zhuǎn)換指令:0x44(啟動(dòng)Ds18b20啟動(dòng)轉(zhuǎn)換溫度)。
讀暫存器指令:0xBE(讀取暫存器中的九字節(jié)數(shù)據(jù))。
1.5.2 ds18b20.h
#ifndef __DS18B20_H #define __DS18B20_H #include "main.h" #include "tim.h"#define DS18B20_DQ_OUT_HIGH HAL_GPIO_WritePin(GPIOG,GPIO_PIN_9,GPIO_PIN_SET) #define DS18B20_DQ_OUT_LOW HAL_GPIO_WritePin(GPIOG,GPIO_PIN_9,GPIO_PIN_RESET)#define DS18B20_DQ_IN HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_11)void DS18B20_IO_IN(void); void DS18B20_IO_OUT(void);uint8_t DS18B20_Init(void); //初始化DS18B20 void DS18B20_Rst(void); //復(fù)位DS18B20 uint8_t DS18B20_Check(void);//檢測(cè)是否存在DS18B20uint8_t DS18B20_Read_Bit(void);//讀出一個(gè)位 uint8_t DS18B20_Read_Byte(void);//讀出一個(gè)字節(jié) void DS18B20_Write_Byte(uint8_t data);//寫(xiě)入一個(gè)字節(jié)void DS18B20_Start(void);//開(kāi)始溫度轉(zhuǎn)換 short DS18B20_Get_Temperature(void); //獲取溫度#endif1.5.3 main測(cè)試
/* USER CODE BEGIN 2 */printf("DS18B20 Test!\r\n");while(DS18B20_Init()){printf("DS18B20 checked failed!!!\r\n");HAL_Delay(500);}//DS18B20_Init();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){temperature=DS18B20_Get_Temperature(); if(temperature < 0)printf("temperature = -%.2f degree\r\n",temperature/10);elseprintf("temperature = %.2f degree\r\n",temperature/10);HAL_Delay(200);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}1.6 測(cè)試結(jié)果
2.DHT11 數(shù)字溫濕度傳感器實(shí)驗(yàn)
在此將介紹數(shù)字溫濕度傳感器DHT11 的使用,該傳感器不但能測(cè)溫度,還能測(cè)濕度。
2.1 DHT11簡(jiǎn)介和接線(xiàn)
DHT11 和 DS18B20 的接口是共用一個(gè)的,不過(guò) DHT11 有 4 條腿,需要把 U12 的 4 個(gè)接口都用上, 將 DHT11 傳感器插入到這個(gè)上面就可以通過(guò) STM32F4來(lái)讀取溫濕度值了。
2.2 通信時(shí)序簡(jiǎn)述
以下內(nèi)容來(lái)自客服給的DHT11說(shuō)明書(shū)。
2.2.1 數(shù)據(jù)格式
微處理器與 DHT11之間的通訊和同步,采用單總線(xiàn)數(shù)據(jù)格式,一次通訊時(shí)間4ms左右,數(shù)據(jù)分小數(shù)部分和整數(shù)部分,具體格式在下面說(shuō)明,當(dāng)前小數(shù)部分用于以后擴(kuò)展,現(xiàn)讀出為零.操作流程如下:
一次完整的數(shù)據(jù)傳輸為40bit,高位先出。
數(shù)據(jù)格式: 8bit濕度整數(shù)數(shù)據(jù)+8bit濕度小數(shù)數(shù)據(jù)
+8bi溫度整數(shù)數(shù)據(jù)+8bit溫度小數(shù)數(shù)據(jù)
+8bit校驗(yàn)和
據(jù)傳送正確時(shí)校驗(yàn)和數(shù)據(jù)等于 “8bit濕度整數(shù)數(shù)據(jù)+8bit濕度小數(shù)數(shù)據(jù)+8bi溫度整數(shù)數(shù)據(jù)+8bit溫度小數(shù)數(shù)據(jù)” 所得結(jié)果的末8位。
2.2.2 通訊時(shí)序
通訊過(guò)程如圖:
總線(xiàn)空閑狀態(tài)為高電平,主機(jī)把總線(xiàn)拉低等待DHT11響應(yīng),主機(jī)把總線(xiàn)拉低必須大于18毫秒,保證DHT11能檢測(cè)到起始信號(hào)。 DHT11接收到主機(jī)的開(kāi)始信號(hào)后,等待主機(jī)開(kāi)始信號(hào)結(jié)束,然后發(fā)送80us低電平響應(yīng)信號(hào)。主機(jī)發(fā)送開(kāi)始信號(hào)結(jié)束后,延時(shí)等待20-40us后,讀取DHT11的響應(yīng)信號(hào),主機(jī)發(fā)送開(kāi)始信號(hào)后,可以切換到輸入模式,或者輸出高電平均可,總線(xiàn)由上拉電阻拉高。
開(kāi)始傳輸信號(hào):
總線(xiàn)為低電平,說(shuō)明DHT11發(fā)送響應(yīng)信號(hào),DHT11發(fā)送響應(yīng)信號(hào)后,再把總線(xiàn)拉高80us,準(zhǔn)備發(fā)送數(shù)據(jù),每一bit數(shù)據(jù)都以50us低電平時(shí)隙開(kāi)始,高電平的長(zhǎng)短定了數(shù)據(jù)位是0還是1。
2.3.2 數(shù)字信號(hào)0/1表示方式
2.3工程配置
2.2.1 輸出GPIO_PG_11
2.2.2 打開(kāi)串口USART1
2.2.3 開(kāi)啟TIM7,與1.4相同
2.4 編寫(xiě)代碼
依據(jù)時(shí)序圖,編寫(xiě)程序。
2.4.1 初始化、封裝IO的輸入輸出
由于是一個(gè)IO口,要滿(mǎn)足輸出和檢測(cè)電平,所以用兩個(gè)函數(shù)來(lái)切換引腳的模式,可以使引腳在輸出和輸入之間切換
//初始化DHT11的IO口 DQ 同時(shí)檢測(cè)DHT11的存在 //返回1:不存在 //返回0:存在 uint8_t DHT11_Init(void) { DHT11_Rst();return DHT11_Check(); } #define DHT11_DQ_OUT_HIGH HAL_GPIO_WritePin(GPIOG,GPIO_PIN_11,GPIO_PIN_SET) #define DHT11_DQ_OUT_LOW HAL_GPIO_WritePin(GPIOG,GPIO_PIN_11,GPIO_PIN_RESET) #define DHT11_DQ_IN HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_11)void DHT11_IO_IN(void) {GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.Pin = GPIO_PIN_11;GPIO_InitStructure.Mode = GPIO_MODE_INPUT;HAL_GPIO_Init(GPIOG,&GPIO_InitStructure); }void DHT11_IO_OUT(void) {GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.Pin = GPIO_PIN_11;GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOG,&GPIO_Ini2.4.2 復(fù)位和響應(yīng)模塊
//復(fù)位DHT11 void DHT11_Rst(void) { DHT11_IO_OUT(); //設(shè)置為輸出DHT11_DQ_OUT_LOW; //拉低DQHAL_Delay(20); //拉低至少18msDHT11_DQ_OUT_HIGH; //DQ=1 delay_us(30); //主機(jī)拉高20~40us }//等待DHT11的回應(yīng) //返回1:未檢測(cè)到DHT11的存在 //返回0:存在 uint8_t DHT11_Check(void) { uint8_t retry=0;DHT11_IO_IN(); //設(shè)置為輸出 while (DHT11_DQ_IN&&retry<100)//DHT11會(huì)拉低40~80us{retry++;delay_us(1);}; if(retry>=100)return 1;else retry=0;while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后會(huì)再次拉高40~80us{retry++;delay_us(1);};if(retry>=100)return 1; return 0; }//從DHT11讀取一個(gè)位 //返回值:1/0 uint8_t DHT11_Read_Bit(void) {uint8_t retry=0;while(DHT11_DQ_IN&&retry<100)//等待變?yōu)榈碗娖?/span>{retry++;delay_us(1);}retry=0;while(!DHT11_DQ_IN&&retry<100)//等待變高電平{retry++;delay_us(1);}delay_us(40);//等待40usif(DHT11_DQ_IN)return 1;else return 0; }//從DHT11讀取一個(gè)字節(jié) //返回值:讀到的數(shù)據(jù) uint8_t DHT11_Read_Byte(void) { uint8_t i,dat;dat=0;for (i=0;i<8;i++) {dat<<=1; dat|=DHT11_Read_Bit();} return dat; }2.4.3 數(shù)據(jù)的解算
//從DHT11讀取一次數(shù)據(jù) //temp:溫度值(范圍:0~50°) //humi:濕度值(范圍:20%~90%) //返回值:0,正常;1,讀取失敗 uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi) { uint8_t buf[5];uint8_t i;DHT11_Rst();if(DHT11_Check()==0){for(i=0;i<5;i++)//讀取40位數(shù)據(jù){buf[i]=DHT11_Read_Byte();}if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){*humi=(buf[0]<<8) + buf[1];*temp=(buf[2]<<8) + buf[3];}}else return 1;return 0; }2.4.4 測(cè)試代碼
uint16_t temperature; uint16_t humidity;while(DHT11_Init()){printf("DHT11 Checked failed!!!\r\n");HAL_Delay(200);}printf("DHT11 Checked Sucess!!!\r\n"); while (1) {DHT11_Read_Data(&temperature,&humidity);printf("DHT11 Temperature = %d.%d degree\r\n",temperature>>8,temperature&0xff);printf("DHT11 Humidity = %d.%d%%\r\n",humidity>>8,humidity&0xff);HAL_Delay(200); }2.5 測(cè)試結(jié)果
總結(jié)
以上是生活随笔為你收集整理的STM32应用(八)数字温度传感器DS18B20、数字温湿度传感器DHT11(软件模拟I2C)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数字温度传感器
- 下一篇: 某音直播协议实现技术探讨