PB1引脚设置output即可,不想用PB1,修改引脚办法,修改dht11.c文件中的所有端口和引脚
现象
dht11.h
#ifndef __HT11_H_
#define __HT11_H_
#include "main.h"
#include "stm32f1xx_hal.h"
//函数原型
//void delay_us(uint8_t); //微妙延时函数,启用了一个定时器。因为DHT11通讯过程涉及微妙延时
void GPIO_Input(void); //GPIO 状态转变的函数 CUBEMX默认的GPIO初始化我只开启了相关总线的使能
//把GPIO状态(输入 输出)封装成了两个函数
void GPIO_Output(void);
void DHT11_Rst(void); //主机开始采集的信号
uint8_t DHT11_Check(void); //检查DHT是否回应
uint8_t DHT11_Init(void); //初始化函数
uint8_t DHT11_ReadBit(void); //读取一位
uint8_t DHT11_ReadByte(void); //读取一个字节
uint8_t DHT11_ReadData(uint8_t *); //读取数据(40个位)
#endif
dht11.c
#include "dht11.h"
#define CPU_FREQUENCY_MHZ 72 // CPU主频,根据实际进行修改
static void delay_us(uint32_t delay)
{
int last, curr, val;
int temp;
while (delay != 0)
{
temp = delay > 900 ? 900 : delay;
last = SysTick->VAL;
curr = last - CPU_FREQUENCY_MHZ * temp;
if (curr >= 0)
{
do
{
val = SysTick->VAL;
}
while ((val < last) && (val >= curr));
}
else
{
curr += CPU_FREQUENCY_MHZ * 1000;
do
{
val = SysTick->VAL;
}
while ((val <= last) || (val > curr));
}
delay -= temp;
}
}
void GPIO_Input(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin : PB1 */
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void GPIO_Output(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin : PB1 */
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void DHT11_Rst(void) //主机开始信号
{
GPIO_Output();
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);
HAL_Delay(20);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);
delay_us(30);
}
uint8_t DHT11_Check(void)
{
uint8_t retry = 0;
GPIO_Input();
while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) && retry <100) //等待回应拉位低电平
{
retry++;
delay_us(1);
}
if(retry >= 100)return 1;else retry = 0; //当变量值大于100 返回1 说明无响应 返回 0 则为正确响应
while(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) && retry <100) //等待变为高电平
{
retry++;
delay_us(1);
}
if(retry >= 100)return 1;
return 0;
}
uint8_t DHT11_Init(void)
{
DHT11_Rst();
return DHT11_Check();
}
uint8_t DHT11_ReadBit(void) //读取一个位
{
uint8_t retry = 0;
while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) && retry <100) //等待变为低电平
{
retry++;
delay_us(1);
}
retry = 0;
while(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) && retry <100) //等待变为高电平
{
retry++;
delay_us(1);
}
delay_us(40); //40us 后如果为低电平 数据为0 高电平数据为1
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1))return 1;else return 0;
}
uint8_t DHT11_ReadByte(void) //读取一个字节 返回值位采集值
{
uint8_t i,dat;
dat = 0;
for(i = 0;i < 8;i++)
{
dat <<= 1; //数据左移一位
dat |= DHT11_ReadBit(); //每读取到一个位 放到dat的最后一位
}
return dat;
}
uint8_t DHT11_ReadData(uint8_t *h)
{
uint8_t buf[5];
uint8_t i;
DHT11_Rst();
if(DHT11_Check() == 0){
for(i = 0;i < 5;i++)
{
buf[i] = DHT11_ReadByte();
}
if(buf[0] + buf[1] + buf[2] + buf[3] == buf[4])
{
*h = buf[0];
h++;
*h = buf[2];
}
}else return 1;
return 0;
}
main.c添加
//你自己要完成OLED显示出温度湿度哈,这个我就不写代码了,不然真的是再喂饭了呜呜
#include "dht11.h" //引入头文件
#include "stdio.h"
uint8_t data[2]; //定义一个数据数组
uint8_t buff1[]="dht11 ok\r\n";
uint8_t buff2[]="dht11 error";
uint8_t str_buff[64];
//int main 死循环外面
if(DHT11_Init() == 0)
{
//这里显示了“温度”“湿度等字符”
HAL_UART_Transmit(&huart1,buff1,sizeof(buff1),10000);
}
else{
//OLED_ShowStr(0,0,"DHT11 error!",1);
HAL_UART_Transmit(&huart1,buff2,sizeof(buff2),10000);
}
HAL_Delay(1000);
while (1)
{
if(DHT11_ReadData(data) == 0)
{ //显示相关数据
sprintf((char *)str_buff,"温度%d%d;湿度%d%d\r\n",data[0] /10 ,data[0] %10,data[1] /10,data[1] /10);
HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000);
}
HAL_Delay(1000); //DHT11每次采集一定要间隔1s
//你自己要完成OLED显示出温度湿度哈,这个我就不写代码了,不然真的是再喂饭了呜呜!
}
评论 (0)