请问LCD显示不对?是不是传送数据有问题吗?

2019-07-15 07:20发布


我做一个温度显示和数据传送系统,温度传感器用的是DS18B20,用U1单片机连接18B20,用U2连接LCD1602,U1 U2进行通讯,为何LCD温度显示不稳,有乱码现象,温度不会超过30度.一会25,一会15,一会0.


U1程序/******************************************************************
/******************************************************************
本单片机采用STC89C52RC芯片,用LCD1602显示温度上限设定值,下限设定值,
  以及在线温度实时显示,用18B20温度传感器检测温度,同时用按键设置温度
  上下限,以及设定切换,用timer0中断设置1秒闪烁指示灯显示运行状态。
*******************************************************************/

#include<REG52.h>
#include <intrins.h>
unsigned char times;

#define uchar unsigned char//宏定义
#define uint unsigned int


sbit DQ= P2^2;          //18B20总线端口
sbit led1=P1^0;          //系统运行指示,
uint temp1;  
uchar bai,shi,ge; //测量温度显示位置
uchar qian1,bai1,shi1,ge1;//上下限温度显示位置
bit flag; //标志位
sbit ds=P2^2;//18B20传感器 I/O口
sbit beep=P1^0;//温度报警
uint temp;

uchar num,num_shang=0,num_xia=0,numled,flag_qiehuan; //变量初始化,定义

/*====================================
函数        : delay(uint z)
参数        :z 延时毫秒设定,取值范围0-65535
返回值        :无
描述        :12T/Fosc11.0592M毫秒级延时
====================================*/

void delayus(uint t)        //us延时函数
{
         while(t--);
}
void init()                                                   //初始化函数
{
        TMOD|=0x01;                                                   //设置定时器0位工作方式(00000001)
        TH0=(65536-22500)/256;                           //装初值
        TL0=(65536-22500)%256;                           
        EA=1;                                                             //开总中断
        ET0=1;                                                           //开定时器0中断
        TR0=1;
        SCON|=0x50;       //串行口工作方式1,8位通用异步发送器
        TMOD|=0x20;                 //定时器1工作方式2
        PCON=0x00;                //波特率不倍增
        TH1=0xf3;
        TL1=0xf3;                //波特率2400
        TR1=1;                        //定时器1开始计时
}
void put(uint x)  //发送函数
{
        SBUF=x;                           //SBUF:串行口数据缓冲器
        while(TI==0);          //等待发送结束
        TI=0;
}
void ds_reset()           //复位函数
{
        ds=1;
        delayus(5);     //         延时
        ds=0;
        delayus(80);
        ds=1;
        delayus(14);
        if(ds==0)
        flag=1;
        else
        flag=0;                                //flag作为标志位,等1表示18b20存在
        delayus(20);
}
bit ds_read_bit(void)                        //读一位数据函数
{
        bit dat;
        ds=0;
        _nop_();                                   //延时机器周期
        _nop_();
        ds=1;                                                //释放总线
        _nop_();
        dat=ds;
        delayus(10);               //延时100us
        return dat;
}
uchar ds_read_byte()                   //读一个字节函数
{
        uchar i,j,k;
        for(i=0;i<8;i++)                  //一个字节8位组成,循环八次
        {
                j=ds_read_bit();
                k=(j<<7)|(k>>1);                //读出的数据最低位在最前面
        }
        return k;
}
void ds_write_byte(uchar dat)      //写一个字节的函数
{
        uchar i;
        for(i=0;i<8;i++)                        //循环八位将一个字节由低到高写入
        {
                ds=0;
                _nop_();
                ds=dat&0x01;                        //保留dat的最低位
                delayus(6);
                ds=1;                 //释放总线
                dat=dat>>1;
        }
        delayus(6);
}
uint read_temp()                //读取温度函数
{
        uchar a,b;
        ds_reset();
        ds_write_byte(0xcc);//                18B20忽略指令
        ds_write_byte(0xbe); //读暂存器指令
        a=ds_read_byte();           //读低八位
        b=ds_read_byte();                        //读高八位
        temp=b;
        temp=temp<<8;
        temp=temp|a;
        temp=temp*0.0625;                //得到实际温度值
        return temp;
}


