stm32f103c8t6实现单总线读取dht11温湿度(江科大模板)

1、开发环境、硬件、功能概述

开发环境:Keil uVision5 + STM32F103C8T6核心板
硬件模块:DHT11温湿度传感器、I2C接口LCD1602显示屏(也包含有四位传输模式的方式驱动lcd1602)、独立按键模块
功能概述:实时显示温湿度数据,通过三个按键(PA3切换四个阈值)支持四个阈值的按键调节(Proteus中lcd用的四位数据模式传输的数据)

2、工程结构解析

2.1. 头文件依赖关系

#include "stm32f10x.h"
#include "Delay.h"
#include "OLED.h"
#include "DHT11.h"
#include "lcd.h"
#include "key.h"
#include "string.h"
#include "stdio.h"
#include "lcd1602_i2c.h"

3、核心数据结构

DHT11_Data g_dht11_data = {0};  // 全局存储传感器数据

// 定义阈值结构体
typedef struct {
    int temp_low;
    int temp_high;
    int humidity_low;
    int humidity_high;
} Thresholds;

Thresholds thresholds = {20, 30, 40, 80}; // 默认阈值
// 当前编辑的阈值索引
uint8_t editing_index = 0;


// 函数声明
void DisplayThresholds(void);
void EditThreshold(int *value, int increment);

extern uint8_t current_mode;

4、主函数逻辑分解

int main(void)
{
	
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    // 初始化延时函数
    DelayInit();

    // 初始化四位模式LCD
    // LCD_GPIO_Init();
    // LCD_Init();

	// 初始化i2_c_LCD
    LCD1602_I2C_Init(I2C1);
	LCD1602_PrintStr("chu");


    // 初始化按键GPIO和中断
    KEY_GPIO_Init();
    KEY_EXTI_Init();

    // 初始化DHT11  
	while(DHT11_Init())
	{
	   
	  LCD1602_PrintStr("no");
      Delay_ms(1000);
	}

    while(1)
    {
        // 读取温湿度数据
        DHT11_ReadData(&g_dht11_data);

        // 检查是否有按键事件
        KeyEvent event = get_key_event();
        if(event != NO_EVENT)
        {
            switch(event)
            {
                case EVENT_MODE:
                    // 切换到下一个编辑项
                    editing_index = (editing_index + 1) % 4;
                    break;
                case EVENT_INCREASE:
                    // 增加当前编辑的阈值
                    if(editing_index == 0) EditThreshold(&(thresholds.temp_low), 1);
                    else if(editing_index == 1) EditThreshold(&(thresholds.temp_high), 1);
                    else if(editing_index == 2) EditThreshold(&(thresholds.humidity_low), 1);
                    else if(editing_index == 3) EditThreshold(&(thresholds.humidity_high), 1);
                    break;
                case EVENT_DECREASE:
                    // 减少当前编辑的阈值
                    if(editing_index == 0) EditThreshold(&(thresholds.temp_low), -1);
                    else if(editing_index == 1) EditThreshold(&(thresholds.temp_high), -1);
                    else if(editing_index == 2) EditThreshold(&(thresholds.humidity_low), -1);
                    else if(editing_index == 3) EditThreshold(&(thresholds.humidity_high), -1);
                    break;
                default:
                    break;
            }

        }
        DisplayThresholds();
        Delay_ms(100); // 简单延时,避免过于频繁的刷新
    }
}

5、 数据显示与阈值编辑函数实现

// 温度显示格式:"T:25.0 H30 L20" 
snprintf(line1, sizeof(line1), "T:%d.%d H%02d L%02d", 
        g_dht11_data.temp_int, g_dht11_data.temp_decimal,
        thresholds.temp_high, thresholds.temp_low);

// 湿度显示格式:"H:50.0% H80 L30"
snprintf(line2, sizeof(line2), "H:%d.%d H%02d L%02d",
        g_dht11_data.humidity_int, g_dht11_data.humidity_decimal,
        thresholds.humidity_high, thresholds.humidity_low);

void EditThreshold(int *value, int increment)
{
    *value += increment;
    // 边界保护逻辑
    *value = (*value < 0) ? 0 : (*value > 9999) ? 9999 : *value;
}

6、总结 

在用Proteus仿真初始化单总线读取dht11时,也就是这里DHT11_Init(),检测不到dht11。可能是单总线协议对us级时序要求十分严格(我用的系统滴答定时器延时的)。也可能我对Proteus不熟悉设置有问题,但是连接实物实验没有问题。实物跟仿真还是有差距的。 需要源码的可以在我资源下载。

    // DHT11初始化检测
    while(DHT11_Init()){
        LCD1602_PrintStr("no"); // 传感器异常提示
        Delay_ms(1000);
    }

 需要源码的可以在我资源下载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值