Ai8051U+DHT11温湿度!

main.c

cpp 复制代码
#include "Ai8051U.h"
#include "Delay.h"
#include "Uart.h"
#include "DHT11.h"
#include <stdint.h>

// ---- 自定义全局变量 ----
uint16_t count = 0; // 全局计数变量(未使用)
__xdata char strbuff[128]; // 字符串缓冲区(未使用)
extern void UartIsr(void) __interrupt(4);
uint8_t temp, humi; // 温度和湿度变量
// ----------------------

void main(void)
{
    CKCON = 0;
    WTST = 0; // 看门狗关闭
    P0M0 = 0x00; P0M1 = 0x00; // 设置P0为准双向口
    P1M0 = 0x00; P1M1 = 0x00; // 设置P1为准双向口
    P2M0 = 0x00; P2M1 = 0x00; // 设置P2为准双向口
    P3M0 = 0x00; P3M1 = 0x00; // 设置P3为准双向口
    P4M0 = 0x00; P4M1 = 0x00; // 设置P4为准双向口
    P5M0 = 0x00; P5M1 = 0x00; // 设置P5为准双向口

    Uart_Init(115200UL); // 初始化UART,波特率115200
    DHT11_Init(); // 初始化DHT11传感器
    UartSendString("Hello,This is DHT11!\r\n");

    while (1)
    {
        if(DHT11_ReadData(&temp, &humi)) {
            // 成功读取数据
            sprintf(strbuff, "Temperature: %dC\r\n", temp);
            UartSendString(strbuff);
            sprintf(strbuff, "Humidity: %d%%\r\n", humi);
            UartSendString(strbuff);
        } else {
            UartSendString("DHT11 Read Error!\r\n");
        }
        delay_ms(2000); // 每2秒读取一次
    }
}

T0定时器自动重载 版本 main.c

cpp 复制代码
#include "Ai8051U.h"
#include "Delay.h"
#include "Uart.h"
#include "DHT11.h"
#include <stdint.h>

// ---- 自定义全局变量 ----
uint16_t count = 0;       // 全局计数变量(未使用)
__xdata char strbuff[64]; // 字符串缓冲区(未使用)
extern void UartIsr(void) __interrupt(4);
uint8_t temp, humi; // 温度和湿度变量
// ----------------------

// 函数声明
void Timer0_Init(void);
// ------
void main(void)
{
    CKCON = 0;
    WTST = 0; // 看门狗关闭
    P0M0 = 0x00;
    P0M1 = 0x00; // 设置P0为准双向口
    P1M0 = 0x00;
    P1M1 = 0x00; // 设置P1为准双向口
    P2M0 = 0x00;
    P2M1 = 0x00; // 设置P2为准双向口
    P3M0 = 0x00;
    P3M1 = 0x00; // 设置P3为准双向口
    P4M0 = 0x00;
    P4M1 = 0x00; // 设置P4为准双向口
    P5M0 = 0x00;
    P5M1 = 0x00; // 设置P5为准双向口

    Timer0_Init();       // 初始化定时器0,用于1ms中断
    Uart_Init(115200UL); // 初始化UART,波特率115200
    DHT11_Init();        // 初始化DHT11传感器
    UartSendString("Hello,This is DHT11!\r\n");

    while (1)
    {
        // 普通读取温湿度
        // if(DHT11_ReadData(&temp, &humi)) {
        //     // 成功读取数据
        //     sprintf(strbuff, "Temperature: %dC\r\n", temp);
        //     UartSendString(strbuff);
        //     sprintf(strbuff, "Humidity: %d%%\r\n", humi);
        //     UartSendString(strbuff);
        // } else {
        //     UartSendString("DHT11 Read Error!\r\n");
        // }
        // delay_ms(2000); // 每2秒读取一次

        // 判断Count变量
        if (count == 1999)
        {
            UartSendString("-------------\r\n");
            if (DHT11_ReadData(&temp, &humi))
            {
                // 成功读取数据
                sprintf(strbuff, "Temperature: %dC\r\n", temp);
                UartSendString(strbuff);
                sprintf(strbuff, "Humidity: %d%%\r\n", humi);
                UartSendString(strbuff);
            }
            else
            {
                UartSendString("DHT11 Read Error!\r\n");
            }
        }
    }
}

// 40MHZ / 1 = 40MHz  -> 1 tick = 0.025us = 25ns
// min 16 bit timer | 25ns <-> 1.638125ms(1628125ns)
void Timer0_Init(void) // 1ms@40MHz  -- 1T
{
    EA = 0;        // 关闭全局中断
    AUXR |= T0x12; // 定时器时钟1T模式(原本12T快12倍 就是1T 不是12*12=144T  -- 如快4T就是3T)
    TMOD &= 0xF0;  // 设置定时器模式
    TMOD |= 0x00;  // 定时器0,模式0,16位计数器 -- 自动重装模式
    // 1,000,000us / 25us 就是1ms需要的计数值
    TH0 = (65536 - (1000000 / 25)) >> 8;   // 设置定时初值,高8位
    TL0 = (65536 - (1000000 / 25)) & 0xFF; // 设置定时初值,低8位
    ET0 = 1;                               // 允许定时器0中断
    TR0 = 1;                               // 启动定时器0
    EA = 1;                                // 全局中断使能
}

