当前位置:   article > 正文

单片机驱动多个ds18b20_多个ds18b20怎么接

多个ds18b20怎么接

目录

1设计内容

2ds18b20介绍

2.1传感器引脚及原理图

2.2寄存器配置

3程序实现

3.1配置初始化

3.2配置寄存器

3.3ROM读取

3.4温度读取


1设计内容

通过51单片机,读取总线上挂载的多个ds18b20的温度信息。

如下图,成功读取到3路温度数据。

2ds18b20介绍

2.1传感器引脚及原理图


DS18B20传感器的引脚及封装图如下:


DS18B20一共有三个引脚,分别是:

GND:电源地线
DQ:数字信号输入/输出端。
VDD:外接供电电源输入端。


单个DS18B20接线方式: VDD接到电源,DQ接单片机引脚,同时外加上拉电阻,GND接地

注意这个上拉电阻是必须的,就是DQ引脚必须要一个上拉电阻.

2.2寄存器配置

DS18B20写入的功能命令:

ROM指令:

采用多个DS18B20时,需要写ROM指令来控制总线上的某个DS18B20
如果是单个DS18B20,直接写跳过ROM指令0xCC即可
在这里插入图片描述

RAM指令,DS18B20的一些功能指令

常用的是:

温度转换 0x44

开启温度读取转换,读取好的温度会存储在高速暂存器的第0个和第一个字节中

读取温度 0xBE
读取高速暂存器存储的数据
在这里插入图片描述

3程序实现

3.1配置初始化

  1. /**初始化DS18B20**/
  2. bit InitDS18B20ACK(){
  3. bit ACK;//用来判断DS18B20是否初始化成功
  4. EA = 0;
  5. DS18B20_IO = 0;
  6. DS18B20_delayms(1);
  7. DS18B20_IO = 1;
  8. DS18B20_delayms(1);
  9. DS18B20_IO = 0;
  10. DS18B20_delayms(1);
  11. ACK = DS18B20_IO;
  12. DS18B20_IO = 1;
  13. DS18B20_delayms(1);
  14. while(!DS18B20_IO);//等待脉冲结束
  15. EA = 1;
  16. return ACK;
  17. }

3.2配置寄存器

3.2.1读取ROM测试

在每个DS18B20内部都有一个唯一的64位长的序列号,这个序列号值就存在DS18B20内部的ROM中。开始的8位是产品类型编码(DS18B20是28H),接着的48位是每个器件唯一的序号,最后的8位是CRC校验码。
在这里插入图片描述

一线总线系统使用单总线主控来控制一个或多个从机设备。每个DS18B20都有独立唯一的64位-ID,此特性决定了它可以将任意多的DS18b20挂载到一根总线上,通过ROM搜索读取相应DS18B20的温度值。

  1. /**启动DS18B20进行温度的采集以及转换,并返回读取成功与否**/
  2. bit startDs18b201(){
  3. bit ACK;
  4. uchar i,x,k,z;
  5. uchar MSB,LSB;
  6. uchar temp[8];
  7. x=0;k=0;
  8. ACK = InitDS18B20ACK();//总线初始化是否完成
  9. if(ACK == 0){
  10. writeToDs18b20(0x33);//跳过ROM的验证操作
  11. //writeToDs18b20(0xbe);//发送一个读取的命令
  12. for(i=0;i<8;i++)
  13. {
  14. MSB = readeToDs18b20();
  15. dis0[i]=MSB;
  16. }
  17. for(i=0;i<4;i++)
  18. {
  19. k=IntToString(temp,(int)dis0[i]);
  20. for(z=0;z<k;z++)
  21. {
  22. LCD_Write_Char(x++,0,temp[z]);
  23. }
  24. }
  25. /*
  26. x=0;
  27. for(i=0;i<4;i++)
  28. {
  29. k=IntToString(temp,(int)dis0[i+4]);
  30. for(z=0;z<k;z++)
  31. {
  32. LCD_Write_Char(x++,1,temp[z]);
  33. }
  34. }
  35. */
  36. LCD_Write_String(0,1,dis0);
  37. while(1);
  38. //DS18B20_delayms(500); //上电转换需要延时足够长时间,否则会读出默认值85 会造成main里面后续任务一直等待,改为通过变量控制。
  39. }
  40. return ACK;//ACK == 0 启动成功,1就不成功
  41. }

