找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4673|回复: 8
收起左侧

protues仿真DS18B20一直失败,各位大佬帮忙看一下?

[复制链接]
ID:814988 发表于 2020-8-18 11:25 | 显示全部楼层 |阅读模式
uint init_DS18B02()//DS18B02初始化
{
uint x;//用于检测DS18B02是否存在,1是并不存在,0是存在
DQ=1;//先将电平拉高
_nop_();
DQ=0;//将电平拉低,要求保持480uS-960uS
delay_us(48);
DQ=1;//释放电平
delay_us(3);
x=DQ;//保持DS18B02是否存在的电平  
delay_us(6);  //延时足够长的时间,等待存在脉冲输出完毕
DQ=1;
delay_us(44);
return x;//返回是否存在
}


void write_DS18B02(uchar date)  //DS18B20写一个字节
{
uint i;
for(i=0;i<8;i++)
{
  DQ=1;
  _nop_();
  DQ=0;
  _nop_();
  _nop_();
  DQ=1;
  delay_us(4);
  DQ=date&0x01;
  _nop_();
  _nop_();
  date>>=1;
}
delay_us(1);
}


uchar Read_DS18B02()//从DS18B02读一节数据
{
uint i;
uchar date=0;//读出的一节数据
for(i=0;i<8;i++)
{
  DQ=1;//将电平拉高
  _nop_();//等待1us(一个机器周期)
  DQ=0;//拉低电平
  _nop_();
  _nop_();
  DQ=1;//拉高电平,为输出电平做准备
  date>>=1;
  if(DQ)
  {
   date|=0x80; //如果读到数据是1,将1存入date
  }
  _nop_();
  _nop_(); //延时3us,|两个读时序之间需要2us恢复期
  _nop_();
}
return date;
}
注释可能有错误,被我改了好多次了。




51hei截图20200818112037.png

DS18B20.rar

55.26 KB, 下载次数: 16

回复

使用道具 举报

ID:235954 发表于 2020-8-18 15:57 | 显示全部楼层
论坛里面例程很多
回复

使用道具 举报

ID:235200 发表于 2020-8-19 00:15 | 显示全部楼层
只需修改程序中的延时程序,使之符合DS18B20读写时序即可
回复

使用道具 举报

