一、DHT11
这个模块主要是测温湿度的,大概样子如下图所示
网上都说DAT口需要上拉一个5k电阻,但是像这种模块的话是不需要大家自行再接一个5k电阻的,因为这都是集成好了的,如果是单独的传感器,那就需要大家自行再接一个5k的电阻了。废话不多说,下面我们直接看stm32端的代码吧
二、stm32端代码
dht11.c
#include "stm32f10x.h" // Device header #include "DHT11.h" #include "delay.h" uint8_t dat[4];//接收数据 //数据输入输出为PB12 void Data_Out_Init(void) { GPIO_InitTypeDef GPIO_Structure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_Structure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Structure.GPIO_Pin = GPIO_Pin_12; GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_Structure); } void Data_In_Init(void) { GPIO_InitTypeDef GPIO_Structure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_Structure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Structure.GPIO_Pin = GPIO_Pin_12; GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_Structure); } /* 首先主机发送开始信号,即:先拉高数据线 再拉低数据线,保持 t1(至少 18ms)时间 然后拉高数据线 t2(20~40us)时间,然后读取 DHT11 的响应 正常的话,DHT11 会拉低数据线,保持 t3(40~50us)时间,作为响应信号 然后 DHT11 拉高数据线,保持 t4(40~50us)时间后,开始输出数据。 */ void DHT11_start(void) { Data_Out_Init(); GPIO_SetBits(GPIOB,GPIO_Pin_12); delay_us(1); GPIO_ResetBits(GPIOB,GPIO_Pin_12); delay_ms(20); //拉低18ms以上 20ms GPIO_SetBits(GPIOB,GPIO_Pin_12); delay_us(30);// 拉高20ms-40ms Data_In_Init(); delay_us(10); } uint8_t DHT11_rec_byte(void) //接收一个字节 { uint8_t i,dat=0; for(i=0;i<8;i++) //从高到低依次接收8位数据 { while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == 0); //等待50us低电平过去 delay_us(40); //延时40us,如果还为高则数据为1,否则为0 dat<<=1; //移位使正确接收8位数据,数据为0时直接移位 if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == 1) //数据为1时,使dat加1来接收数据1 { dat+=1; } while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == 1); //等待数据线拉低 } return dat; } void DHT11_rec_data(void) //接收40位的数据 { uint8_t R_H,R_L,T_H,T_L,revise; DHT11_start(); if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == 0) { while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == 0);//处理响应低电平,等待拉高 while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == 1);//处理响应高电平,等待拉低 R_H=DHT11_rec_byte(); //接收湿度高八位 R_L=DHT11_rec_byte(); //接收湿度低八位 T_H=DHT11_rec_byte(); //接收温度高八位 T_L=DHT11_rec_byte(); //接收温度低八位 revise=DHT11_rec_byte(); //接收校正位 while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) == 0);//等待从机拉低 if((R_H+R_L+T_H+T_L) == revise) //校正 { dat[0]=T_H; //温度高8位(表示整数部分) dat[1]=T_L; //温度低8位(表示小数部分) dat[2]=R_H; //湿度高8位(表示整数部分) dat[3]=R_L; //湿度低8位(表示小数部分) } } }
dht11.h
#ifndef __DHT11_H #define __DHT11_H #include "stm32f10x.h" // Device header extern uint8_t dat[4];//接收数据 void Data_Out_Init(void); void Data_In_Init(void); void DHT11_start(void); uint8_t DHT11_rec_byte(void); void DHT11_rec_data(void) ;//温度 湿度 #endif
main.c
#include "led.h" #include "delay.h" #include "key.h" #include "sys.h" #include "usart.h" #include "time.h" #include "myiic.h" #include "oled.h" #include "beep.h" #include "SR602.h" #include "dht11.h" #include "MOTOR.h" int i=0; u8 string[30] = {0},string1[30] = {0}; void Use_DHT11(void) { DHT11_rec_data();//dht11初始化 sprintf((char *)string,"T:%d",dat[0]);//温度整数 OLED_ShowString(1,15,string,8,1); OLED_ShowNum(29,15,dat[1],2,8,1);//温度小数 OLED_DrawPoint(27,20,1);//小数点 sprintf((char *)string,"humidity:%d",dat[2]);//湿度整数 OLED_ShowString(1,25,string,8,1); OLED_ShowNum(71,25,dat[3],2,8,1);//湿度小数 OLED_DrawPoint(69,30,1); } int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先 delay_init();//延时函数初始化 OLED_Init();//oled显示屏初始化 OLED_ColorTurn(0); //0正常显示,1 反色显示 OLED_DisplayTurn(0); //屏幕旋转180度调整 while(1) { OLED_Refresh();//oled刷新 Use_DHT11(); } }
还没有评论,来说两句吧...