【WCH】CH32F203读取DHT11数据

【WCH】CH32F203读取DHT11数据

  • ✨CH32F203可以直接使用上面的STM32工程修改为对应的WCH型号单片机,使用WCH-DAP进行烧录,完全可以运行,比从官方的SDK工程创建出来的工程,printf函数输出温度符号()时,Keil会报警告,串口输出这个,会出现乱码。

在这里插入图片描述

  • 🔖CH32工程
    在这里插入图片描述

  • 🔖STM32工程
    在这里插入图片描述

  • 🌿keil c编译器处理汉字字符串时,会提示“warning: #870-D: invalid multibyte character sequence”。处理方式:

在源文件中加入编译器选项,#pragma  diag_suppress 870,就可以禁止出现这个warning消息了。
或在编译选项里Misc Controls添加
--diag_suppress=870
  • 🌿温湿度传感器
    在这里插入图片描述

📓CH32驱动代码

  • 🌿DHT11.C
#include "dht11.h"
#include "debug.h"

/* DHT11延时函数使用DWT外设实现,因为SysTick的延时精度被设置为了1ms,不能提供us级别的延时 */

#define DHT11_DELAY_US(us)  Delay_Us(us)
#define DHT11_DELAY_MS(ms)  Delay_Ms(ms)

static void    DHT11_GPIO_Config(void);
static void    DHT11_Mode_IPU(void);
static void    DHT11_Mode_Out_PP(void);
static uint8_t DHT11_ReadByte(void);

/**
 * @brief  DHT11 初始化函数
 * @param  无
 * @retval 无
 */
void DHT11_Init(void)
{
    DHT11_GPIO_Config();

    macDHT11_Dout_1;               // 拉高GPIOB10
}


/*
 * 函数名:DHT11_GPIO_Config
 * 描述  :配置DHT11用到的I/O口
 * 输入  :无
 * 输出  :无
 */
static void DHT11_GPIO_Config(void)
{
    /*定义一个GPIO_InitTypeDef类型的结构体*/
    GPIO_InitTypeDef GPIO_InitStructure;


    /*开启macDHT11_Dout_GPIO_PORT的外设时钟*/
    macDHT11_Dout_SCK_APBxClock_FUN(macDHT11_Dout_GPIO_CLK, ENABLE);

    /*选择要控制的macDHT11_Dout_GPIO_PORT引脚*/
    GPIO_InitStructure.GPIO_Pin = macDHT11_Dout_GPIO_PIN;

    /*设置引脚模式为通用推挽输出*/
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    /*设置引脚速率为50MHz */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    /*调用库函数,初始化macDHT11_Dout_GPIO_PORT*/
    GPIO_Init(macDHT11_Dout_GPIO_PORT, &GPIO_InitStructure);

}


/*
 * 函数名:DHT11_Mode_IPU
 * 描述  :使DHT11-DATA引脚变为上拉输入模式
 * 输入  :无
 * 输出  :无
 */
static void DHT11_Mode_IPU(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /*选择要控制的macDHT11_Dout_GPIO_PORT引脚*/
    GPIO_InitStructure.GPIO_Pin = macDHT11_Dout_GPIO_PIN;

    /*设置引脚模式为浮空输入模式*/
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;

    /*调用库函数,初始化macDHT11_Dout_GPIO_PORT*/
    GPIO_Init(macDHT11_Dout_GPIO_PORT, &GPIO_InitStructure);

}


/*
 * 函数名:DHT11_Mode_Out_PP
 * 描述  :使DHT11-DATA引脚变为推挽输出模式
 * 输入  :无
 * 输出  :无
 */
static void DHT11_Mode_Out_PP(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /*选择要控制的macDHT11_Dout_GPIO_PORT引脚*/
    GPIO_InitStructure.GPIO_Pin = macDHT11_Dout_GPIO_PIN;

    /*设置引脚模式为通用推挽输出*/
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    /*设置引脚速率为50MHz */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    /*调用库函数,初始化macDHT11_Dout_GPIO_PORT*/
    GPIO_Init(macDHT11_Dout_GPIO_PORT, &GPIO_InitStructure);

}


/*
 * 从DHT11读取一个字节,MSB先行
 */
static uint8_t DHT11_ReadByte(void)
{
    uint8_t i, temp = 0;


    for(i = 0; i < 8; i++)
    {
        /*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/
        while(macDHT11_Dout_IN() == Bit_RESET);

        /*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,
         *通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时
         */
        DHT11_DELAY_US(40); //延时x us 这个延时需要大于数据0持续的时间即可

        if(macDHT11_Dout_IN() == Bit_SET) /* x us后仍为高电平表示数据“1” */
        {
            /* 等待数据1的高电平结束 */
            while(macDHT11_Dout_IN() == Bit_SET);

            temp |= (uint8_t)(0x01 << (7 - i)); //把第7-i位置1,MSB先行
        }
        else	 // x us后为低电平表示数据“0”
        {
            temp &= (uint8_t)~(0x01 << (7 - i)); //把第7-i位置0,MSB先行
        }
    }

    return temp;

}