void deal()//         温度报警设定
{
        if((temp>=num_xia)||(temp<=num_shang))        //大于下限或低于上限不报警
        {
                beep=0;
        }
        if((temp<num_xia)&&(temp>num_shang)) //低于下限或高于上限报警
        {
                beep=1;
        }        
}                                       
/****************************************/

/************************************/


  void delay_DS18B20(  time)//18B20延时5us函数
{
        uint i,j;
        for(i=0;i<time;i++)
                for(j=0;j<1;j++);
}
void delay_ms(uchar y)
{
        uchar i;
        while(y--)
        for(i=0;i<120;i++)
        ;
}

uchar Init_DS18B20(void)//18B20初始化
{
        uchar Presence;
        DQ=1;                                //数据端置高电平
        delay_DS18B20(10);         //延时

        DQ=0;                                 //数据端置低电平
        delay_DS18B20(29);

        DQ=1;
        delay_DS18B20(3);

        Presence=DQ;
        delay_DS18B20(23);
        return (Presence);

}

uchar Read_bit_DS18B20(void)
{
        DQ=1;
        delay_DS18B20(1);//DS18B20读位
        DQ=0;
        DQ=1;
        return (DQ);
}

void Write_bit_DS18B20(uchar date)//DS18B20写位
{
        DQ=0;
        if(date==1)
                DQ=1;
        delay_DS18B20(1);
        DQ=1;
        delay_DS18B20(1);
}

uchar Read_Byte_DS18B20(void)//DS18B20读字节
{
        uchar i,date=0;
        for(i=0;i<8;i++)
        {
                if(Read_bit_DS18B20())
                {
                        date=date|(0x01<<i); //00000001   00000010
                }
        }

        return (date);
}

void Write_Byte_DS18B20(uchar date)//DS18B20写字节
{
        uchar i;
        for(i=0;i<8;i++)
        {
                Write_bit_DS18B20(date&0x01);
                date=date>>1;        
        }
}

uint Gettemp(void)//读取温度,并将二进制数据转换成温度值
{
        uchar a,b;
        uint temp;
        float t;
        Init_DS18B20();
        Write_Byte_DS18B20(0xcc);//跳过        ROM
    Write_Byte_DS18B20(0x44);//开始转换温度
        delay_DS18B20(30);

        Init_DS18B20();
        Write_Byte_DS18B20(0xcc);//跳过        ROM
    Write_Byte_DS18B20(0xbe);//读取数据

        a=Read_Byte_DS18B20();//读温度值的低位
        b=Read_Byte_DS18B20();//读温度值的高位

        temp=b;
        temp=temp<<8;
        temp=temp|a;

        t=temp*0.0625;                 //计算温度值
        temp=t*100+0.5;                 

        return (temp);                // 返回

}

void main(void)
{

          init();                                //定时器初始化函数调用

        {
         ds_reset();
         ds_write_byte(0xcc); //18B20忽略指令
         ds_write_byte(0x44);//18B20温度转换指令

         deal();        //测量温度处理

        }


        while(1)
        {         
                   if(led1)
        {
                                             
                temp1=Gettemp();
                                   put(temp1);

        }  

        

           }

}
/***************************************************/
void T0_time() interrupt 1//中断1
{
        TH0=(65536-22500)/256;                           //装初值
        TL0=(65536-22500)%256;
        numled++;
        if(numled==50)
        {
          numled=0;
          led1=~led1;         //定时1s灯闪烁
        }

}
单片机采用STC89C52RC芯片,用LCD1602显示温度上限设定值,下限设定值,

  以及在线温度实时显示,用18B20温度传感器检测温度,同时用按键设置温度
  上下限,以及设定切换,用timer0中断设置1秒闪烁指示灯显示运行状态。
*******************************************************************/


#include<REG52.h>
#include <intrins.h>
unsigned char times;


#define uchar unsigned char//宏定义
#define uint unsigned int




sbit DQ= P2^2;          //18B20总线端口
sbit led1=P1^0;          //系统运行指示,
uint temp1;  
uchar bai,shi,ge; //测量温度显示位置
uchar qian1,bai1,shi1,ge1;//上下限温度显示位置
bit flag; //标志位
sbit ds=P2^2;//18B20传感器 I/O口
sbit beep=P1^0;//温度报警
uint temp;


