找回密码
 立即注册

QQ登录

只需一步,快速开始

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

使用DS18B20仿真后,不显示温度,单片机代码发出来了,求助啊

[复制链接]
ID:665413 发表于 2019-12-27 17:53 | 显示全部楼层 |阅读模式
仿真线路确定没问题,是我的代码问题,目前的问题是,其他显示都可以实现,比如显示数组table[],table1[],table2[],开始仿真都显示正常,就是不显示温度,谢谢各位大佬指教了

51hei图片_20191227174932.png

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

#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define delayNop(); {_nop_();_nop_();_nop_();_nop_();};

uchar code table[]=" ERROR!!!       ";
uchar code table1[]="xianzaiwendu    ";
uchar code table2[]="Temp=    .  Cent";
uchar code table3[10]="0123456789";

sbit lcd_rs=P1^0;
//sbit lcd_rw=P1^1;
sbit lcd_en=P2^5;
sbit DQ=P2^3;
uchar num,time;
void delay(uint t)
{
unsigned char n;
   while(t--)
   {
     for(n = 0; n<250; n++)
    {
      _nop_();
      _nop_();
     _nop_();
      _nop_();
    }
   }
}

void write_com(uchar com)    //写命令
{
////lcd_rw=0;
//delay(5);
        lcd_rs=0;
        lcd_en=0;
        _nop_();
        _nop_();
        P0=com;
        delayNop();
        lcd_en=1;  
        delay(1);
        lcd_en=0;
}

void write_date(uchar date)      //写数据
{
//lcd_rw=0;
// delay(5);
  lcd_rs=1;
  lcd_en=0;
  _nop_();
  _nop_();

   P0=date;        
   delayNop();
        lcd_en=1;                                                         
         delay(1);
        lcd_en=0;               
}

void init()       //初始化函数
{
// dula=0;
// wela=0;
lcd_en=0;  //可以试试不加这一句看结果怎样
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}

uchar init_DS18bB20()
{
        bit flag;
        DQ=1;                                          //人为拉高
        for(time=0;time<2;time++);                        //稍微延时6US;
        DQ=0;                                                        //认为拉低
        for(time=0;time<200;time++);                          //延时600US给单片机检测
        DQ=1;                                                                   //被上拉电阻拉高        (仿真里面没有上拉,有没有都需要人为拉高)
        for(time=0;time<20;time++);                           // 延时60US检测
        flag=DQ;                                                                //这时又被DS18B20拉低,
        for(time=0;time<200;time++);                   //延时600US检测时间
        return flag;                     //返回0表示存在

}

void Write_Byte(uchar dat)                 //写一个字节,单片机向DS18B20写命令,确定DS18B20的工作方法之类的
{
unsigned char i=0;
        for (i=0; i<8; i++)
                 {
                  DQ =1;         // 先将数据线拉高
                  _nop_();             //等待一个机器周期         
                  DQ=0;          //将数据线从高拉低时即启动写时序      
                  DQ=dat&0x01;   //利用与运算取出要写的某位二进制数据,
                       //并将其送到数据线上等待DS18B20采样        
                 for(time=0;time<10;time++)        
                     ;//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样
                  DQ=1;          //释放数据线                    
                  for(time=0;time<1;time++)
                          ;//延时3us,两个写时序间至少需要1us的恢复期
                  dat>>=1;       //将dat中的各二进制位数据右移1位
                 }
          for(time=0;time<4;time++)
                      ; //稍作延时,给硬件一点反应时间
}

