沥沥小鱼 2024-02-13 21:22 采纳率: 45.5%
浏览 11

(标签-51单片机|关键词-main)(相关搜索:51单片机|红外遥控器|温度传感器)

题目:温度监测系统
利用51单片机,通过红外遥控器,DS18B20温度传感器(单片机自带),LCD1602显示屏,做一个温度监测系统
(1)通过红外遥控,能够设置温度阚值和电机转速
(2)能够在LCD1602显示屏上显示实时温度和电机转速
(3)温度超出值时蜂鸣器报警,电机转动 ,电机转速使用PWM波实现
(4)温度低于闯值时解除报警,电机停止
问题:现在写的代码现象是
1 达到温度高阈值报警后DS18B20就不再测温了,LCD显示屏就冻结了
main函数是

#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"
#include "Motor.h"//可变速模块
 
float T,TShow;
char TLow,THigh;
unsigned char KeyNum;
unsigned char Address;
unsigned char Command;
unsigned char Speed;
void main()
{
    IR_Init();
      LCD_Init();
      OneWire_Init();
    DS18B20_ConvertT(); 
      Motor_Init();
      Delay(1000);            //等待转换完成
    THigh=AT24C02_ReadByte(0);    //读取温度阈值数据
    TLow=AT24C02_ReadByte(1);
      if(THigh>125 || TLow<-55 || THigh<=TLow)
       {
            THigh=25;            //如果阈值非法,则设为默认值
            TLow=15;
       }
    while(1)
    {
                 DS18B20_ConvertT();    //转换温度
                     Delay(1);
           T=DS18B20_ReadT();    //读取温度
           if(T<0)                //如果温度小于0
           {
              LCD_ShowChar(1,3,'-');    //显示负号
              TShow=-T;        //将温度变为正数
           }
           else                //如果温度大于等于0
           {
              TShow=T;
           }
                     LCD_ShowString(1,1,"T:");
           LCD_ShowNum(1,3,TShow,3);        //显示温度整数部分
           LCD_ShowChar(1,6,'.');        //显示小数点
           LCD_ShowNum(1,7,(unsigned long)(TShow*100)%100,2);//显示温度小数部分
              if(IR_GetDataFlag() || IR_GetRepeatFlag())    //如果收到数据帧或者收到连发帧
        {
            Address=IR_GetAddress();        //获取遥控器地址码
            Command=IR_GetCommand();        //获取遥控器命令码
            /*温度读取及显示*/
           
            if(Command==IR_VOL_MINUS)        //如果遥控器VOL-按键按下
            {
                    THigh++;                
            }
            if(Command==IR_VOL_ADD)            //如果遥控器VOL+按键按下
            {
                    THigh--;        
            }
            if(Command==IR_POWER)
            {
                TLow++;
            }
            if(Command==IR_MODE)
            {
                  TLow--;
            }
                        //因为题目要求红外遥控还要控制电机速度
                        if(Command==IR_0){Speed=0;}        //根据遥控器命令码设置速度
                  if(Command==IR_1){Speed=1;}
                  if(Command==IR_2){Speed=2;}
                  if(Command==IR_3){Speed=3;}
              
                  if(Speed==0){Motor_SetSpeed(0);}    //速度输出
                  if(Speed==1){Motor_SetSpeed(50);}
                  if(Speed==2){Motor_SetSpeed(75);}
                  if(Speed==3){Motor_SetSpeed(100);}
            }
         }
                 LCD_ShowString(2,1,"TH:");
         LCD_ShowString(2,9,"TL:");
         LCD_ShowSignedNum(2,4,THigh,3);
         LCD_ShowSignedNum(2,12,TLow,3);
                 LCD_ShowSignedNum(1,11,Speed,1);//LCD显示速度
            AT24C02_WriteByte(0,THigh);        //写入到At24C02中保存
            Delay(5);
            AT24C02_WriteByte(1,TLow);
            Delay(5);
        if(T>THigh)            //如果高出阈值
        {
                      motor();   //直流电机运转(不同与Motor,这个不可变速)
            Buzzer_Time(10000); //蜂鸣器报警
        }
        else if(T<TLow) //如果低于阈值
        {
            P2=0xFF;      //小灯全亮
        }
}
 

2 添加了电机调速代码后报错警告解决不了
main.c(27): warning C206: 'Motor_Init': missing function-prototype
main.c(82): warning C206: 'Motor_SetSpeed': missing function-prototype
main.c(82): error C267: 'Motor_SetSpeed': requires ANSI-style prototype
3 不知道怎么写能使温度低于阈值后解除报警,直流电机停止转动
这是main函数


