沥沥小鱼 2024-02-06 17:50 采纳率: 45.5%
浏览 30
已结题

关于#51单片机#的问题:温度报警系统(相关搜索:红外遥控器|温度传感器|红外遥控)

题目: 温度监测系统
利用51单片机,通过红外遥控器,DS18B20温度传感器(单片机自带),LCD1602显示屏,做一个温度监测系统
(1)通过红外遥控,能够设置温度阚值和电机转速
(2)能够在LCD1602显示屏上显示实时温度和电机转速
(3)温度超出值时蜂鸣器报警,电机转动 (电机转速使用PWM波实现)
(4)温度低于闯值时解除报警,电机停止,小灯全亮

请问这个主函数有什么问题呀,没有报错没有警告,但现象就是LCD屏不显示任何东西,DS18B20也没工作

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "IR.h"
#include "Buzzer.h"
#include "AT24C02.h"
#include "motor.h"
#include "DS18B20.h"
#include "Timer0.h"
#include "OneWire.h"
#include "I2C.h"
#include "Int0.h"

float T,TShow;
char TLow,THigh;
unsigned char KeyNum;
unsigned char Address;
unsigned char Command;
void main()
{
    IR_Init();
    DS18B20_ConvertT();        //上电先转换一次温度,防止第一次读数据错误
    Delay(1000);            //等待转换完成
    THigh=AT24C02_ReadByte(0);    //读取温度阈值数据
    TLow=AT24C02_ReadByte(1);
    while(1)
    {
        if(IR_GetDataFlag() || IR_GetRepeatFlag())    //如果收到数据帧或者收到连发帧
        {
            Address=IR_GetAddress();        //获取遥控器地址码
            Command=IR_GetCommand();        //获取遥控器命令码
            /*温度读取及显示*/
           DS18B20_ConvertT();    //转换温度
           T=DS18B20_ReadT();    //读取温度
           if(T<0)                //如果温度小于0
           {
              LCD_ShowChar(1,3,'-');    //显示负号
              TShow=-T;        //将温度变为正数
           }
           else                //如果温度大于等于0
           {
              TShow=T;
           }
           LCD_ShowNum(1,4,TShow,3);        //显示温度整数部分
           LCD_ShowChar(1,7,'.');        //显示小数点
           LCD_ShowNum(1,8,(unsigned long)(TShow*100)%100,2);//显示温度小数部分
            if(Command==IR_VOL_MINUS)        //如果遥控器VOL-按键按下
            {
                    THigh++;                
            }
            if(Command==IR_VOL_ADD)            //如果遥控器VOL+按键按下
            {
                    THigh--;        
            }
            if(Command==IR_POWER)
            {
                TLow++;
            }
            if(Command==IR_MODE)
            {
                  TLow--;
            }
             LCD_Init();
         LCD_ShowString(2,1,"TH:");
         LCD_ShowString(2,9,"TL:");
         LCD_ShowSignedNum(2,4,THigh,3);
         LCD_ShowSignedNum(2,12,TLow,3);
         Timer0_Init();
              
            AT24C02_WriteByte(0,THigh);        //写入到At24C02中保存
            Delay(5);
            AT24C02_WriteByte(1,TLow);
            Delay(5);
        }
        if(T>THigh)            //如果高出阈值
        {
            motor();   //直流电机运转
            Buzzer_Time(100);  //蜂鸣器报警
        }
        else if(T<TLow) //如果低于阈值
        {
            P2=0;      //小灯全亮
        }
    }
}


  • 写回答

15条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-02-06 17:51
    关注
    获得10.00元问题酬金

    引自免费微信小程序:皆我百晓生

    在分析代码前,我注意到您提到的现象是LCD1602显示屏不显示任何内容且DS18B20温度传感器没有工作。针对您的问题,以下是对主函数进行逐段分析并提出可能存在的问题:

    1. 初始化部分:首先,确保所有相关外设(如IR遥控器、LCD1602、DS18B20等)的初始化函数已正确实现并在main()函数开始时调用。根据您提供的代码,可以看到IR_Init()在一开始就进行了调用,但LCD1602和DS18B20的相关初始化并未在循环之外完成全局初始化,而是在每次收到红外遥控信号后才初始化。应将LCD1602和DS18B20的初始化移动到主循环之前。
    void main()
    {
        IR_Init();
        LCD_Init(); // 移动到此处,保证只初始化一次
        DS18B20_Init(); // 如果有此初始化函数,则应在此处调用
        ...
    }
    
    1. 温度读取及显示:在循环内处理红外遥控信号的同时,也进行了温度转换和读取。但是,这里可能存在一个逻辑上的错误,即温度转换(DS18B20_ConvertT())和读取(DS18B20_ReadT())应当在一个稳定的延时之后进行,以确保转换完成后再读取。因此,在调用DS18B20_ReadT()之前,需要等待一定时间(通常为750微秒左右)。

    2. LCD显示:虽然在处理遥控信号时更新了温度显示,但是LCD_ShowString()LCD_ShowSignedNum()用于显示阈值的代码也应该独立于遥控器事件,应该在循环中始终进行显示更新,而不是仅在接收到遥控指令时才更新。

    修正后的主循环可能如下:

    void main()
    {
        IR_Init();
        LCD_Init();
        DS18B20_Init();
        
        THigh=AT24C02_ReadByte(0);
        TLow=AT24C02_ReadByte(1);
    
        while(1)
        {
            // 独立于遥控器事件的温度读取与显示
            DS18B20_ConvertT();
            Delay_us(750); // 延迟以确保温度转换完成
            T = DS18B20_ReadT();
            ... // 温度显示代码保持不变
    
            if(IR_GetDataFlag() || IR_GetRepeatFlag())
            {
                ... // 遥控器处理代码保持不变
            }
    
            // 不依赖遥控器事件的阈值显示
            LCD_ShowString(2,1,"TH:");
            LCD_ShowString(2,9,"TL:");
            LCD_ShowSignedNum(2,4,THigh,3);
            LCD_ShowSignedNum(2,12,TLow,3);
    
            // 温度报警逻辑保持不变
        }
    }
    

    总结:

    • 检查LCD1602和DS18B20的初始化是否正确,并确保它们在程序开始时被初始化。
    • 在读取DS18B20温度值之前添加适当的延时,确保温度转换完成。
    • 将显示阈值的代码从遥控器事件处理中分离出来,使其在主循环中持续执行,这样即使没有接收到遥控信号也能正常显示温度和阈值。
    评论 编辑记录
    1人已打赏

报告相同问题?

问题事件

  • 系统已结题 2月14日
  • 创建了问题 2月6日