void Timer0_Isr(void) __interrupt(1)
{
    count++; // 增加计数
    if (count >= 2000)
    {              // 每1000ms执行一次
        count = 0; // 重置计数器
    }
}

DHT11.h

cpp 复制代码
#ifndef __DHT11_H__
#define __DHT11_H__

#include "Ai8051U.h"
#include "Delay.h"
#include "Uart.h"
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

#define DHT11_PIN P00 // 定义DHT11数据引脚
#define DHT11_PIN_IO do { \
    P0M0 &= ~(1 << 0); /* 将 P0M0 的 Bit 0 清零 */ \
    P0M1 &= ~(1 << 0); /* 将 P0M1 的 Bit 0 清零 */ \
} while(0) // 使用 do-while(0) 确保宏在语法上像一个语句

void DHT11_Init(void);
bool DHT11_ReadData(uint8_t *temperature, uint8_t *humidity);

#endif // __DHT11_H__

DHT11.c

cpp 复制代码
#include "DHT11.h"

void DHT11_Init(void) {
    DHT11_PIN_IO; // 配置DHT11数据引脚为准双向口
    DHT11_PIN = 1; // 设置数据引脚为高电平
    delay_ms(100); // 延时100毫秒,等待传感器稳定
}

bool DHT11_StartSignal(void) {
    uint8_t timeout;
    
    DHT11_PIN = 0; // 拉低数据线
    delay_ms(20); // 延时20ms,符合DHT11要求
    
    DHT11_PIN = 1; // 拉高数据线
    delay_us(30); // 延时30us,符合标准时序(20-40us)
    
    DHT11_PIN = 1; // 显式置1,确保准双向口进入输入态
    timeout = 0; // 重置超时计数器
    while(DHT11_PIN == 1) {
        if(++timeout > 40) { // 大约40us超时
            UartSendString("DHT11 pull low timeout!\r\n"); // 串口打印超时信息,方便调试
            return false;
        }
        delay_us(1);
    }
    timeout = 0;
    while(DHT11_PIN == 0) {
        if(++timeout > 85) {
            UartSendString("DHT11 pull high timeout!\r\n"); 
            return false;
        }
        delay_us(1);
    }
    
    return true;
}

uint8_t DHT11_Receive_Byte(void) {
    uint8_t i;
    uint8_t byte = 0;
    for(i = 0; i < 8; i++) {
        while(DHT11_PIN); // 等待进入低电平
        while (!DHT11_PIN); // 等待50us低电平过去 
        delay_us(45); // 延时45us,判断高电平长度       
        if(DHT11_PIN == 1) {
            byte |= (1 << (7 - i)); // 接收1
            while(DHT11_PIN); // 等待高电平结束
        }
    }
    return byte;
}

bool DHT11_ReadData(uint8_t *temperature, uint8_t *humidity) {
    uint8_t data[5] = {0};
    // __xdata char strbuff[50];
    if(!DHT11_StartSignal()) {
        UartSendString("DHT11 not responding!\r\n");
        return false; // DHT11未响应
    }
    for(int i = 0; i < 5; i++) {
        data[i] = DHT11_Receive_Byte();
    }
    // 校验和验证
    if(data[4] != (data[0] + data[1] + data[2] + data[3])) {
        // sprintf(strbuff, "D1:%x D2:%x D3:%x D4:%x Checksum:%x\r\n", data[0], data[1], data[2], data[3], data[4]);
        // UartSendString(strbuff);
        UartSendString("DHT11 checksum error!\r\n");
        return false; // 校验失败
    }
    *humidity = data[0]; // 整数部分湿度
    *temperature = data[2]; // 整数部分温度
    return true;
}

效果

实际

__xdata char strbuff[128]; // 字符串缓冲区(未使用)

可以缩小

相关推荐
一只大马猴呀2 小时前
IntelliJ IDEA 中启动项目不显示端口号
java·ide·intellij-idea
xcs194052 小时前
前端 项目构建问题 \node_modules\loader-runner\lib\loadLoader.js
开发语言·前端·javascript
一人の梅雨2 小时前
VVIC图片搜索接口进阶实战:服装批发场景下的精准识图与批量调度方案
开发语言·机器学习·php
s1hiyu2 小时前
实时控制系统验证
开发语言·c++·算法
AC赳赳老秦2 小时前
科研数据叙事:DeepSeek将实验数据转化为故事化分析框架
开发语言·人工智能·数据分析·r语言·时序数据库·big data·deepseek
楼田莉子2 小时前
C++现代特性学习:C++14
开发语言·c++·学习·visual studio
2301_765703142 小时前
C++代码复杂度控制
开发语言·c++·算法
m0_708830962 小时前
C++中的享元模式实战
开发语言·c++·算法
naruto_lnq2 小时前
分布式计算C++库
开发语言·c++·算法