• 【GD32F427开发板试用】+DHT11温湿度监测


    本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:四季的温度

    在完成所有项目后会开源,本次依旧是想做一个通过DHT11采集信息,OLED显示,ESP8266上传,可通过小程序查看的简易智能家居事例。

    MDK环境准备

    这里遇到了不少坑,到时候专门开一篇来讲

    DHT11工作原理

    具体可看csdn这篇文章https://blog.csdn.net/m0_5678…
    简单来说就是

    /*
    数据格式:
    湿度整数 湿度小数 温度整数 温度小数 校验位
    00000000 00000000 00000000 00000000 00000000
    1 看原理图确认GPIO引脚
    2、 输出模式, 输出起始信号 :输出低电平18~30ms, 20ms
    3、 IO口配置浮空输入模式,准检测响应信号
    传感器把数据总线( SDA)拉低 83μs, 再接高 87μs 以响应主机的起始信号。
    4、 40 个位的数据,高位先发;
    一位一位的收,数据0: 54us低电平 + 23~27高电平 数据1: 54us低电平 + 68~74高电平 注意高位先发的(每个字节)
    5、校验数据
    前4个字节,求和,把和值的末八位和校验位对比 相同数据正确、否则数据异常
    */

    接下来就开始写代码了

    由于官方库的systick是ms级别的,需要改写成us级别或者另外实现,我这里都做了,各位可以按需使用~~

    第一种基于官方库systick修改为us级别

    systick.c
    void systick_config(void)
    {
        /* setup systick timer for 1000Hz interrupts */
        /*1000u是ms,1000000是us*/
        if(SysTick_Config(SystemCoreClock / 1000000U)) {
            /* capture error */
            while(1) {
            }
        }
        /* configure the systick handler priority */
        NVIC_SetPriority(SysTick_IRQn, 0x00U);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    第二种,自己重新写
    下边写的是delay_us,如果需要ms则*1000就可以了

    delay.c
     void delay_us(uint32_t nus)
    {
        int i;
        uint32_t temp;    
        for(i=0;i<8;i++)
        {
                 
        SysTick->LOAD= nus *25;                     //时间加载               
        SysTick->VAL=0x00;                            //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;    //开始倒数      
        do
        {
            temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;    //关闭计数器
        SysTick->VAL =0X00;                           //清空计数器    
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    接下来开始写DHT11的代码了,主要是调用库,开发难度很低

    dht11.c
    #include "dht11.h"
    
    void dht11_gpio_input(void)
    {
        rcu_periph_clock_enable(RCU_GPIOB);
        /*配置输入*/
        gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_12);
        gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
        
    }
    
    void dht11_gpio_output(void)
    {
    
        rcu_periph_clock_enable(RCU_GPIOB);
        /*配置下拉输出*/
        gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_12);
        gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
        
    }
    
    
    void dht11_reset(void)//复位
    {
        
        dht11_gpio_output();
        DHT11_OUT_L;
        delay_us(19000);
        DHT11_OUT_H;
        delay_us(30);
        dht11_gpio_input();
    }
    
    uint16_t dht11_scan(void)//判断总线状态
    {
        return DHT11_IN;
    }
    
    uint16_t dht11_read_bit(void)//读取一个bit
    {
        while (DHT11_IN == RESET);
        delay_us(40);
        if (DHT11_IN == SET)
        {
            while (DHT11_IN == SET);
            return 1;
        }
        else
        {
            return 0;
        }
    }
    
    uint16_t dht11_read_byte(void)//读取一个字节
    {
        uint16_t i;
        uint16_t data = 0;
        for (i = 0; i < 8; i++)
        {
            data <<= 1;
            data |= dht11_read_bit();
        }
        return data;
    }
    uint8_t checksum;
    uint16_t dht11_read_data(uint8_t buffer[5])//读取数据
    {
        uint16_t i = 0;
        
        dht11_reset();
        if (dht11_scan() == RESET)
        {
            
            while (dht11_scan() == RESET);
            while (dht11_scan() == SET);
            for (i = 0; i < 5; i++)
            {
                buffer[i] = dht11_read_byte();
            }
            
            while (dht11_scan() == RESET);
            dht11_gpio_output();
            DHT11_OUT_H;
            
             checksum = buffer[0] + buffer[1] + buffer[2] + buffer[3];
            if (checksum != buffer[4])
            {
                // checksum error
                return 1;
            }
        }
        
        return 0;
    }
    dht11.h
    #ifndef __DHT11_H__
    #define __DHT11_H__
    
    //#include "timer.h"
    #include "gd32f4xx.h"
    #include "gd32f427v_start.h"
    #include "systick.h"
    
    #define DHT11_GPIO_TYPE  GPIOB
    #define DHT11_GPIO_PIN   GPIO_PIN_12
    #define DHT11_RCC        RCC_APB2Periph_GPIOB
    
    #define DHT11_OUT_H gpio_bit_set(DHT11_GPIO_TYPE, DHT11_GPIO_PIN)
    #define DHT11_OUT_L gpio_bit_reset(DHT11_GPIO_TYPE, DHT11_GPIO_PIN)
    #define DHT11_IN    gpio_input_bit_get(DHT11_GPIO_TYPE, DHT11_GPIO_PIN)
    
    /*如果使用的是重新写delay_us,不需要下面的宏,如果是改官方的就需要*/
    #define delay_us delay_1ms
    
    #define RESET 0
    #define SET   1
    
    void dht11_gpio_input(void);
    void dht11_gpio_output(void);
    uint16_t dht11_scan(void);
    uint16_t dht11_read_bit(void);
    uint16_t dht11_read_byte(void);
    uint16_t dht11_read_data(uint8_t buffer[4]);
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126

    写完了DHT11的代码,接下来验证下
    在main里调用下

    while (1)
        {
            if (dht11_read_data(buffer) == 0)
            {
                hum = buffer[0] + buffer[1] / 10.0;
                temp1 = buffer[2] + buffer[3] / 10.0;
                printf("hum:%f,temp:%f\r\n",hum,temp1);    
            }
            delay_1ms(1000000);/*因为改了systick,没在delay_1ms所以要把它单us用*/
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    看下结果

    总结

    GD32F427使用库开发体验还行,不过像systick这个库少了delay_us得自己写或者改,要是更完善点会更好,现在已经完成了DHT11,下一步是OLED,加油

    下篇预告

    下一篇我会整理下从安装pack到跑起LED工程到写DHT11遇到的问题,给各位参考参考

  • 相关阅读:
    7-1 后序和中序构造二叉树
    大模型的实践应用2-基于BERT模型训练医疗智能诊断问答的运用研究,协助医生进行疾病诊断
    富格林:揭露黑幕平台保障安全
    【光谱-空间交互网络:Pansharpening】
    Zookeeper客户端——I0Itec-zkClient
    C goto 语句
    git 忽略已经提交的文件或文件夹 (修改.gitignore文件无效)
    odoo 按钮打印pdf报表
    系统升级丨VR会议主动呼叫,开启云洽谈新模式
    中枢神经系统解剖结构图,神经系统的解剖结构
  • 原文地址:https://blog.csdn.net/weixin_47569031/article/details/128184699