历史上的今天
返回首页

历史上的今天

今天是:2024年09月10日(星期二)

正在发生

2021年09月10日 | STM32F103C8T6+温湿度传感器DHT11实现温湿度采集

2021-09-10 来源:eefocus

通信原理

单总线通信

DHT11器件采用简化的单总线通信。单总线只有一根数据线,主从机之间的数据交换、控制命令等均由单总线完成。在单总线系统中,只有当主机呼叫从机时,从机才能应答。


挂载于单总线上的设备,必须通过一个漏极开路或三态端口连接至该数据线,以允许设备在不发生数据时能够释放总线。单总线通常要求外接一个4.7kΩ的上拉电阻,这样,当总线闲置时,总线上始终是高电平


传输数据位定义

一次传送40位数据,高位先出。数据格式位:


8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位。

注:其中湿度小数部分为0。


校验位的数据定义:


“8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据”


8bit校验位等于所得结果的末8位。


数据传输时序:

数据传输时序图

数据采集流程

首先,对MCU进行初始化,将MCU的I/O口设置推挽输出,有上拉电阻。代码见下:

/*Configure GPIO pin : DHT11_Pin */

GPIO_InitStruct.Pin = DHT11_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);


MCU发送开始信号——I/O口输出低电平,最少不小于18ms,最大不大于30ms。


将MCU的I/O设置为浮空输入状态,等待DHT11的应答信号,总线由于上拉电阻的存在变为高电平,设置I/O的代码如下:


/*

 * 函数名:DHT11_Mode_IPU

 * 描述  :使DHT11-DATA引脚变为浮空输入模式

 * 输入  :无

 * 输出  :无

 */

void DHT11_Mode_IPU(void)

{

    GPIO_InitTypeDef GPIO_InitStruct;

    /*选择要控制的DHT11_GPIO_PORT引脚*/

    GPIO_InitStruct.Pin=DHT11_Pin;

    /*设置引脚模式为浮空输入模式*/

    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    /*调用库函数,初始化DHT11_GPIO_PORT*/

    HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);

}


接下来就是DHT11向MCU发送数据的过程。


首先,在DHT11检测到外部有MCU发来的低电平信号时,等外部信号低电平结束后,延迟后输出83us的低电平作为应答信号,紧接着输出87us的高电平通知外设准备接收。

在这里插入图片描述

MCU延时30us后,检测总线上是否出现低电平(应答信号),如不响应则返回error信息。如响应后先等待低电平结束,再等待高电平结束,即可开始接收40位有效数据。

位数据“0”的格式为:54微秒的低电平和23-27微秒的高电平,位数据“1”的格式为:54微秒的低电平加68-74微秒的高电平

在这里插入图片描述

MCU等待低电平结束,根据DHT11中0、1的表示方法可知,通过检测x毫秒后总线上的电平状态即可获得数据,此处的x大于数据’0‘高电平的持续时间。此处需要注意的是,数据为高位先出。代码如下:

/*

 * 从DHT11读取一个字节,MSB先行

 */

uint8_t DHT11_ReadByte ( void )