uchar num,num_shang=0,num_xia=0,numled,flag_qiehuan; //变量初始化,定义


/*====================================
函数        : delay(uint z)
参数        :z 延时毫秒设定,取值范围0-65535
返回值        :无
描述        :12T/Fosc11.0592M毫秒级延时
====================================*/

void delayus(uint t)        //us延时函数
{
         while(t--);
}
void init()                                                   //初始化函数
{
        TMOD|=0x01;                                                   //设置定时器0位工作方式(00000001)
        TH0=(65536-22500)/256;                           //装初值
        TL0=(65536-22500)%256;                           
        EA=1;                                                             //开总中断
        ET0=1;                                                           //开定时器0中断
        TR0=1;
        SCON|=0x50;       //串行口工作方式1,8位通用异步发送器
        TMOD|=0x20;                 //定时器1工作方式2
        PCON=0x00;                //波特率不倍增
        TH1=0xf3;
        TL1=0xf3;                //波特率2400
        TR1=1;                        //定时器1开始计时
}
void put(uint x)  //发送函数
{
        SBUF=x;                           //SBUF:串行口数据缓冲器
        while(TI==0);          //等待发送结束
        TI=0;
}
void ds_reset()           //复位函数
{
        ds=1;
        delayus(5);     //         延时
        ds=0;
        delayus(80);
        ds=1;
        delayus(14);
        if(ds==0)
        flag=1;
        else
        flag=0;                                //flag作为标志位,等1表示18b20存在
        delayus(20);
}
bit ds_read_bit(void)                        //读一位数据函数
{
        bit dat;
        ds=0;
        _nop_();                                   //延时机器周期
        _nop_();
        ds=1;                                                //释放总线
        _nop_();
        dat=ds;
        delayus(10);               //延时100us
        return dat;
}
uchar ds_read_byte()                   //读一个字节函数
{
        uchar i,j,k;
        for(i=0;i<8;i++)                  //一个字节8位组成,循环八次
        {
                j=ds_read_bit();
                k=(j<<7)|(k>>1);                //读出的数据最低位在最前面
        }
        return k;
}
void ds_write_byte(uchar dat)      //写一个字节的函数
{
        uchar i;
        for(i=0;i<8;i++)                        //循环八位将一个字节由低到高写入
        {
                ds=0;
                _nop_();
                ds=dat&0x01;                        //保留dat的最低位
                delayus(6);
                ds=1;                 //释放总线
                dat=dat>>1;
        }
        delayus(6);
}
uint read_temp()                //读取温度函数
{
        uchar a,b;
        ds_reset();
        ds_write_byte(0xcc);//                18B20忽略指令
        ds_write_byte(0xbe); //读暂存器指令
        a=ds_read_byte();           //读低八位
        b=ds_read_byte();                        //读高八位
        temp=b;
        temp=temp<<8;
        temp=temp|a;
        temp=temp*0.0625;                //得到实际温度值
        return temp;
}




void deal()//         温度报警设定
{
        if((temp>=num_xia)||(temp<=num_shang))        //大于下限或低于上限不报警
        {
                beep=0;
        }
        if((temp<num_xia)&&(temp>num_shang)) //低于下限或高于上限报警
        {
                beep=1;
        }        
}                                       
/****************************************/


/************************************/


         
  void delay_DS18B20(  time)//18B20延时5us函数
{
        uint i,j;
        for(i=0;i<time;i++)
                for(j=0;j<1;j++);
}
void delay_ms(uchar y)
{
        uchar i;
        while(y--)
        for(i=0;i<120;i++)
        ;
}


uchar Init_DS18B20(void)//18B20初始化
{
        uchar Presence;
        DQ=1;                                //数据端置高电平
        delay_DS18B20(10);         //延时


        DQ=0;                                 //数据端置低电平
        delay_DS18B20(29);


        DQ=1;
        delay_DS18B20(3);


        Presence=DQ;
        delay_DS18B20(23);
        return (Presence);


}


uchar Read_bit_DS18B20(void)
{
        DQ=1;
        delay_DS18B20(1);//DS18B20读位
        DQ=0;
        DQ=1;
        return (DQ);
}


