日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32应用(八)数字温度传感器DS18B20、数字温湿度传感器DHT11(软件模拟I2C)

發布時間:2024/3/7 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32应用(八)数字温度传感器DS18B20、数字温湿度传感器DHT11(软件模拟I2C) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1.DS18B20 數字溫度傳感器實驗
    • 1.1 DS18B20簡介
    • 1.2 硬件與IO口配置
    • 1.3 實物圖與接線
    • 1.4 工程配置
    • 1.5 驅動和檢測代碼編寫
      • 1.5.1 ds18b20.c
      • 1.5.2 ds18b20.h
      • 1.5.3 main測試
    • 1.6 測試結果
  • 2.DHT11 數字溫濕度傳感器實驗
    • 2.1 DHT11簡介和接線
    • 2.2 通信時序簡述
      • 2.2.1 數據格式
      • 2.2.2 通訊時序
      • 2.3.2 數字信號0/1表示方式
    • 2.3工程配置
      • 2.2.1 輸出GPIO_PG_11
      • 2.2.2 打開串口USART1
      • 2.2.3 開啟TIM7,與1.4相同
    • 2.4 編寫代碼
      • 2.4.1 初始化、封裝IO的輸入輸出
      • 2.4.2 復位和響應模塊
      • 2.4.3 數據的解算
      • 2.4.4 測試代碼
    • 2.5 測試結果

這兩個傳感器F4的開發板上都沒有,如果要閱讀此博客,請先買好傳感器喲(^U^)ノYO

1.DS18B20 數字溫度傳感器實驗

1.1 DS18B20簡介

1.2 硬件與IO口配置


將 DS18B20 傳感器插入到這個上面就可以通過 STM32 來讀取 DS18B20 的溫度了。

1.3 實物圖與接線


1.4 工程配置

1.開啟GPIOG_9

2.開啟串口

3.開啟TIMX,實現us級定時

在tim.c文件中加入:

/* USER CODE BEGIN 1 */ void delay_us(uint16_t us){uint16_t differ = 0xffff-us-5; __HAL_TIM_SET_COUNTER(&htim7,differ); HAL_TIM_Base_Start(&htim7); while(differ < 0xffff-5){ differ = __HAL_TIM_GET_COUNTER(&htim7); }HAL_TIM_Base_Stop(&htim7); } /* USER CODE END 1 */

1.5 驅動和檢測代碼編寫

驅動代碼移植原子哥。驅動代碼有很多,可以自行修改。

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); } //復位DS18B20 void DS18B20_Rst(void) {DS18B20_IO_OUT();DS18B20_DQ_OUT_LOW;delay_us(750);DS18B20_DQ_OUT_HIGH;delay_us(15); } //等待DS18B20的回應 //返回1:未檢測到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讀取一個位 //返回值: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讀取一個字節 //返回值:讀到的數據 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; } //寫一個字節到DS18B20 //dat:要寫入的字節 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);}} } //開始溫度轉換 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 同時檢測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讀取溫度需要發送一些命令,
溫度轉換指令:0x44(啟動Ds18b20啟動轉換溫度)。
讀暫存器指令:0xBE(讀取暫存器中的九字節數據)。

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); //復位DS18B20 uint8_t DS18B20_Check(void);//檢測是否存在DS18B20uint8_t DS18B20_Read_Bit(void);//讀出一個位 uint8_t DS18B20_Read_Byte(void);//讀出一個字節 void DS18B20_Write_Byte(uint8_t data);//寫入一個字節void DS18B20_Start(void);//開始溫度轉換 short DS18B20_Get_Temperature(void); //獲取溫度#endif

1.5.3 main測試

/* 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 測試結果

2.DHT11 數字溫濕度傳感器實驗

在此將介紹數字溫濕度傳感器DHT11 的使用,該傳感器不但能測溫度,還能測濕度。

2.1 DHT11簡介和接線


DHT11 和 DS18B20 的接口是共用一個的,不過 DHT11 有 4 條腿,需要把 U12 的 4 個接口都用上, 將 DHT11 傳感器插入到這個上面就可以通過 STM32F4來讀取溫濕度值了。

2.2 通信時序簡述

以下內容來自客服給的DHT11說明書。

2.2.1 數據格式

微處理器與 DHT11之間的通訊和同步,采用單總線數據格式,一次通訊時間4ms左右,數據分小數部分和整數部分,具體格式在下面說明,當前小數部分用于以后擴展,現讀出為零.操作流程如下:
一次完整的數據傳輸為40bit,高位先出。
數據格式: 8bit濕度整數數據+8bit濕度小數數據
+8bi溫度整數數據+8bit溫度小數數據
+8bit校驗和

據傳送正確時校驗和數據等于 “8bit濕度整數數據+8bit濕度小數數據+8bi溫度整數數據+8bit溫度小數數據” 所得結果的末8位。

2.2.2 通訊時序

通訊過程如圖:

總線空閑狀態為高電平,主機把總線拉低等待DHT11響應,主機把總線拉低必須大于18毫秒,保證DHT11能檢測到起始信號。 DHT11接收到主機的開始信號后,等待主機開始信號結束,然后發送80us低電平響應信號。主機發送開始信號結束后,延時等待20-40us后,讀取DHT11的響應信號,主機發送開始信號后,可以切換到輸入模式,或者輸出高電平均可,總線由上拉電阻拉高。
開始傳輸信號:


總線為低電平,說明DHT11發送響應信號,DHT11發送響應信號后,再把總線拉高80us,準備發送數據,每一bit數據都以50us低電平時隙開始,高電平的長短定了數據位是0還是1。

2.3.2 數字信號0/1表示方式

2.3工程配置

2.2.1 輸出GPIO_PG_11

2.2.2 打開串口USART1

2.2.3 開啟TIM7,與1.4相同

2.4 編寫代碼

依據時序圖,編寫程序。

2.4.1 初始化、封裝IO的輸入輸出

由于是一個IO口,要滿足輸出和檢測電平,所以用兩個函數來切換引腳的模式,可以使引腳在輸出和輸入之間切換

//初始化DHT11的IO口 DQ 同時檢測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_Ini

2.4.2 復位和響應模塊

//復位DHT11 void DHT11_Rst(void) { DHT11_IO_OUT(); //設置為輸出DHT11_DQ_OUT_LOW; //拉低DQHAL_Delay(20); //拉低至少18msDHT11_DQ_OUT_HIGH; //DQ=1 delay_us(30); //主機拉高20~40us }//等待DHT11的回應 //返回1:未檢測到DHT11的存在 //返回0:存在 uint8_t DHT11_Check(void) { uint8_t retry=0;DHT11_IO_IN(); //設置為輸出 while (DHT11_DQ_IN&&retry<100)//DHT11會拉低40~80us{retry++;delay_us(1);}; if(retry>=100)return 1;else retry=0;while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后會再次拉高40~80us{retry++;delay_us(1);};if(retry>=100)return 1; return 0; }//從DHT11讀取一個位 //返回值:1/0 uint8_t DHT11_Read_Bit(void) {uint8_t retry=0;while(DHT11_DQ_IN&&retry<100)//等待變為低電平{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讀取一個字節 //返回值:讀到的數據 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 數據的解算

//從DHT11讀取一次數據 //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位數據{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 測試代碼

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 測試結果

總結

以上是生活随笔為你收集整理的STM32应用(八)数字温度传感器DS18B20、数字温湿度传感器DHT11(软件模拟I2C)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。