标题: 单片机LCD12864没有加入DHT11部分的代码时可以显示内容,加入后就不显示了 [打印本页]

作者: Qmxxxx    时间: 2023-6-9 15:16
标题: 单片机LCD12864没有加入DHT11部分的代码时可以显示内容,加入后就不显示了
怎么解决啊
#include <reg52.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define LCD_DATA P0 // 数据口
sbit LCD_RS = P2^0; // 命令/数据选择位
sbit LCD_RW = P2^1; // 读/写选择位
sbit LCD_EN = P2^2; // 使能信号位
sbit PSB = P2^6;

//定义DHT11传感器的引脚
sbit DHT11=P2^4;

void _nop_(void);

void delay(unsigned int t) { // 延时函数
    unsigned int i, j;
    for (i = t; i > 0; i--) {
        for (j = 110; j > 0; j--);
    }
}

void delay_us(int us)// 延时子程序
{
    char j;
    while(us--)
    {
        for(j=0;j<1200;j++);
    }
}

void WriteCommand(unsigned char cmd) { // 写命令函数
    LCD_RS = 0; // RS=0,选择命令
    LCD_RW = 0; // RW=0,写入数据
    LCD_DATA = cmd; // 写入命令
    LCD_EN = 1; // 使能
    _nop_(); // 等待
    LCD_EN = 0; // 失能
    delay(1); // 延时
}

void WriteData(unsigned char dat) { // 写数据函数
    LCD_RS = 1; // RS=1,选择数据
    LCD_RW = 0; // RW=0,写入数据
    LCD_DATA = dat; // 写入数据
    LCD_EN = 1; // 使能
    _nop_(); // 等待
    LCD_EN = 0; // 失能
    delay(1); // 延时
}

void InitLCD12864() { // 初始化函数
    WriteCommand(0x30); // 设置8位数据总线,基本指令集
    WriteCommand(0x0C); // 打开显示,关闭光标
    WriteCommand(0x01); // 清屏
    WriteCommand(0x06); // 设置文字写入方向,自动加地址
}

void lcd_write_str(unsigned char row, unsigned char col, char *str) { // 写字符串函数
    unsigned char addr = 0;
    if (row == 0) { // 第1行
        addr = 0x80 + col;
    } else if (row == 1) { // 第2行
        addr = 0x90 + col;
    } else if (row == 2) { // 第3行
        addr = 0x88 + col;
    } else if (row == 3) { // 第4行
        addr = 0x98 + col;
    }
    WriteCommand(addr); // 设置DDRAM地址
    while (*str != '\0') { // 写入字符串
        WriteData(*str++);
    }
}


void DHT11_start() { // 启动DHT11传感器函数
    DHT11 = 0; // 拉低数据线
    delay_us(18000); // 延时18ms
    DHT11 = 1; // 拉高数据线
    delay_us(40); // 延时40us
    while (!DHT11); // 等待DHT11响应
    while (DHT11); // 等待DHT11响应结束
}

void DHT11_read_data(unsigned char *humi, unsigned char *temp) {
    unsigned char i, j, f[5] = {0, 0, 0, 0, 0};
    DHT11_start(); // 启动DHT11传感器
    // 发送起始信号
    DHT11 = 1;
    delay_us(40);
    DHT11 = 0;
    delay_us(20);
    DHT11 = 1;
    // 等待DHT11响应
    while (!DHT11);
    while (DHT11);
    while (!DHT11);
    // 读取数据
    for (i = 0; i < 5; i++) {
        for (j = 0; j < 8; j++) {
            while (!DHT11);
            delay_us(30);
            if (DHT11) {
                f[ i] |= (1 << (7 - j));
            }
            while (DHT11);
        }
    }
    // 验证数据
    if ((f[0] + f[1] + f[2] + f[3]) == f[4]) {
        *humi = f[0]; // 湿度
        *temp = f[2]; // 温度
    } else {
        *humi = 0;
        *temp = 0;
    }
    delay(2000); // 延时2秒等待下一次读取
}



void main() {
    unsigned char humi, temp; // 定义温湿度变量
    char temp_str[5], humi_str[5]; // 定义字符串变量,用于存放温湿度值
    InitLCD12864(); // 初始化LCD12864显示屏
    while (1) {
        DHT11_read_data(&humi, &temp); // 读取温湿度数据
        sprintf(temp_str, "%d", temp); // 将温度值转换为字符串类型
        sprintf(humi_str, "%d", humi); // 将湿度值转换为字符串类型
        lcd_write_str(0, 0, "当前温度:"); // 在第1行第1列显示"当前温度:"
        lcd_write_str(1, 0, "当前湿度:"); // 在第2行第1列显示"当前湿度:"
        lcd_write_str(0, 7, temp_str); // 在第1行第7列显示当前温度
        lcd_write_str(1, 7, humi_str); // 在第2行第7列显示当前湿度
        delay(1000); // 延时1秒
    }
}

作者: 暖西夏    时间: 2023-6-9 19:12
因为你DHT11的延时太长了,LCD屏幕是SPI驱动的,对时序有一定要求
作者: Qmxxxx    时间: 2023-6-9 20:22
暖西夏 发表于 2023-6-9 19:12
因为你DHT11的延时太长了,LCD屏幕是SPI驱动的,对时序有一定要求

可是DHT11好像就是要两秒才能读取一次
作者: 君工创    时间: 2023-6-10 06:52
while (DHT11); // 等待DHT11响应结束 }到这里还能出来吗?
作者: 热度三分    时间: 2023-6-10 09:21
这个情况很明显是在DHT11程序里没跳出来,猜测是你的几个while函数导致一直在死循环。你可以把while注释掉再试试
作者: wys91203    时间: 2023-6-10 10:38
把 lcd_write_str(0, 0, "当前温度:"); // 在第1行第1列显示"当前温度:"放在WHILE(1)之前,在主循环之前让12864显示,之后慢慢调显示数据.
作者: Qmxxxx    时间: 2023-6-10 21:33
热度三分 发表于 2023-6-10 09:21
这个情况很明显是在DHT11程序里没跳出来,猜测是你的几个while函数导致一直在死循环。你可以把while注释掉 ...

注释掉也不显示
作者: 51jia    时间: 2023-6-10 22:16
用定时器定时3S刷新DHT11,时间到读取数据再更新显示数据就好。




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1