单片机温度传感器Proteus仿真LCD显示


#include<reg51.h>
#include<intrins.h>
sbit DS18B20_DQ=P3^3;
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
typedef unsigned int u8;
typedef unsigned char u16;
typedef float u4;
u16 xdata buffer[]={'0','0','0','0','0','0','0'};

u8 tempL;
u16 tempH;
u4 temp1;
u8 temp2;
void Delay(u8 x)
{
     u16 i;
    while(x--)
    {
         for(i=0;i<200;i++);
    }
}
bit DS18B20_reset()
{
    bit flag;
    u8 i;
    DS18B20_DQ=0;
    for(i=240;i>0;i--);//每执行一次约两个机器周期,2us,240--480us
    DS18B20_DQ=1;
    for(i=40;i>0;i--);
    flag=DS18B20_DQ;
    for(i=200;i>0;i--);
    return flag;
}

void DS18B20_WriteData(u8 dat)
{
    u8 i,j;
    for(j=0;j<8;j++)
    {
        DS18B20_DQ=0;
        for(i=2;i>0;i--);
        DS18B20_DQ=dat&0x01;//取出最低位
        for(i=30;i>0;i--);
        DS18B20_DQ=1;//释放总线
        dat=dat>>1;//右移
    }
}

u8 DS18B20_ReadData()
{
    u8 i,j,rdata;
    for(j=0;j<8;j++)
    {
        rdata>>=1;//右移一位
        DS18B20_DQ=0;
        for(i=2;i>0;i--);
        DS18B20_DQ=1;
        for(i=3;i>0;i--);
        if(DS18B20_DQ==1)
            rdata=rdata|0x80;
        for(i=30;i>0;i--);
        DS18B20_DQ=1;//释放总线
    }
    return rdata;
}
void Temperature_read()//读出温度
{
    u8 i;
    DS18B20_reset();
    DS18B20_WriteData(0xcc);//跳过ROM检测
    DS18B20_WriteData(0x44);//启动温度转换
    DS18B20_reset();
    DS18B20_WriteData(0xcc);//跳过ROM检测
    DS18B20_WriteData(0xbe);//读暂存器命令
    tempL=DS18B20_ReadData();//读温度低位
    tempH=DS18B20_ReadData();//读温度高位
    tempH=(tempH<<8)|tempL;//高位右移八位,或上低位,高位全1为负,高五位全0为正。
    if((tempH&0xF8)==0xF8)
            tempH=~tempH+1;//为负取反加一
    temp1=tempH*0.0625;//127.937
    temp2=temp1;
    for(i=2;i>=0;i--)
    {
        buffer[i]=temp2%10;
        temp2=temp2/10;
    }
    buffer[3]='.';
    temp1=(u8)temp1%1*1000;
    for(i=7;i>=4;i--)
    {
        buffer[i]=(u8)temp1%10+'0';
    temp1=temp1/10;
    }
}
void LCD_busyCheck()
{
    u8 sta;
    P0=0xff;
    LCD_RS=0;
    LCD_RW=1;
    do{
        LCD_EN=1;
        sta=P0;
        LCD_EN=0;
    }while((sta&0x80)!=0x80);//10000000
}
void LCD_write_x(u8 x)//写单个数据
{
    LCD_busyCheck();
    LCD_RS=1;
    LCD_RW=0;
    P0=x;
    LCD_EN=1;
    LCD_EN=0;
}
void LCD_write_xx(u8 *x)//写单个数据
{
    while(*x)
    {
        LCD_write_x(*x++);//自加
    }
}
void LCD_write_cmd(u8 cmd)//写命令
{
    LCD_busyCheck();
    LCD_RS=0;
    LCD_RW=0;
    P0=cmd;
    LCD_EN=1;
    LCD_EN=0;
}
void LCD_position(bit x,u8 y)
{
    u8 position;
    if(x==0)
        position=0x80+y;
    else
        position=0xc0+y;
}

void main()
{
    u8 i;
    LCD_write_cmd(0x01);
    LCD_write_cmd(0x38);//八位接口,两行显示
    LCD_write_x(0x80);//从第一位开始显示,写地址
    LCD_write_xx("Temperature : ");
    LCD_write_x(0xc0);//从第二行开始显示,写地址
    LCD_write_xx("TEMP: ");
    while(1)
    {
        Temperature_read();
        LCD_position(1,6);
        for(i=0;i<16;i++)
        {
            LCD_write_x(buffer[i]);     
        }
        LCD_position(1,14);
        LCD_write_xx("C");
    }
}

代码运行出来没有错误,但proteus中的显示屏(LCD)没有办法显示,运行的话就是下面的图,什么都没有

img


怎么改呀

转换需要时间的,这个地方需要加个延时,手册里转换时间好像是750ms

img