#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"
#include "Motor one.h"//可变速模块
 
float T,TShow;
char TLow,THigh;
unsigned char KeyNum;
unsigned char Address;
unsigned char Command;
unsigned char Speed;
void main()
{
    IR_Init();
      LCD_Init();
      OneWire_Init();
    DS18B20_ConvertT(); 
      Motor_Init();
      Delay(1000);            //等待转换完成
    THigh=AT24C02_ReadByte(0);    //读取温度阈值数据
    TLow=AT24C02_ReadByte(1);
      if(THigh>125 || TLow<-55 || THigh<=TLow)
       {
            THigh=25;            //如果阈值非法,则设为默认值
            TLow=15;
       }
    while(1)
    {
                 DS18B20_ConvertT();    //转换温度
                     Delay(1);
           T=DS18B20_ReadT();    //读取温度
           if(T<0)                //如果温度小于0
           {
              LCD_ShowChar(1,3,'-');    //显示负号
              TShow=-T;        //将温度变为正数
           }
           else                //如果温度大于等于0
           {
              TShow=T;
           }
                     LCD_ShowString(1,1,"T:");
           LCD_ShowNum(1,3,TShow,3);        //显示温度整数部分
           LCD_ShowChar(1,6,'.');        //显示小数点
           LCD_ShowNum(1,7,(unsigned long)(TShow*100)%100,2);//显示温度小数部分
              if(IR_GetDataFlag() || IR_GetRepeatFlag())    //如果收到数据帧或者收到连发帧
        {
            Address=IR_GetAddress();        //获取遥控器地址码
            Command=IR_GetCommand();        //获取遥控器命令码
            /*温度读取及显示*/
           
            if(Command==IR_VOL_MINUS)        //如果遥控器VOL-按键按下
            {
                    THigh++;                
            }
            if(Command==IR_VOL_ADD)            //如果遥控器VOL+按键按下
            {
                    THigh--;        
            }
            if(Command==IR_POWER)
            {
                TLow++;
            }
            if(Command==IR_MODE)
            {
                  TLow--;
            }
                        //因为题目要求红外遥控还要控制电机速度
                        if(Command==IR_0){Speed=0;}        //根据遥控器命令码设置速度
                  if(Command==IR_1){Speed=1;}
                  if(Command==IR_2){Speed=2;}
                  if(Command==IR_3){Speed=3;}
              
                  if(Speed==0){Motor_SetSpeed(0);}    //速度输出
                  if(Speed==1){Motor_SetSpeed(50);}
                  if(Speed==2){Motor_SetSpeed(75);}
                  if(Speed==3){Motor_SetSpeed(100);}
            }
         }
                 LCD_ShowString(2,1,"TH:");
         LCD_ShowString(2,9,"TL:");
         LCD_ShowSignedNum(2,4,THigh,3);
         LCD_ShowSignedNum(2,12,TLow,3);
                 LCD_ShowSignedNum(1,11,Speed,1);   //LCD显示速度
            AT24C02_WriteByte(0,THigh);     //写入到At24C02中保存
            Delay(5);
            AT24C02_WriteByte(1,TLow);
            Delay(5);
        if(T>THigh)            //如果高出阈值
        {
                      motor();   //直流电机运转(不同与Motor one,这个不可变速)
                                          while(1)
                                          { Buzzer_Time(1000); }
        }

       
}

这是Motor one.c //可变速

#include <REGX52.H>
#include "Timer1.h"

//引脚定义
sbit Motor=P1^0;

unsigned char Counter,Compare;

/**
  * @brief  电机初始化
  * @param  无
  * @retval 无
  */
void Motor_Init(void)
{
    Timer1_Init();
}

/**
  * @brief  电机设置速度
  * @param  Speed 要设置的速度,范围0~100
  * @retval 无
  */
void Motor_SetSpeed(unsigned char Speed)
{
    Compare=Speed;
}

//定时器1中断函数
void Timer1_Routine() interrupt 3
{
    TL1 = 0x9C;        //设置定时初值
    TH1 = 0xFF;        //设置定时初值
    Counter++;
    Counter%=100;    //计数值变化范围限制在0~99
    if(Counter<Compare)    //计数值小于比较值
    {
        Motor=1;        //输出1
    }
    else                //计数值大于比较值
    {
        Motor=0;        //输出0
    }
}


Motor one.h


