找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1760|回复: 6
收起左侧

单片机使用ds18b20和lcd12864时cd显示就只有0和16

[复制链接]
ID:900557 发表于 2021-4-4 16:54 | 显示全部楼层 |阅读模式
我在做一个温控浴缸的diy,但是在测温时lcd上只显示0和16再无其他变化。lcd我是用的串行口的方式连接的PSB,GND,BLK接地,VCC,RS,BLA接+5V。
麻烦帮助一下指出问题,谢谢。

单片机程序如下:
#include<reg52.h>

#define uchar unsigned char
#define uint  unsigned int

sbit reshui=P3^5;
sbit lengshui=P3^6;
sbit zenjia=P3^3;
sbit jianshao=P3^4;                                                                                                                                                                          
sbit kaishi=P1^1;
sbit jieshu=P1^2;

sbit wendu=P3^7;


sbit EN=P2^7;
sbit RW=P2^6;


uint a,c;
uchar b=0,d=0;


//舵机初始化
void delay(uint i)
{
for(;i>0;i--);
}

void duoji()
{
         TMOD=0x22;
        TH0=0x9C;TL0=0x9C;
        TH1=0x9C;TL1=0x9C;
        EA=1;
        ET0=1;ET1=1;
         
}

void delay1ms(uint y)
{
          uint x;
        for(;y>0;y--)
        {
          for(x=110;x>0;x--);
        }
}
//传感器初始化
uchar ds18b20int()         
{
         uchar i=0;
        wendu=0;
        i=70;
        while(i--);           //642us
        wendu=1;
        i=0;
        while(wendu)
        {
           delay1ms(1);
           i++;
           if(i>5)
           {
                   return 0;
           }
        }
        return 1;
}

void ds18b20write(uchar dat)//  写命令
{
        uchar i,j;
        for(j=0;j<8;j++)
        {
                wendu=0;
                i++;
                wendu=dat&0x01;
                i=6;
                while(i--);        //68us
                wendu=1;
                dat>>=1;
        }
}

uchar ds18b20read()          //读命令
{
         uint i,j;
        uchar cun,byte;
        for(j=8;j>0;j--)
        {
                 wendu=0;
                i++;
                wendu=1;
                i++;
                i++;
                cun=wendu;
                byte=(byte>>1)|(cun<<7);
                i=4;
                while(i--);               
        }
        return cun;
}


void ds18b20chang()  //rom指令   转换
{
           ds18b20int();
          delay1ms(1);
          ds18b20write(0xcc);        //发送温度变换指令
          ds18b20write(0x44);        //进行温度变换,储存温度到rom
}

void ds18b20readzhiling()         //rom指令   读取
{
          ds18b20int();
          delay1ms(1);
          ds18b20write(0xcc);        
          ds18b20write(0xbe);
}

float ds18b20readwendu()         //rom指令   温度读取
{
          int temp=0;
          float tp;
          uchar high,low;
          ds18b20chang();
          ds18b20readzhiling();
          high=ds18b20read();
          low=ds18b20read();
          temp=high;
          temp<<=8;
          temp|=low;         
          if(temp<0)
          {                  
                 temp=temp-1;
                 temp=~temp;
                 tp=temp;
                 temp=tp*0.0625;
               
          }
          else
          {                                   
                 tp=temp;
                 temp=tp*0.0625;
                 
          }
           return temp;
}



void Delay_ms(unsigned char n)
{
           unsigned char  i,j;
    for(i=0;i<n;i++)
    for(j=0;j<123;j++);
}

void LCD_sendbyte(unsigned char dat)
{
   unsigned char i;
   for(i=0;i<8;i++)
         {
                EN=0;
                if(dat&0x80)
                RW=1;
                else RW=0;
                EN=1;
                dat=dat<<1;;         //左移一位         
         }
}

void LCD_write_com(unsigned char com)
{        
           LCD_sendbyte(0xf8);                 //送入5个连续的“1“,启动一个周期,11111,RW(0),RS(0),0
           LCD_sendbyte(0xf0&com);      //取高四位,数据分两次传送,每个字节的内容被送入两个字节,高四位放在第一个字节的高四位                                 
          LCD_sendbyte(0xf0&(com<<4));  //低四位放在第二个字节的高四位           
          Delay_ms(1);                               //串行不支持读操作,不可检测忙操作,这里用延时替代
}

void LCD_write_dat(unsigned char dat)
{      
           LCD_sendbyte(0xfa);        
           LCD_sendbyte(0xf0&dat);      
           LCD_sendbyte(0xf0&(dat<<4));            
           Delay_ms(1);  
}

void LCD_init(void)
{        
         LCD_write_com(0x30);    //选择基本指令集            
        LCD_write_com(0x0c);    //开显示,无游标,不反白   
         LCD_write_com(0x01);    //清除显示屏幕,把DDRAM位址计数器调整为00H  
         Delay_ms(1);                   //清屏操作时间较长1.6ms 因此加此延时
         LCD_write_com(0x02);    //清DDRAM位址归位,此处貌似与清屏重复  
        LCD_write_com(0x06);    //设定光标右移,整体显示不移动  
}

void LCD_Setaddress(unsigned char x,unsigned char y) //地址从第1行第1列开始不从0开始
{            
          unsigned char addr;
          switch(x)
          {
           case 1: addr=0x80+y-1;
                   break;
            case 2: addr=0x90+y-1;
                   break;
           case 3: addr=0x88+y-1;
                   break;
           case 4: addr=0x98+y-1;
                   break;
           default : break;
          }
           LCD_write_com(addr);   //字符显示开始地址
}

