STM32作业实现(五)温湿度传感器dht11

目录

STM32作业设计
STM32作业实现(一)串口通信
STM32作业实现(二)串口控制led
STM32作业实现(三)串口控制有源蜂鸣器
STM32作业实现(四)光敏传感器
STM32作业实现(五)温湿度传感器dht11
STM32作业实现(六)闪存保存数据
STM32作业实现(七)OLED显示数据
STM32作业实现(八)触摸按键TPAD
STM32作业实现(九)驱动舵机
源码位置

编写dht11(温湿度传感器)驱动文件

打开pa7引脚用于传输数据,tim1用做计时器(微秒级定时器,因为时钟频率72MHz,分频72之后计数一次为1us)

在项目所在路径的Core目录中Src下添加源文件,Inc下添加头文件

Keil uVision5中添加新建的源文件,在源文件中include头文件后编译



core下的src 新建并添加一个dht11.c的文件,在core下的Inc也同步新建dht11.h的空文件

编写驱动文件内容

dht11.h

c 复制代码
#ifndef __DHT11_H__
#define __DHT11_H__

#include "main.h"
#include "tim.h"

uint8_t DHT_read(void); // 读取温湿度

#endif

dht11.c

c 复制代码
#include "dht11.h"

uint8_t dht11_data[5] = {0, 0, 0, 0, 0};

// 将GPIO引脚设置为输出
void SET_PIN_OUTPUT()
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /*Configure GPIO pin : PA7 */
  GPIO_InitStruct.Pin = GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 输出模式
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
// 将GPIO引脚设置为输入
void SET_PIN_INPUT()
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /*Configure GPIO pin : PA7 */
  GPIO_InitStruct.Pin = GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 输入模式
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
// 微秒级延时
void Delay_us(uint16_t us)
{
  uint16_t us_cnt = us;
  __HAL_TIM_SET_COUNTER(&htim1, 0); // 设置计数器起始值
  HAL_TIM_Base_Start(&htim1);       // 启动定时器
  while (htim1.Instance->CNT < us_cnt)
    ; // 循环等待
  HAL_TIM_Base_Stop(&htim1);
}
// 电平读取函数,每8个电平存一个字节
uint8_t DGT_read_byte()
{
  uint8_t read_byte; // 读取到的电平
  uint8_t hp = 0;    // 防止死循环
  for (uint8_t i = 0; i < 8; i++)
  {
    read_byte <<= 1;
    // 先判断此时引脚的电平状态,如果是低电平就一直循环等待,
    while ((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_RESET) && hp < 100)
    {
      Delay_us(1); // 等待1us
      hp++;
    }
    // 直到高电平出现,高电平出现后延时 40us,
    Delay_us(40);
    // 并读取延时后的电平状态,如果此时是高电平,则数据为 1,否则为 0
    if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_SET)
    {
      read_byte++;
    }
    hp = 0;
    // 等待低电平到来,开启下一次读取数据或结束
    while ((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_SET) && hp < 100)
    {
      Delay_us(1); // 等待1us
      hp++;
    }
  }

  return read_byte;
}
// DHT11温湿度读取程序
uint8_t DHT_read(void)
{
  // 总线控制权在32
  // 发送18毫秒低电平
  SET_PIN_OUTPUT();                                     // 将引脚设置为输出
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET); // 设置低电平
  HAL_Delay(18);

  // 拉高一段时间高电平
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
  Delay_us(20);

  // 总线控制在DHT11
  SET_PIN_INPUT();
  // 如果读取到低电平,说明DHT11有响应
  if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_RESET)
  {
    uint8_t hp = 0; // 防卡死
    // 等待反转高电平
    while ((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_RESET) && hp < 100)
    {
      Delay_us(1);
      hp++;
    }
    hp = 0;
    // 等待低电平到来,低电平到来后读取数据
    while ((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_SET) && hp < 100)
    {
      Delay_us(1);
      hp++;
    }
    // 开始读取数据
    for (uint8_t i = 0; i < 5; i++)
    {
      dht11_data[i] = DGT_read_byte();
    }
    // 读取结束等待50us
    Delay_us(50);
    // 校验数据
    uint32_t sum = dht11_data[0] + dht11_data[1] + dht11_data[2] + dht11_data[3];
    if ((sum & 0x000000ff) == dht11_data[4])
      return 1;
  }
  return 0;
}
相关推荐
星汇极客4 分钟前
【星汇极客】单片机竞赛之2024睿抗机器人大赛-火线速递赛道(持续更新)
stm32·单片机·嵌入式硬件·机器人
嵌联驰1 小时前
【S32K3 RTD MCAL 篇1】 K344 KEY 控制 EMIOS PWM
单片机
Daemon.Chen1 小时前
【STM32开发之寄存器版】(五)-窗口看门狗WWDG
stm32·单片机·嵌入式硬件
嵌入式杂谈3 小时前
STM32中断编程详解:配置外部中断和中断服务例程
stm32·单片机·嵌入式硬件
光子物联单片机4 小时前
传感器模块编程实践(三)舵机+超声波模块融合DIY智能垃圾桶模型
stm32·单片机·嵌入式硬件·mcu
嵌入式杂谈6 小时前
STM32中断编程指南:NVIC和中断优先级
stm32·单片机·嵌入式硬件
xiaobuding_QAQ7 小时前
自用Proteus(8.15)常用元器件图示和功能介绍(持续更新...)
单片机·嵌入式硬件·学习·proteus
zxfly20139 小时前
STM32的DMA技术介绍
stm32·单片机·嵌入式硬件
CV金科14 小时前
蓝桥杯—STM32G431RBT6(IIC通信--EEPROM(AT24C02)存储器进行通信)
stm32·单片机·嵌入式硬件·算法·蓝桥杯
嵌入式详谈16 小时前
基于STM32的智能风扇控制系统设计
stm32·单片机·嵌入式硬件