#ifndef __MOTOR_H__
#define __MOTOR_H__

void Motor_Init(void);
void Motor_SetSpeed(unsigned char Speed);

#endif

这是motor.c //不可变速

#include"reg52.h"
#include<Delay.h>
sbit zhengzhuan = P2^2;
sbit fangzhuan = P2^1;
sbit shineng = P2^0;
 
#define uint unsigned int   // 把 unsigned int 简写成uint
 void motor()
     {            // 直流电机函数
    shineng = 1;         // 使能 = 1
    zhengzhuan = 1;      // 正转 = 1
    Delay(75);           // 延时75毫秒
    zhengzhuan = 0;      // 正转 = 0
    Delay(25);           // 延时25毫秒
   }

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-02-13 21:24
    关注

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

    针对您提供的代码和问题,我将逐个分析并给出相应的解答与建议:

    1. 温度达到高阈值报警后停止测温及LCD冻结问题

      • 根据您的描述,当温度超过设定的THigh阈值时,系统会执行直流电机转动和蜂鸣器报警。但是,当前代码中没有看到恢复温度检测和更新LCD显示的部分。
      • 需要在if(T>THigh)条件块的末尾添加一个循环或标志位来控制报警状态,并在解除报警条件满足时(即温度低于阈值)恢复正常的温度检测和显示流程。
    2. 编译警告:缺少函数原型声明

      • 编译器提示“missing function-prototype”,这意味着在使用Motor_Init()Motor_SetSpeed()之前,对应的函数原型未在main.c文件中声明或者包含头文件错误。
      • 检查motor.h是否正确包含进main.c中,确保包含了正确的头文件路径。修改如下:
        #include "Motor_one.h"  // 更改此处为正确的头文件名
        
        确保Motor_one.c中的函数原型在Motor_one.h中有定义。
    3. 温度低于阈值解除报警并停止电机转动

      • 在main.c的while循环内,需要增加对温度低于阈值情况的处理逻辑,同时停止电机转动:
        if(T<=TLow) // 如果温度低于等于阈值
        {
            Buzzer_Stop(); // 停止蜂鸣器报警
            Motor_Stop();  // 添加这个函数以停止可变速电机转动
            zhengzhuan = 0; fangzhuan = 0; shineng = 0; // 不可变速电机停止转动
        }
        
    4. 直流电机停止转动的代码实现: 对于不可变速模块的电机,可以在motor.h中声明一个停止电机转动的函数,在motor.c中实现它:

      // motor.h
      void Motor_Stop(void);
      
      // motor.c
      void Motor_Stop()
      {
          zhengzhuan = 0;
          fangzhuan = 0;
          shineng = 0;  // 关闭所有控制信号,使电机停止转动
      }
      

    综合以上内容,调整后的main.c部分代码应如下所示:

    // ...其他不变...
    
    #include "Motor_one.h"
    
    void main()
    {
        // ...IR, LCD, DS18B20等初始化...
        
        while(1)
        {
            // ...温度获取与显示...
            
            // ...遥控器命令处理...
            
            LCD_ShowString(2,1,"TH:");
            LCD_ShowString(2,9,"TL:");
            LCD_ShowSignedNum(2,4,THigh,3);
            LCD_ShowSignedNum(2,12,TLow,3);
            LCD_ShowSignedNum(1,11,Speed,1); //LCD显示速度
    
            // 温度阈值超出或低于处理
            if(T>THigh)            // 如果高出阈值
            {
                Motor_Start();   // 可变速电机启动(这里假设有一个Motor_Start()函数)
                while(T > THigh)  // 循环直到温度低于阈值
                {
                    Buzzer_Time(1000); 
                    Delay_ms(some_time_to_allow_temperature_reading); 
                    T=DS18B20_ReadT(); // 继续读取温度
                }
                Motor_Stop();  // 温度降低到阈值以下时,停止电机
            }
            else if(T<=TLow) // 如果温度低于等于阈值
            {
                Buzzer_Stop();
                Motor_Stop();
                zhengzhuan = 0; fangzhuan = 0; shineng = 0;
            }
    
            // ...数据保存至AT24C02...
        }
    }
    

    请根据实际情况调整延时时间和电机控制逻辑,确保系统的稳定性和实时性。另外,请注意,对于可变速电机的控制逻辑,示例中假定了有Motor_Start()Motor_Stop()函数用于启动和停止电机,实际应用中需要根据电机驱动的具体实现来编写相应函数。

    评论

报告相同问题?

问题事件

  • 创建了问题 2月13日