通过连接多个温湿度测试,第一位都是( ,对应16进制28,10进制40.

3.3ROM读取

上面那个只是测试,直接用下面这个读取rom

  1. /*************************************************************************************************************************
  2. *函数 : u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num)
  3. *功能 : 搜索DS18B20 ROM
  4. *参数 : pID:DS18B20 ID缓冲区指针
  5. Num:DS18B20数目,必须事先知道
  6. *返回 : 搜索到的DS18B20数目
  7. *说明 : 程序必须事先知道DS18B20数目,搜索的数目只会小于这个数目
  8. 代码移植于互联网
  9. *************************************************************************************************************************/
  10. u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num)
  11. {
  12. unsigned char k,l,chongtuwei,m,n;
  13. unsigned char zhan[(MAXNUM)]= {0x00 }; //一定要初始化为0,否则会概率性搜错
  14. unsigned char ss[64];
  15. bit ACK;
  16. uchar MSB,LSB;
  17. uchar dis1111[16];
  18. u8 num = 0;
  19. l=0;
  20. chongtuwei=0;
  21. do
  22. {
  23. ACK = InitDS18B20ACK();
  24. writeToDs18b20(0xf0);//搜索rom
  25. //DS18B20_WriteData(0xf0);
  26. for(m=0;m<8;m++)
  27. {
  28. unsigned char s=0;
  29. for(n=0;n<8;n++)
  30. {
  31. k=DS18B20_Read2Bit();//读两位数据
  32. if(n==1)
  33. {
  34. sprintf(dis1111,"dis1111 %d ",(int)k);
  35. LCD_Write_String(0,0,dis1111);
  36. //while(1);
  37. }
  38. k=k&0x03;
  39. s>>=1;
  40. if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应
  41. {
  42. DS18B20_WriteBit (0);
  43. ss[(m*8+n)]=0;
  44. }
  45. else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应
  46. {
  47. s=s|0x80;
  48. DS18B20_WriteBit (1);
  49. ss[(m*8+n)]=1;
  50. }
  51. else if(k==0x00)//读到的数据为00 有冲突位 判断冲突位
  52. { //如果冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写1
  53. chongtuwei=m*8+n+1;
  54. if(chongtuwei>zhan[l])
  55. {
  56. DS18B20_WriteBit (0);
  57. ss[(m*8+n)]=0;
  58. zhan[++l]=chongtuwei;
  59. }
  60. else if(chongtuwei<zhan[l])
  61. {
  62. s=s|((ss[(m*8+n)]&0x01)<<7);
  63. DS18B20_WriteBit (ss[(m*8+n)]);
  64. }
  65. else if(chongtuwei==zhan[l])
  66. {
  67. s=s|0x80;
  68. DS18B20_WriteBit (1);
  69. ss[(m*8+n)]=1;
  70. l=l-1;
  71. }
  72. }
  73. else
  74. {
  75. return num; //搜索完成,//返回搜索到的个数
  76. }
  77. }
  78. pID[num][m]=s;
  79. }
  80. num=num+1;
  81. }
  82. while(zhan[l]!=0&&(num<MAXNUM));
  83. return num; //返回搜索到的个数
  84. }

3.4温度读取

  1. do{
  2. num = DS18B20_SearchROM(ID_Buff,DS18B20_NUM);
  3. sprintf(dis0,"DS18B20_NUM %d ",(int)DS18B20_NUM);
  4. LCD_Write_String(0,0,dis0);
  5. sprintf(dis1,"num %d ",(int)num);
  6. LCD_Write_String(0,1,dis1);
  7. }while(num!=DS18B20_NUM);
  8. startDs18b20();
  9. //while(1);
  10. DelayMs(500);DelayMs(500);DelayMs(500);DelayMs(500);
  11. while(1)
  12. {
  13. //温度传感器-----start
  14. if(readTemFlags == 1)
  15. {
  16. readTemFlags = 0;//清零
  17. //DelayMs(500); //启动ds18b20后一定要延时,流出转换时间,否则读出为-1
  18. temperature = DS18B20_ReadDesignateTemper(ID_Buff[i ++]);
  19. startDs18b20();
  20. temp_int = temperature/100;//取整数部分
  21. temp_dec = temperature%100;//取小数部分
  22. len = IntToString(str,(int)temp_int);
  23. }
  24. //temperature = temperature >> 4;
  25. sprintf(dis1,"temp[%d] %d.%d ",(int)i,(int)temp_int,(int)temp_dec);
  26. LCD_Write_String(0,1,dis1);
  27. if(i>3) i=0;
  28. DelayMs(100);DelayMs(500);DelayMs(500);DelayMs(500);
  29. }

项目整体链接如下。

https://download.csdn.net/download/weixin_51248645/88797969

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/647917
推荐阅读
相关标签
  

闽ICP备14008679号