ID:213173 发表于 2020-8-19 06:52 | 显示全部楼层
主要问题是时序不当和数据处理不当。
无标题.jpg

  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uchar unsigned char
  4. #define uint unsigned int

  5. void display1_Temperature(int temp);
  6. int num1(uchar temp1,uchar temp2);
  7. uint shu10(t);
  8. uint time;

  9. uchar code cdis1[]="Error!!!";
  10. uchar code cdis2[]="Xianzaiwendu:";
  11. uchar code cdis3[]="Temp:XXXX.X*C";
  12. uint code date1[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

  13. sbit RS=P2^0;
  14. sbit RW=P2^1;
  15. sbit EN=P2^2;
  16. sbit DQ=P3^7;

  17. void delay_ms(uchar ms)//毫秒延时
  18. {
  19.         uint x,y;
  20.         for(x=ms;x>0;x--)
  21.                 for(y=124;y>0;y--);
  22. }
  23. //大致延时长度如下 T=us×2+5 uS
  24. void delay_us(uchar us)
  25. {
  26.         while(--us);
  27. }

  28. bit busy()        //检测LCD1602忙
  29. {
  30.         bit Bit;
  31.         RS=0;
  32.         RW=1;
  33.         EN=1;
  34.         delay_ms(1);
  35.         Bit=(bit)(P0&0x80);//最高位为忙信号位
  36.         EN=0;
  37.         return Bit;
  38. }
  39. void write_com(uchar com)//LCD1602写指令函数
  40. {
  41.         while(busy());
  42.         RS=0;
  43.         RW=0;
  44.         P0=com;
  45.         delay_ms(5);
  46.         EN=1;
  47.         delay_ms(5);
  48.         EN=0;
  49. }
  50. void pos_LCD(uchar pos)//LCD的显示位置
  51. {
  52.         write_com(0x80|pos);
  53. }

  54. void write_date(uchar date)//LCD1602写数据函数
  55. {
  56.         while(busy());         //测忙
  57.         RS=1;
  58.         RW=0;
  59.         P0=date;
  60.         delay_ms(5);
  61.         EN=1;
  62.         delay_ms(5);
  63.         EN=0;
  64. }
  65. void init_LCD1602()//LCD1602初始化
  66. {
  67.         EN=0;
  68.         write_com(0X38);//设置16*2显示,5*7点阵,8位数据接口
  69.         write_com(0X0C);//设置开显示,不开光标
  70.         write_com(0X06);//写一个字符时,整屏右移
  71.         write_com(0X01);//显示清零
  72. }

  73. bit init_DS18B02()//DS18B02初始化
  74. {
  75.         bit x;//用于检测DS18B02是否存在,1是并不存在,0是存在       
  76.         DQ=1;//先将电平拉高       
  77.         delay_us(5);
  78.         DQ=0;//将电平拉低,要求保持480uS-960uS
  79.         delay_us(200);
  80.         delay_us(200);
  81.         DQ=1;//释放电平
  82.         delay_us(50);       
  83.         x=DQ;//保持DS18B02是否存在的电平               
  84.         delay_us(25);//延时足够长的时间,等待存在脉冲输出完毕
  85.         return x;//返回是否存在
  86. }
  87. void write_DS18B02(uchar date)         //DS18B20写一个字节
  88. {
  89.         uint i;
  90.         for(i=8;i>0;i--)
  91.         {
  92.                 DQ=0;
  93.                 DQ=date&0x01;
  94.                 delay_us(25);
  95.                 DQ=1;
  96.                 date>>=1;
  97.         }
  98.         delay_us(25);       
  99. }
  100. uchar Read_DS18B02()//从DS18B02读一节数据
  101. {
  102.         uint i;
  103.         uchar date=0;//读出的一节数据
  104.         for(i=8;i>0;i--)
  105.         {
  106.                 DQ=0;//拉低电平
  107.                 date>>=1;
  108.                 DQ=1;//拉高电平,为输出电平做准备
  109.                 if(DQ)
  110.                         date|=0x80;        //如果读到数据是1,将1存入date
  111.                 delay_us(25);
  112.         }
  113.         return date;
  114. }
  115. void error()//显示检测不到DS18B02
  116. {
  117.         uint i;
  118.         pos_LCD(0x00);//设置显示位置为第一行
  119.         for(i=0;i<8;i++)write_date(cdis1[i]);       
  120. }
  121. void display_explan1()//第一行的显示
  122. {
  123.         uint i;
  124.         pos_LCD(0x00);//设置显示位置为第一行
  125.         for(i=0;i<13;i++)write_date(cdis2[i]);       
  126. }
  127. void display_explan2()//第二行的显示
  128. {
  129.         uint i;
  130.         pos_LCD(0x40);//设置显示位置为第二行
  131.         for(i=0;i<13;i++)write_date(cdis3[i]);
  132. }
  133. uint display()//读温度
  134. {
  135.         uchar L;
  136.         uint t,H;
  137.         init_DS18B02();//DS18B02初始化
  138.         write_DS18B02(0xCC);//跳过读序号的操作
  139.         write_DS18B02(0x44);//启动温度转换
  140.         delay_ms(10);//温度转换需要一点时间
  141.         init_DS18B02();//DS18B02初始化
  142.         write_DS18B02(0xCC);//跳过读序号的操作
  143.         write_DS18B02(0xBE);//读取温度寄存器
  144.         L=Read_DS18B02();
  145.         H=Read_DS18B02();
  146.         t=H<<8|L;
  147.         return(t);
  148. }

  149. void main()
  150. {
  151.         uchar Temp_L,Temp_H;
  152.         uint Temp;
  153.         bit negative=0;
  154.         init_LCD1602();//LCD1602初始化       
  155.         if(init_DS18B02()==1)//检测不到DS18B02
  156.                 error();//显示检测不到DS18B02
  157.         display_explan1();//第一行的显示
  158.         display_explan2();//第二行的显示

  159.         while(1)
  160.         {
  161.                 Temp=display();
  162.                  if(Temp&0x8000)       
  163.                 {
  164.                         negative=1;
  165.                         Temp=~Temp+1;
  166.                 }
  167.                 else negative=0;
  168.                
  169.                 Temp_H=Temp>>4;                //分解出整数
  170.                 Temp_L=Temp&0x0f;           //分解出小数
  171.                 Temp_L=Temp_L*0.625;        //保留一位小数

  172.                 write_com(0xc5);
  173.                 if(negative==1)
  174.                         write_date('-');
  175.                 else
  176.                         write_date('+');
  177.                 write_date(Temp_H/100+'0');
  178.                 write_date(Temp_H/10%10+'0');
  179.                 write_date(Temp_H%10+'0');
  180.                 write_date('.');
  181.                 write_date(Temp_L+'0');
  182.                 write_date(0xdf);
  183.                 delay_us(10);
  184.         }  
  185. }
复制代码



回复

使用道具 举报

ID:744327 发表于 2020-8-19 08:17 | 显示全部楼层
DS18B20读写时序,在单片机发送复位脉冲低电平保持至少480us释放总线进入接收状态
回复

使用道具 举报

ID:814988 发表于 2020-8-19 08:31 | 显示全部楼层
csmyldl 发表于 2020-8-19 00:15
只需修改程序中的延时程序,使之符合DS18B20读写时序即可

已解决,谢谢大佬。
回复

使用道具 举报

ID:814988 发表于 2020-8-31 11:25 | 显示全部楼层
wulin 发表于 2020-8-19 06:52
主要问题是时序不当和数据处理不当。

谢谢大佬。
回复

使用道具 举报

ID:235954 发表于 2020-8-31 14:04 | 显示全部楼层
大佬们就是厉害,火速解决问题
回复

使用道具 举报

ID:786629 发表于 2020-9-23 23:06 | 显示全部楼层
wulin 发表于 2020-8-19 06:52
主要问题是时序不当和数据处理不当。

所以你这原理图能显示数据也是奇葩,能不能帮帮我,我发现ds18b20无法转换温度,就是没数据也不知道怎么回事
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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