{

    uint8_t i, temp=0;



    for(i=0;i<8;i++)

    {

        /*每bit以50us低电平标置开始,轮询直到从机发出的50us 低电平 结束*/

        while(DHT11_Dout_IN()==GPIO_PIN_RESET);


        /*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,

         *通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时

         */

        CPU_TS_Tmr_Delay_US(30); //延时x us 这个延时需要大于数据0持续的时间即可


        if(DHT11_Dout_IN()==GPIO_PIN_SET)/* x us后仍为高电平表示数据“1” */

        {

            /* 等待数据1的高电平结束 */

            while(DHT11_Dout_IN()==GPIO_PIN_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;


}


MCU再读取完40位数据后,需要检查数据的正确性。

校验位的数据定义:


“8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据”


8bit校验位等于所得结果的末8位。


至此就完成了DHT11的一次数据采集。下面是一次完整采集的函数代码:


/*

 * 一次完整的数据传输为40bit,高位先出

 * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和

 */

uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)

{

    /*输出模式*/

    DHT11_Mode_Out_PP();

    /*主机拉低*/

    DHT11_Dout_0;

    /*延时18ms*/

    HAL_Delay(25);


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

    DHT11_Dout_1;


    CPU_TS_Tmr_Delay_US(30);   //延时30us

    /*主机设为输入 判断从机响应信号*/

    DHT11_Mode_IPU();


    /*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/

    if(DHT11_Dout_IN()==GPIO_PIN_RESET)

    {

        /*轮询直到从机发出 的80us 低电平 响应信号结束*/

        while(DHT11_Dout_IN()==GPIO_PIN_RESET);


        /*轮询直到从机发出的 80us 高电平 标置信号结束*/

        while(DHT11_Dout_IN()==GPIO_PIN_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();

        /*主机拉高*/

        DHT11_Dout_1;


        /*检查读取的数据是否正确*/

        if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)

            return SUCCESS;

        else

            return ERROR;

    }


    else

        return ERROR;


}

推荐阅读

史海拾趣

Hirose公司的发展小趣事

对于单级PFC电路,网友可能还会有多种问题,以下是一些常见问题及其回答:

一、技术原理与特性

  1. 单级PFC电路的基本工作原理是什么?
    • 回答:单级PFC电路通过共用一个开关管和一套PWM控制电路,同时实现功率因数校正(PFC)和对输出电压的调节。它通常由升压型PFC级和DC-DC变换器组合而成,两部分电路共用一个开关,通过控制开关的通断,电路同时完成对AC输入电流的整形和对输出电压的调节。
  2. 单级PFC电路相比两级PFC电路有哪些优缺点?
    • 回答:优点包括电路结构简单、成本较低、效率较高(在某些设计下)。缺点则在于PFC和对输入电流谐波抑制的效果可能不如两级PFC电路,且在某些应用中可能面临安规问题。

二、设计与应用

  1. 如何设计单级PFC电路以满足特定的功率因数要求?
    • 回答:设计单级PFC电路以满足特定功率因数要求时,需要考虑电感的选择、开关管的选型、控制电路的设计以及反馈机制等因素。通过精确控制开关管的通断时间和占空比,可以实现对输入电流的整形,从而改善功率因数。此外,还可以采用有源钳位和软开关技术来进一步提高效率并降低开关损耗。
  2. 单级PFC电路在哪些应用场景中较为常见?
    • 回答:单级PFC电路因其结构简单、成本较低而广泛应用于各种需要功率因数校正的电子设备中,如LED驱动电源、电源适配器、开关电源等。特别是在对成本有一定要求的场合,单级PFC电路更具竞争力。

三、故障与调试

  1. 单级PFC电路在调试过程中可能会遇到哪些常见问题?
    • 回答:在调试单级PFC电路时,可能会遇到次级去电流检测电阻过大、光耦供电电阻过大、比较器电流反馈电容过大等问题。这些问题可能导致PFC电路无法正常工作或性能下降。解决方法包括调整相关电阻和电容的数值、检查电路连接是否正确、更换损坏的元件等。
  2. 如何诊断和解决单级PFC电路中的故障?
    • 回答:诊断和解决单级PFC电路中的故障时,首先需要检查电路中的保险丝是否熔断、MOS管是否损坏或过热、反馈控制元件是否失效以及负载是否存在故障等。通过逐一排查这些可能的问题点,可以定位故障原因并采取相应的修复措施。在检修过程中,需要注意安全操作规范,避免触碰高压部位并断开电源。

四、性能优化

  1. 如何优化单级PFC电路的性能?
    • 回答:优化单级PFC电路的性能可以从多个方面入手,包括优化电感的设计以减小损耗、选择合适的开关管和二极管以降低导通压降和反向恢复时间、改进控制算法以提高控制精度和响应速度等。此外,还可以采用有源钳位和软开关技术来进一步降低开关损耗并提高整体效率。
  2. 单级PFC电路的效率如何提升?
    • 回答:提升单级PFC电路的效率可以通过多种方法实现,包括优化电路拓扑结构、选用高效率的开关管和二极管、降低电路中的寄生参数和损耗、采用先进的控制算法等。此外,合理设计散热系统以确保开关管和其他关键元件在正常工作温度下运行也是提高效率的重要手段之一。
Dover Corporation公司的发展小趣事

作为一家多元化制造商,Dover Corporation一直致力于创新技术的研发与应用。公司在多个领域拥有先进的技术和解决方案,如先进的电梯控制系统、高效的燃料解决方案等。这些技术的应用不仅提高了Dover产品的性能和质量,也为客户提供了更加优质的服务。

Deutsch公司的发展小趣事

在竞争激烈的电子行业中,品质控制和品牌建设至关重要。Deutsch公司深知这一点,因此始终将品质控制和品牌建设作为公司的重要任务。公司建立了严格的质量管理体系,确保产品的每一个细节都符合高标准。同时,通过精心策划的品牌推广活动,Deutsch公司的品牌形象逐渐深入人心。这些努力不仅提升了公司的市场地位,也增强了客户对公司的忠诚度。

北京人民电器厂公司的发展小趣事

随着北京人民电器产品的不断优化和升级,其生产的GM系列直流断路器在发电、输变电系统中得到了广泛应用。众多电力企业和项目都选择了北京人民电器的产品,这不仅是对其产品质量和技术水平的认可,也进一步推动了公司在电力行业的深入发展。

Electro-Term/Hollingsworth公司的发展小趣事

面对全球电子市场的不断变化,Electro-Term公司及时调整了市场布局和战略方向。公司深入分析了不同地区的市场需求和消费者偏好,制定了有针对性的市场推广策略。同时,公司还加强了与国际知名企业的合作,共同开发新技术和产品。这些努力使Electro-Term在全球市场上取得了显著的成绩。

ELNA(依娜)公司的发展小趣事

随着全球对环保和可持续发展的重视,ELNA也开始关注绿色制造和环保产品。公司积极采用环保材料和清洁能源,减少生产过程中的污染和排放。同时,ELNA还加强了对废旧产品的回收和再利用,推动循环经济的发展。

问答坊 | AI 解惑

BitBlt的效率问题

现在用的ARM920T, 400M的cpu,Bitblt 640*480的 位图 用时0.5ms。太慢了,画面有明显的从上到下显示的感觉。 大家贴位图都是怎么贴的?有更快的方法吗? 还有一个疑问,系统的窗口为什么能显示的那么快,而没有从上到下显示的感觉? 或者需要更 ...…

查看全部问答>

如何将速度为12MBaud的uart数据传给电脑?

大家好,我现在有一个uart设备要工作在12MBaud的波特率,请问应该怎样把速度传输到电脑?…

查看全部问答>

请教一个命令行编译问题

我在命令行下编译一个exe工程的时候, 老是报不能打开libc.lib库文件. 我用IDE直接编译却没有问题。 我用同样的方法编译静态库工程都没有任何问题,就编译dll和exe工程就有如此问题。请叫高人是何原因,谢谢! 补充:我编译的是EVC工程 报错如下 ...…

查看全部问答>

ARM9读数据口的问题

ARM9中有DATA0-DATA31,先在想从这几个口中读取数据,应该怎么办啊???…

查看全部问答>

错误调用分析---Verilog案例

Error (10207): Verilog HDL error at liftime.v(132): can\'t resolve reference to object \"interrput\"是为什么啊? 程序这是调用语句always @ ( posedge clk)           if(oflag) led_ro = interrput(ios,iom, ...…

查看全部问答>

TI(德州仪器) ZigBee 培训会邀请函

尊敬的客户: 您好! 为了让广大用户更好得了解和使用ZigBee协议栈,产品及其开发套件。我司特联合深圳市无线龙电子科技有线公司,共同举办TI ZigBee培训会。我们荣幸得邀请您参加此次活动。具体安排如下:   地点: 江苏省无锡市无锡 ...…

查看全部问答>

12864

本帖最后由 paulhyde 于 2014-9-15 03:39 编辑  …

查看全部问答>

MSP430单片机C语言应用程序设计实例精讲-书pdf

MSP430单片机C语言应用程序设计实例精讲-书pdf…

查看全部问答>