uchar Read_Byte()
{
        uchar i=0;
        uchar dat;//用来储存读出的一个字节,默认为0
        for(i=0;i<8;i++)
        {
                DQ=1;
                _nop_();
                DQ=0;        //读命令一定得是低电平
                dat>>=1;   //读取数据是从高位开始读,dat默认是0,也就是0000 0000,
                                 //  这是下标是指向最高位的,所以得先右移一位让出一个位置
                _nop_();        //需要>1US;
                DQ=1;                //又被上拉电阻拉高
           for(time=0;time<2;time++);
                if(DQ==1)                   //由DQ发送的信号来决定,发送的是高电平还是低电平
                        dat|=0x80;           //高电平就或0x80,1000 0000
                else
                        dat|=0x00;         //低电平就或,0x00
                for(time=0;time<5;time++);//延时10US左右,因为需要在15US内完成读取
                }                                 
        return dat;
}

void Readyread()//做好读温度准备。。。。可以加在主函数里面,但是分出来比较清晰明了
{
        init_DS18bB20();
        Write_Byte(0xcc);        //跳过读序号
        Write_Byte(0x44);   //启动温度转换
        for(time=0;time<100;time++);
        init_DS18bB20();           //再初始化一下
        Write_Byte(0xcc);  //跳过读序号
        Write_Byte(0xbe);  //都温度寄存器,前两个分别是温度的,低,高位
}

void display()                                                //显示第一行说明
{
        write_com(0x80);
         for(num=0;num<16;num++)
         {
                  write_date(table[num]);
          //        delay(1);
         }  
                while(1);
}

void display1()                                        //显示第二行说明
{
        write_com(0x80);
         for(num=0;num<16;num++)
         {
                 write_date(table1[num]);
          //        delay(1);
         }


}

void display2()
{
        write_com(0x80+0x40);
         for(num=0;num<16;num++)
         {
                  write_date(table2[num]);
                  //delay(1);
         }
}
                                                
void display_temp(uchar x)          //显示温度整数部分
{
        uchar bai,shi,ge;
        bai=x/100;
        shi=(x%100)/10;
        ge=x%10;
        write_com(0x46);
        write_date(table3[bai]);
        write_date(table3[shi]);
        write_date(table3[ge]);



}

void display1_temp(uchar x)          //显示温度小数部分
{
        write_com(0x4a);
        write_date(table3[x]);
}



void main()
{
        uchar TL;//储存暂存器的温度最高位
        uchar TH;//储存暂存器的温度最低位
        uchar TN; //储存温度整数部分
        uchar TD; //储存温度小数部分
        init();
        if(init_DS18bB20()==1)
                display();
        display1();
//        display2();
        while(1)
        {
                Readyread();
                TL=Read_Byte();
                TH=Read_Byte();
                TN=TH*16+TL/16;      //实际温度值=(TH*256+TL)/16,即:TH*16+TL/16
                                          //这样得出的是温度的整数部分,小数部分被丢弃了
            TD=(TL%16)*10/16;    //计算温度的小数部分,将余数乘以10再除以16取整,
                                          //这样得到的是温度小数部分的第一位数字(保留1位小数)

                display_temp(TN);
                display1_temp(TD);
                _nop_(); _nop_();
        }
               
}

回复

使用道具 举报

ID:584814 发表于 2019-12-30 17:08 | 显示全部楼层
看来你自己已解决了
回复

使用道具 举报

ID:863585 发表于 2021-1-25 16:39 | 显示全部楼层
我也遇到同样问题,请问解决了吗
回复

使用道具 举报

ID:208271 发表于 2023-2-25 13:03 | 显示全部楼层
你可以试一下把仿真里的晶振改为6M,不行的话,改下DS18B20程序里的延时函数,因为DS18B20对时序要求很严格,仿真里运行的时间和实物不一样的,时序要改一改的。
回复

使用道具 举报

ID:891089 发表于 2023-2-25 16:03 来自手机 | 显示全部楼层
ds18b20信号线要用电阻上拉
回复

使用道具 举报

ID:1064915 发表于 2023-7-20 16:03 | 显示全部楼层
write_com(0x4a);
地址有误,改为
write_com(0x4a|0x80);
回复

使用道具 举报

ID:1089154 发表于 2023-7-20 22:26 | 显示全部楼层
DS18B20数据位要接上拉电阻
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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