单片机/MCU论坛
直播中

支前进

6年用户 7经验值
擅长:电源/新能源 模拟技术
私信 关注
[问答]

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


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



U1程序/******************************************************************

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

#include
#include
unsigned char times;

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


***it DQ= P2^2;          //18B20总线端口
***it led1=P1^0;          //系统运行指示,
uint temp1;  
uchar bai,shi,ge; //测量温度显示位置
uchar qian1,bai1,shi1,ge1;//上下限温度显示位置
bit flag; //标志位
***it ds=P2^2;//18B20传感器 I/O口
***it 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((tempnum_shang)) //低于下限或高于上限报警
        {
                beep=1;
        }        
}                                       
/****************************************/

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


  void delay_DS18B20(  time)//18B20延时5us函数
{
        uint i,j;
        for(i=0;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<                 }
        }

        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
#include
unsigned char times;


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




***it DQ= P2^2;          //18B20总线端口
***it led1=P1^0;          //系统运行指示,
uint temp1;  
uchar bai,shi,ge; //测量温度显示位置
uchar qian1,bai1,shi1,ge1;//上下限温度显示位置
bit flag; //标志位
***it ds=P2^2;//18B20传感器 I/O口
***it 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((tempnum_shang)) //低于下限或高于上限报警
        {
                beep=1;
        }        
}                                       
/****************************************/


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


         
  void delay_DS18B20(  time)//18B20延时5us函数
{
        uint i,j;
        for(i=0;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<
                }
        }


        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
#include
unsigned char times;


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




***it RS = P2^6;   //定义lcd1602通讯端口
***it RW = P2^5;
***it EN = P2^7;
***it DQ= P1^7;          //18B20总线端口
***it led1=P1^1;          //系统运行指示,
uint temp1;  
uchar qian, bai,shi,ge; //测量温度显示位置
uchar qian1,bai1,shi1,ge1;//上下限温度显示位置
bit flag; //标志位
***it ds=P1^7;//18B20传感器 I/O口
***it led0=P1^0;//温度报警
uint temp;
***it led4=P1^4;//温度上下限设定指示
***it 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;


}






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


                           
/****************************************/
void display_set_alm()                                        //显示子函数,报警数据分离,显示在液晶面板上
{                                                                                


        qian1=num_shang/10;                                   
        bai1=num_shang%10;
        shi1=num_xia/10;
        ge1=num_xia%10;
}
/************************************/


         
  
void delay_ms(uchar time)//延时1ms函数
{
  unsigned int i,j;
  for(i=0;i
          for(j=0;j<110;j++);
}


void LCD_Write_Com(uchar com)//         lcd写命令
{  
delay_ms(5);
RS=0;
RW=0;
EN=1;
P0=com;
EN=0;
}
void LCD_Write_Data(uchar Data) //写入数据函数
{
delay_ms(5);
RS=1;
RW=0;
EN=1;
P0= Data;
EN=0;
}
void gotoxy(uchar x,uchar y)         //确定显示位置
{
        if (x == 1)
         {     
                 LCD_Write_Com(0x80 + y-1);     //表示第一行
         }
        else
         {      
                 LCD_Write_Com(0xC0 + y-1);      //表示第二行
         }        
}
void LCD_Write_String(uchar *s) // 写入字符串函数
{     
         while (*s)
         {     
         LCD_Write_Data( *s);     
         s ++;     
         }
}
void LCD_Init(void)  //初始化函数
{
   LCD_Write_Com(0x38);    /*显示模式设置*/
   delay_ms(1);
   LCD_Write_Com(0x38);
   delay_ms(1);
   LCD_Write_Com(0x38);
   delay_ms(1);
   LCD_Write_Com(0x38);  
   LCD_Write_Com(0x08);    /*显示关闭*/
   LCD_Write_Com(0x01);    /*显示清屏*/
   LCD_Write_Com(0x06);    /*显示光标移动设置*/
   delay_ms(1);
   LCD_Write_Com(0x0C);    /*显示开及光标设置*/
}
void main(void)
{
         
          init();                                //定时器初始化函数调用
        
      
         
        LCD_Init();
        gotoxy(1,1);
        LCD_Write_String("ALM H   L"); //第一行第一列开始写
        gotoxy(2,1);
        LCD_Write_String("DS18B20:z      ");//第二行第三列开始写
        while(1)
        {     
                     
                      if(RI)
                {
                        RI=0;
                 temp1=SBUF;


               
                }  
   if(led3) {
                         if(temp1>25){
                 
                         led0=0;
                 }        
                qian=temp1/1000;
                bai=temp1/100;
                        
                shi=temp1%10;
                                 if(bai>25)
                          {
                 
                    bai=bai+25;
                 }
                 }
//               ge=temp1%10;
        gotoxy(2,9);
                        LCD_Write_Data(qian+0x30);
                LCD_Write_Data(bai+0x30);        //加0x30的原因是在ASCII码中0的地址是0x30
                LCD_Write_Data(shi+0x30);
//                LCD_Write_Data('.');
//              LCD_Write_Data(ge+0x30);
                        
         gotoxy(1,6);
                LCD_Write_Data(qian1+0x30);
                LCD_Write_Data(bai1+0x30);
                gotoxy(1,10);
                LCD_Write_Data(shi1+0x30);
                LCD_Write_Data(ge1+0x30);
                        
                        
                display_set_alm();
                                }
         


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



已退回4积分

回帖(3)

支前进

2019-3-19 12:21:52
咋没人啊,
/??????????????????????????????
举报

支前进

2019-3-19 14:23:43
着急啊………………………………………
举报

阿信509

2019-3-19 15:51:02
两个单片机单独进行调试,调好了再联调
1 举报

更多回帖

×
20
完善资料,
赚取积分