void LCD_Putstring( unsigned char x, unsigned char y, unsigned char *pData )
{
         LCD_Setaddress(x,y);
         while(*pData)
         {
           LCD_write_dat( *pData++ );
         }
}

void lcd_putint( unsigned char x, unsigned char y, unsigned int Data )
{
        unsigned char a,b,c,d,e;
        unsigned int Datas;
        Datas=Data*100+0.5;
        a=Datas/10000;
        b=Datas%10000/1000;
        c=Datas%1000/100;
        d=Datas%100/10;
        e=Datas%100%10;
//a=Data/10000;b=Data%10000/1000;c=Data%1000/100;d=Data%100/10;e=Data%10;
        LCD_Setaddress(x,y);
        LCD_write_dat(a+48);
        LCD_write_dat(b+48);
        LCD_write_dat(c+48);
        LCD_write_dat(0x2e);
        LCD_write_dat(d+48);
        LCD_write_dat(e+48);
}


void main(void)
{
        uint i=0;
        float m,n;
        duoji();
        LCD_init();
        while(1)
        {
                if(kaishi==0)
                {
                        m=0;
                        delay(2000);
                        if(kaishi==0)
                        {
                                c=15;a=15;
                                TR1=1;TR0=1;
                        }
                    while(!kaishi);                        
                }
                else
            TR1=0;TR0=0;
                if(zenjia==1)
                {
                           m=m+5;
                }
                if(jianshao==1)
                {
                       m=m-5;
                }
                if(n>m)
                {
                         delay(2000);
                          a=a-1;
                          c=c+1;
                          TR0=1;TR1=1;
                }
                if(n<m)
                {
                          delay(2000);
                          a=a+1;
                          c=c-1;
                          TR0=1;TR1=1;
                }
                if(n==m)
                {
                        delay(2000);
                        a=a;
                         c=c;
                         TR0=1;TR1=1;
                }
                if(jieshu==0)
                {
                        delay(2000);
                        if(jieshu==0)
                        {
                                c=5;a=5;
                                TR1=1;TR0=1;
                        }
                    while(!jieshu);                        
                }
                else
            TR1=0;TR0=0;
                n=ds18b20readwendu();
                LCD_Putstring(1,1, "当前温度");
                lcd_putint(1,5, n);
                LCD_Putstring(2,1, "预设温度");
                lcd_putint(2,5, m);
        }
        


}

void timer_0(void) interrupt 1 using 0
{
         b++;
        if(b<a)
        {
                reshui=1;
        }
        if(b>a)
        {
                reshui=0;
        }
        if(b==200)
        {
                b=0;
        }
                 TH0=0x9C;TL0=0x9C;
}


void timer_1(void) interrupt 3 using 0
{
        d++;
        if(d<c)
        {
                lengshui=1;
        }
        if(d>c)
        {
                lengshui=0;
        }
        if(d==200)
        {
                d=0;
        }
    TH1=0x9C;TL1=0x9C;
}




回复

使用道具 举报

ID:517951 发表于 2021-4-5 08:24 | 显示全部楼层
可以把n=ds18b20readwendu(); 改成n=0xfc90;  这个值对应转换后的温度是-55度(或者其他对应数值也可以)如果显示不正确就找液晶显示器部分的代码,如果显示正确,就要看下18B20初始化或者读数部分的代码的问题。 我做电子日历,温度显示用液晶屏,测温就是18B20,调试代码debug就是这么干的,希望对你有用。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:900557 发表于 2021-4-5 14:22 | 显示全部楼层
rayin 发表于 2021-4-5 08:24
可以把n=ds18b20readwendu(); 改成n=0xfc90;  这个值对应转换后的温度是-55度(或者其他对应数值也可以) ...

谢谢老哥
回复

使用道具 举报

ID:900557 发表于 2021-4-5 15:02 | 显示全部楼层
好的,非常感谢
回复

使用道具 举报

ID:900557 发表于 2021-4-5 16:10 | 显示全部楼层
问题找到了,是读命令的返回值错误,应该返回byte,我写成了cun
回复

使用道具 举报

ID:997450 发表于 2022-1-17 19:36 | 显示全部楼层
812839019 发表于 2021-4-5 16:10
问题找到了,是读命令的返回值错误,应该返回byte,我写成了cun

温度为负值时,计算时不是按位取反再加1吗??

  if(temp<0)
          {                  
                 temp=temp-1;
                 temp=~temp;
                 tp=temp;
                 temp=tp*0.0625;
           }

我的判断温度为负值条件是这样的
if(temp & 0xf800 == 0xf800)

当然,也许你是在其他地方处理了,我只看了这一部分
回复

使用道具 举报

ID:997450 发表于 2022-1-22 08:32 | 显示全部楼层
yeyuemyl 发表于 2022-1-17 19:36
温度为负值时,计算时不是按位取反再加1吗??

  if(temp

我错了,对于负值,温度转换出来的好像就是负的,然后减一再取反
                                                                 if(Data <0)
                                                                 {
                                                                                LCD_write_dat(45);
                                                                                Data=~(Data-1);
                                                                 }
                                                                 else                                                                 
                                                                         LCD_write_dat(0x20);
                                                                 
                                                                 Data=Data*0.0625*100;//12345
                                                                LCD_write_dat(Data/10000+0x30);
                                                                LCD_write_dat(Data/1000%10+0x30 );
                                                                LCD_write_dat(Data/100%10+0x30 );
                                                                LCD_write_dat(0x2e);
                                                                LCD_write_dat(Data/10%10+0x30);
                                                                LCD_write_dat(Data%10+0x30 );

Data是温度转换后返回的16位数
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表