目录1.模块清单2.功能展示3.程序实现1.模块清单主要用到STM32F103C8T6最小系统板0.96寸OLED4线IIC屏幕DHT11温湿度传感器在某宝上都可以买到。目前我买的这款DHT11温度可以读取到小数部分湿度并不能读取到小数部分不知道是啥原因。工程放在文末免费获取。2.功能展示我买了一个小米的温湿度计然后根据温湿度计测出的数据对DHT11测出的数据进行一个对比总体测量出来的话DHT11湿度误差比较大±5%温度测量误差比较小±2℃。3.程序实现原理什么的就不多赘述了b站和csdn上都有大量的讲解我就贴出一些主要的代码部分工程会放在文末。采样周期我是使用的tim定时器1.5秒采样一次。main.c部分/** ****************************************************************************** * * * 应用平台STM32F103C8T6最小系统板 * * * * * * ****************************************************************************** */ #include stm32f10x.h #include OLED_I2C.h #include delay.h #include ./led/bsp_led.h #include ./usart/bsp_usart.h #include tim.h #include sys.h #include dht11.h extern u8 dat[5];//DHT11数据存放数组 int flag0;//温湿度采集标志位1.5s采集一次数据 unsigned int m;//毫秒计算变量 float tempurate,humi;//温度 湿度 变量定义 /* 温湿度dht11 data 接PB14 屏幕 SCL接PB6 SDA接PB7 */ char str[64]{0};//屏幕显示字符串 int main(void) { /*初始化LED、串口、OLED、DHT11*/ delay_init();//初始化延迟函数 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级设置 USART_Config();//串口初始化函数 LED_GPIO_Config();//LED初始化函数 I2C_Configuration();//配置CPU的硬件I2C OLED_Init();//初始化OLED OLED_CLS();//清屏 TIM3_Init(1000-1,72-1); //打开定时器3周期为500us DHT11_GPIO_IN();//温湿度传感器初始化 while(1) { //获取数据时让开发板的灯闪一下 if(flag) GPIO_ResetBits(GPIOC, GPIO_Pin_13); else GPIO_SetBits(GPIOC, GPIO_Pin_13); if(flag) { if(DHT_Read())//读取数据正确情况下进行温湿度计算 { flag0;//标志位置零进入下一次计时 humidat[0] dat[1]/10.f5;//计算湿度 tempuratedat[2] dat[3]/10.f;//计算温度 } OLED_ShowCN(0,2,0);//显示汉字温 OLED_ShowCN(16,2,1);//显示汉字度 sprintf(str,: %.1f C ,tempurate);//显示温度数值 OLED_ShowStr(32,2,(unsigned char*)str,2); OLED_ShowCN(0,5,2);//显示汉字湿 OLED_ShowCN(16,5,3);//显示汉字度 sprintf(str,: %.1f %% ,humi);//显示湿度数值 OLED_ShowStr(32,5,(unsigned char*)str,2); } } } /*********************************************END OF FILE**********************/dht11.c部分#include dht11.h #include delay.h uint8_t dat[5]{0x00,0x00,0x00,0x00,0x00}; uint8_t sum 0; /* *初始化输出 */ void DHT11_GPIO_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); } /* *初始化输入 */ void DHT11_GPIO_IN(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, GPIO_InitStructure); } /* *读取一个字节 */ uint8_t DHT_Read_Byte(void) { uint8_t temp; uint8_t ReadDat 0; uint8_t retry 0; uint8_t i; for(i0; i8;i) { //读取一位数据时会先收到低电平信号50us while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) 0 retry 100) { Delay_us(1); retry; } retry 0; Delay_us(30); temp 0; //再接收高电平信号16us-28us代表数据0或高电平信号70us代表数据1 if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)1) temp1; while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) 1 retry100) { Delay_us(1); retry; } retry 0; ReadDat1; ReadDat|temp; } return ReadDat; } /* *读取一次数据 */ uint8_t DHT_Read(void) { uint8_t i; uint8_t retry 0; //总线设置为输出并拉低18ms DHT11_GPIO_OUT(); GPIO_ResetBits(GPIOB, GPIO_Pin_14); Delay_ms(18); //总线再拉高40ms GPIO_SetBits(GPIOB, GPIO_Pin_14); Delay_us(40); //总线设置为输入 DHT11_GPIO_IN(); Delay_us(20); //等待响应信号为低电平 if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) 0) { //等待响应信号为高电平超时等待100us while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)0retry100) { Delay_us(1); retry; } retry0; //等待数据传送超时等待100us while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)1retry100) { Delay_us(1); retry; } retry0; //循环读取数据dat[0]为湿度整数数据dat[1]为湿度小数数据dat[2]为温度整数数据dat[3]为温度小数数据dat[4]为校验和数据 for(i0;i5;i) { dat[i] DHT_Read_Byte(); } Delay_us(50); } //当校验和数据湿度整数数据湿度小数数据温度整数数据温度小数数据说明正确传送。 sum dat[0] dat[1] dat[2] dat[3]; if(dat[4] sum) { return 1; } else return 0; }dht11.h#ifndef __DHT11_H #define __DHT11_H #include stm32f10x.h void DHT11_GPIO_OUT(void); void DHT11_GPIO_IN(void); uint8_t DHT_Read_Byte(void); uint8_t DHT_Read(void); #endif工程链接https://download.csdn.net/download/weixin_53801451/88787956