void Write_bit_DS18B20(uchar date)//DS18B20写位
{
        DQ=0;
        if(date==1)
                DQ=1;
        delay_DS18B20(1);
        DQ=1;
        delay_DS18B20(1);
}


uchar Read_Byte_DS18B20(void)//DS18B20读字节
{
        uchar i,date=0;
        for(i=0;i<8;i++)
        {
                if(Read_bit_DS18B20())
                {
                        date=date|(0x01<<i); //00000001   00000010
                }
        }


        return (date);
}


void Write_Byte_DS18B20(uchar date)//DS18B20写字节
{
        uchar i;
        for(i=0;i<8;i++)
        {
                Write_bit_DS18B20(date&0x01);
                date=date>>1;        
        }
}


uint Gettemp(void)//读取温度,并将二进制数据转换成温度值
{
        uchar a,b;
        uint temp;
        float t;
        Init_DS18B20();
        Write_Byte_DS18B20(0xcc);//跳过        ROM
    Write_Byte_DS18B20(0x44);//开始转换温度
        delay_DS18B20(30);


        Init_DS18B20();
        Write_Byte_DS18B20(0xcc);//跳过        ROM
    Write_Byte_DS18B20(0xbe);//读取数据


        a=Read_Byte_DS18B20();//读温度值的低位
        b=Read_Byte_DS18B20();//读温度值的高位


        temp=b;
        temp=temp<<8;
        temp=temp|a;


        t=temp*0.0625;                 //计算温度值
        temp=t*100+0.5;                 


        return (temp);                // 返回


}


void main(void)
{
            
          init();                                //定时器初始化函数调用
        
        {
         ds_reset();
         ds_write_byte(0xcc); //18B20忽略指令
         ds_write_byte(0x44);//18B20温度转换指令
        
         deal();        //测量温度处理
               
        }
         
      
        while(1)
        {         
                   if(led1)
        {
                                             
                temp1=Gettemp();
                                   put(temp1);
         
        }  


        
            
           }


}
/***************************************************/
void T0_time() interrupt 1//中断1
{
        TH0=(65536-22500)/256;                           //装初值
        TL0=(65536-22500)%256;
        numled++;
        if(numled==50)
        {
          numled=0;
          led1=~led1;         //定时1s灯闪烁
        }
}
U2程序
/******************************************************************
本单片机采用STC89C52RC芯片,用LCD1602显示温度上限设定值,下限设定值,
  以及在线温度实时显示,用18B20温度传感器检测温度,同时用按键设置温度
  上下限,以及设定切换,用timer0中断设置1秒闪烁指示灯显示运行状态。
*******************************************************************/


#include<REG52.h>
#include <intrins.h>
unsigned char times;


#define uchar unsigned char//宏定义
#define uint unsigned int




sbit RS = P2^6;   //定义lcd1602通讯端口
sbit RW = P2^5;
sbit EN = P2^7;
sbit DQ= P1^7;          //18B20总线端口
sbit led1=P1^1;          //系统运行指示,
uint temp1;  
uchar qian, bai,shi,ge; //测量温度显示位置
uchar qian1,bai1,shi1,ge1;//上下限温度显示位置
bit flag; //标志位
sbit ds=P1^7;//18B20传感器 I/O口
sbit led0=P1^0;//温度报警
uint temp;
sbit led4=P1^4;//温度上下限设定指示
sbit led3=P1^2;//工作指示
uchar num,num_shang=0,num_xia=0,numled,flag_qiehuan; //变量初始化,定义


/*====================================
函数        : delay(uint z)
参数        :z 延时毫秒设定,取值范围0-65535
返回值        :无
描述        :12T/Fosc11.0592M毫秒级延时
====================================*/




void init()                                                   //初始化函数
{
        TMOD|=0x01;                                                   //设置定时器0位工作方式(00000001)
        TH0=(65536-22500)/256;                           //装初值
        TL0=(65536-22500)%256;                           
        EA=1;                                                             //开总中断
        ET0=1;                                                           //开定时器0中断
        TR0=1;
        SCON=0x50;                         //串行口工作方式1,8位通用异步发送器
        TMOD|=0x20;                         //定时器1工作方式2
        PCON=0x00;                         //波特率不倍增
        TH1=0xf4;
        TL1=0xf4;
        TR1=1;


}






/*************************************/


                           
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。