程序分两步调试:
1、首先实现LCD的显示功能调试,比如先实现单个字符,固定数字的显示;
2、再进行18B20的功能调试,18B20的主要难点在时序,对着芯片手册调时序,比较容易调通的。

LCD的VSS VDD VEE都悬空怎么显示。


#include<reg51.h>
#include<intrins.h>
sbit DS18B20_DQ=P3^3;
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
typedef unsigned int u8;
typedef unsigned char u16;
typedef float u4;
u16 xdata buffer[]={'0','0','0','0','0','0','0'};

u8 tempL;
u16 tempH;
u4 temp1;
u8 temp2;
void Delay(u8 x)
{
     u16 i;
    while(x--)
    {
         for(i=0;i<200;i++);
    }
}
bit DS18B20_reset()
{
    bit flag;
    u8 i;
    DS18B20_DQ=0;
    for(i=240;i>0;i--);//每执行一次约两个机器周期,2us,240--480us
    DS18B20_DQ=1;
    for(i=40;i>0;i--);
    flag=DS18B20_DQ;
    for(i=200;i>0;i--);
    return flag;
}

void DS18B20_WriteData(u8 dat)
{
    u8 i,j;
    for(j=0;j<8;j++)
    {
        DS18B20_DQ=0;
        for(i=2;i>0;i--);
        DS18B20_DQ=dat&0x01;//取出最低位
        for(i=30;i>0;i--);
        DS18B20_DQ=1;//释放总线
        dat=dat>>1;//右移
    }
}

u8 DS18B20_ReadData()
{
    u8 i,j,rdata;
    for(j=0;j<8;j++)
    {
        rdata>>=1;//右移一位
        DS18B20_DQ=0;
        for(i=2;i>0;i--);
        DS18B20_DQ=1;
        for(i=3;i>0;i--);
        if(DS18B20_DQ==1)
            rdata=rdata|0x80;
        for(i=30;i>0;i--);
        DS18B20_DQ=1;//释放总线
    }
    return rdata;
}
void Temperature_read()//读出温度
{
    u8 i;
    DS18B20_reset();
    DS18B20_WriteData(0xcc);//跳过ROM检测
    DS18B20_WriteData(0x44);//启动温度转换
    DS18B20_reset();
    DS18B20_WriteData(0xcc);//跳过ROM检测
    DS18B20_WriteData(0xbe);//读暂存器命令
    tempL=DS18B20_ReadData();//读温度低位
    tempH=DS18B20_ReadData();//读温度高位
    tempH=(tempH<<8)|tempL;//高位右移八位,或上低位,高位全1为负,高五位全0为正。
    if((tempH&0xF8)==0xF8)
            tempH=~tempH+1;//为负取反加一
    temp1=tempH*0.0625;//127.937
    temp2=temp1;
    for(i=2;i>=0;i--)
    {
        buffer[i]=temp2%10;
        temp2=temp2/10;
    }
    buffer[3]='.';
    temp1=(u8)temp1%1*1000;
    for(i=7;i>=4;i--)
    {
        buffer[i]=(u8)temp1%10+'0';
    temp1=temp1/10;
    }
}
void LCD_busyCheck()
{
    u8 sta;
    P0=0xff;
    LCD_RS=0;
    LCD_RW=1;
    do{
        LCD_EN=1;
        sta=P0;
        LCD_EN=0;
    }while((sta&0x80)==0x80);//10000000
}
void LCD_write_dat(u16 dat)//写单个数据
{
    LCD_busyCheck();
    LCD_RS=1;
    LCD_RW=0;
    P0=dat;
    LCD_EN=1;
    LCD_EN=0;
}
void LCD_write_datt(u16 *s)//写单个数据
{
    while(*s)
    {
        LCD_write_dat(*s++);//自加
    }
}
void LCD_write_cmd(u8 cmd)//写命令
{
    LCD_busyCheck();
    LCD_RS=0;
    LCD_RW=0;
    P0=cmd;
    LCD_EN=1;
    LCD_EN=0;
}

void main()
{
    u8 i;
    LCD_write_cmd(0x01);//清屏
    LCD_write_cmd(0x06);//指针自增
    LCD_write_cmd(0x0c);//显示开,光标关
    LCD_write_cmd(0x38);//八位接口,两行显示
    LCD_write_cmd(0x80);//从第一位开始显示,写地址
    LCD_write_datt("Temperature : ");
    LCD_write_cmd(0xC0);//从第二行开始显示,写地址
    LCD_write_datt("TEMP: ");
    while(1)
    {
        Temperature_read();
        LCD_write_cmd(0xC6);
        for(i=0;i<16;i++)
        {
            LCD_write_dat(buffer[i]);
        }
        LCD_write_cmd(0xCE);
        LCD_write_dat('C');
    }
}

这是修改之后的代码,修改后LCD的显示没有问题,应该是温度传感器的问题,但我找不到,修改后运行就是下面的图

img