/*
 * 一次完整的数据传输为40bit,高位先出
 * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和
 */
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef* DHT11_Data)
{
    /*输出模式*/
    DHT11_Mode_Out_PP();
    /*主机拉低*/
    macDHT11_Dout_0;
    /*延时18ms*/
    DHT11_DELAY_MS(22);

    /*总线拉高 主机延时30us*/
    macDHT11_Dout_1;

    DHT11_DELAY_US(40);   //延时30us

    /*主机设为输入 判断从机响应信号*/
    DHT11_Mode_IPU();

    /*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/
    if(macDHT11_Dout_IN() == Bit_RESET)
    {
        /*轮询直到从机发出 的80us 低电平 响应信号结束*/
        while(macDHT11_Dout_IN() == Bit_RESET);

        /*轮询直到从机发出的 80us 高电平 标置信号结束*/
        while(macDHT11_Dout_IN() == Bit_SET);

        /*开始接收数据*/
        DHT11_Data->humi_int = DHT11_ReadByte();

        DHT11_Data->humi_deci = DHT11_ReadByte();

        DHT11_Data->temp_int = DHT11_ReadByte();

        DHT11_Data->temp_deci = DHT11_ReadByte();

        DHT11_Data->check_sum = DHT11_ReadByte();


        /*读取结束,引脚改为输出模式*/
        DHT11_Mode_Out_PP();
        /*主机拉高*/
        macDHT11_Dout_1;

        /*检查读取的数据是否正确*/
        if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int + DHT11_Data->temp_deci)
            return 1;
        else
            return 0;
    }

    else
        return 0;

}
/*************************************END OF FILE******************************/

  • 🌿DHT11.h
#ifndef __DHT11_H
#define	__DHT11_H


#include "ch32f20x.h"

/************************** DHT11 数据类型定义********************************/
typedef struct
{
    uint8_t  humi_int;		//湿度的整数部分
    uint8_t  humi_deci;	 	//湿度的小数部分
    uint8_t  temp_int;	 	//温度的整数部分
    uint8_t  temp_deci;	 	//温度的小数部分
    uint8_t  check_sum;	 	//校验和

} DHT11_Data_TypeDef;


/************************** DHT11 连接引脚定义********************************/

#define      macDHT11_Dout_SCK_APBxClock_FUN              RCC_APB2PeriphClockCmd
#define      macDHT11_Dout_GPIO_CLK                       RCC_APB2Periph_GPIOB

#define      macDHT11_Dout_GPIO_PORT                      GPIOB
#define      macDHT11_Dout_GPIO_PIN                       GPIO_Pin_7



/************************** DHT11 函数宏定义********************************/
#define macDHT11_Dout_0	   GPIO_ResetBits ( macDHT11_Dout_GPIO_PORT, macDHT11_Dout_GPIO_PIN )
#define macDHT11_Dout_1	   GPIO_SetBits ( macDHT11_Dout_GPIO_PORT, macDHT11_Dout_GPIO_PIN )

#define macDHT11_Dout_IN() GPIO_ReadInputDataBit ( macDHT11_Dout_GPIO_PORT, macDHT11_Dout_GPIO_PIN )


/************************** DHT11 函数声明 ********************************/
void DHT11_Init(void);
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef* DHT11_Data);

#endif
/* __DHT11_H */


  • 📝主程序代码
#include <stdio.h>
#include "led.h"
#include "DHT11.h"


/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    DHT11_Data_TypeDef DHT11_Data = {0};
    
    Delay_Init();//延时函数初始化
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);
		
//    LED_Init();//初始化
    DHT11_Init();
    printf("Init \r\n");

    while(1)
    {
//        LED0 = 1;
//        LED1 = 0;
        Delay_Ms(1000);
//        LED0 = 0;
//        LED1 = 1;
        if(!DHT11_Read_TempAndHumidity(&DHT11_Data))
        {
            printf("read dht11 error \n");
        }//读取温湿度,并且校验读取的示数是否准确
        else
            printf("Temp:%02d.%02d℃ Humi:%02d.%02d %%RH \n", DHT11_Data.temp_int, DHT11_Data.temp_deci, DHT11_Data.humi_int, DHT11_Data.humi_deci);
        Delay_Ms(1000);

    }
}

📚程序源码

  • ⚡新环境需要重新指定库函数头文件路径,否则编译回报错!
链接: https://pan.baidu.com/s/1yvcOhGbiBtZGKaI5SKTecQ
提取码: h6r5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值