使用STM32制作智能温湿度计

智能温湿度计是一种可以测量环境温度和湿度的设备,本文将使用STM32微控制器制作一个智能温湿度计。我们将使用STM32CubeMX和Keil MDK来配置和编写代码。以下是实现这个项目的详细步骤。

  1. 硬件准备 首先,我们需要准备以下硬件组件:

    • STM32微控制器开发板(例如:STM32F103C8T6)
    • 温湿度传感器(例如:DHT11)
    • LCD显示屏(例如:16x2字符LCD)
    • 杜邦线和面包板
  2. 硬件连接 将温湿度传感器和LCD显示屏连接到STM32开发板。以下是连接的示意图:

    STM32开发板       温湿度传感器           LCD显示屏
    ----------------------------------------------------
    GND ------------ GND ----------------- GND
    5V ------------- VCC ----------------- VCC
    PB6 ------------ DATA -----------------
    ----------------------------------------------------
    GND ----------------------------------- GND
    5V ------------------------------------ VCC
    PA6 ----------------------------------- RS
    PA7 ----------------------------------- E
    PB0 ----------------------------------- D4
    PB1 ----------------------------------- D5
    PB10 ---------------------------------- D6
    PB11 ---------------------------------- D7
    

  3. STM32CubeMX配置 使用STM32CubeMX工具配置STM32开发板的引脚和时钟。以下是配置步骤:

    • 打开STM32CubeMX并创建一个新项目。
    • 选择正确的STM32微控制器型号。
    • 在Pinout & Configuration选项卡中配置引脚功能。
      • 将PB6设置为GPIO_Output,并将其命名为DHT11_DATA。
      • 将PA6、PA7、PB0、PB1、PB10、PB11设置为GPIO_Output,并将其命名为LCD_RS、LCD_E、LCD_D4、LCD_D5、LCD_D6、LCD_D7。
    • 在Configuration选项卡中配置时钟。
      • 根据需求调整系统时钟和外设时钟。
  4. 生成代码 在STM32CubeMX中生成代码。这将会自动生成一个基本的代码框架和初始化函数。

  5. 编写温湿度传感器驱动程序 在生成的代码中,打开main.c文件并添加以下函数来读取温湿度传感器的数据:

    // 引用必要的头文件
    #include "stm32f1xx_hal.h"
    
    // 定义DHT11_DATA引脚
    #define DHT11_DATA_PIN GPIO_PIN_6
    #define DHT11_DATA_PORT GPIOB
    
    // DHT11传感器数据结构
    typedef struct {
        uint8_t humidity;
        uint8_t temperature;
        uint8_t checksum;
    } DHT11_Data;
    
    // DHT11传感器初始化
    void DHT11_Init(void) {
        HAL_GPIO_WritePin(DHT11_DATA_PORT, DHT11_DATA_PIN, GPIO_PIN_SET);
        HAL_Delay(1000);
    }
    
    // 读取DHT11传感器数据
    DHT11_Data DHT11_ReadData(void) {
        uint8_t data[5] = {0};
        DHT11_Data result;
    
        // 发送开始信号
        HAL_GPIO_WritePin(DHT11_DATA_PORT, DHT11_DATA_PIN, GPIO_PIN_RESET);
        HAL_Delay(18);
        HAL_GPIO_WritePin(DHT11_DATA_PORT, DHT11_DATA_PIN, GPIO_PIN_SET);
        HAL_Delay(40);
    
        // 等待DHT11响应
        while (HAL_GPIO_ReadPin(DHT11_DATA_PORT, DHT11_DATA_PIN) == GPIO_PIN_SET);
    
        // 接收传感器数据
        for (int i = 0; i < 40; i++) {
            // 等待下一个位
            while (HAL_GPIO_ReadPin(DHT11_DATA_PORT, DHT11_DATA_PIN) == GPIO_PIN_RESET);
    
            // 延迟50us以接收位数据
            HAL_Delay(50);
    
            // 如果高电平持续时间大于50us,则认为是高位
            if (HAL_GPIO_ReadPin(DHT11_DATA_PORT, DHT11_DATA_PIN) == GPIO_PIN_SET) {
                // 设置当前位为1
                data[i / 8] |= (1 << (7 - (i % 8)));
            }
        }
    
        // 检查校验和
        if (data[4] == (data[0] + data[1] + data[2] + data[3])) {
            result.humidity = data[0];
            result.temperature = data[2];
            result.checksum = data[4];
        } else {
            // 校验和错误,返回无效数据
            result.humidity = 0;
            result.temperature = 0;
            result.checksum = 0;
        }
    
        return result;
    }
    

  6. 编写LCD显示屏驱动程序 在生成的代码中,打开main.c文件并添加以下函数来控制LCD显示屏:

    // 引用必要的头文件
    #include "stm32f1xx_hal.h"
    
    // 定义LCD引脚
    #define LCD_RS_PIN GPIO_PIN_6
    #define LCD_RS_PORT GPIOA
    
    #define LCD_E_PIN GPIO_PIN_7
    #define LCD_E_PORT GPIOA
    
    #define LCD_D4_PIN GPIO_PIN_0
    #define LCD_D4_PORT GPIOB
    
    #define LCD_D5_PIN GPIO_PIN_1
    #define LCD_D5_PORT GPIOB
    
    #define LCD_D6_PIN GPIO_PIN_10
    #define LCD_D6_PORT GPIOB
    
    #define LCD_D7_PIN GPIO_PIN_11
    #define LCD_D7_PORT GPIOB
    
    // 控制LCD显示屏
    void LCD_WriteCommand(uint8_t command) {
        // 设置LCD_RS引脚为低电平以选择命令模式
        HAL_GPIO_WritePin(LCD_RS_PORT, LCD_RS_PIN, GPIO_PIN_RESET);
    
        // 发送高4位
        HAL_GPIO_WritePin(LCD_D4_PORT, LCD_D4_PIN, (command >> 4) & 0x01);
        HAL_GPIO_WritePin(LCD_D5_PORT, LCD_D5_PIN, (command >> 5) & 0x01);
        HAL_GPIO_WritePin(LCD_D6_PORT, LCD_D6_PIN, (command >> 6) & 0x01);
        HAL_GPIO_WritePin(LCD_D7_PORT, LCD_D7_PIN, (command >> 7) & 0x01);
    
        // 发送使能脉冲
        HAL_GPIO_WritePin(LCD_E_PORT, LCD_E_PIN, GPIO_PIN_SET);
        HAL_Delay(1);
        HAL_GPIO_WritePin(LCD_E_PORT, LCD_E_PIN, GPIO_PIN_RESET);
        HAL_Delay(1);
    
        // 发送低4位
        HAL_GPIO_WritePin(LCD_D4_PORT, LCD_D4_PIN, command & 0x01);
        HAL_GPIO_WritePin(LCD_D5_PORT, LCD_D5_PIN, (command >> 1) & 0x01);
        HAL_GPIO_WritePin(LCD_D6_PORT, LCD_D6_PIN, (command >> 2) & 0x01);
        HAL_GPIO_WritePin(LCD_D7_PORT, LCD_D7_PIN, (command >> 3) & 0x01);
    
        // 发送使能脉冲
        HAL_GPIO_WritePin(LCD_E_PORT, LCD_E_PIN, GPIO_PIN_SET);
        HAL_Delay(1);
        HAL_GPIO_WritePin(LCD_E_PORT, LCD_E_PIN, GPIO_PIN_RESET);
        HAL_Delay(1);
    }
    
    // 控制LCD显示屏
    void LCD_WriteData(uint8_t data) {
        // 设置LCD_RS引脚为高电平以选择数据模式
        HAL_GPIO_WritePin(LCD_RS_PORT, LCD_RS_PIN, GPIO_PIN_SET);
    
        // 发送高4位
        HAL_GPIO_WritePin(LCD_D4_PORT, LCD_D4_PIN, (data >> 4) & 0x01);
        HAL_GPIO_WritePin(LCD_D5_PORT, LCD_D5_PIN, (data >> 5) & 0x01);
        HAL_GPIO_WritePin(LCD_D6_PORT, LCD_D6_PIN, (data >> 6) & 0x01);
        HAL_GPIO_WritePin(LCD_D7_PORT, LCD_D7_PIN, (data >> 7) & 0x01);
    
        // 发送使能脉冲
        HAL_GPIO_WritePin(LCD_E_PORT, LCD_E_PIN, GPIO_PIN_SET);
        HAL_Delay(1);
        HAL_GPIO_WritePin(LCD_E_PORT

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大黄鸭duck.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值