侧边栏壁纸
    • 累计撰写 296 篇文章
    • 累计收到 520 条评论
    HAL库开发stm32 DHT11传感器
    我的学记|刘航宇的博客

    HAL库开发stm32 DHT11传感器

    刘航宇
    2022-04-20 / 0 评论 / 720 阅读 / 正在检测是否收录...

    现象

    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显示出温度湿度哈,这个我就不写代码了,不然真的是再喂饭了呜呜!
    
      }
    13
    智能无源感知技术简介
    « 上一篇 2022-05-07
    【视频课程】STM32系统开发与protues仿真快速入门课
    下一篇 » 2022-04-12

    评论 (0)

    取消