Kalman

  • 3 主题
  • 17 帖子
  • 610 积分
  • 身份:LV3 中级技术员
  • E币:494

【ART-Pi开发板】+DS18B20温度传感器

2021-2-28 18:41:30 显示全部楼层
本帖最后由 Kalman 于 2021-2-28 18:47 编辑

DS18B20是一款DALLAS公司推出的单总线数字温度测量芯片。它具有体积小,硬件开销低,抗干扰能力强,精度高的特点
这次实现在ART-Pi开发板上挂载1个DS18B20测量温度功能
硬件如下:
1.png
2.png
VDD接到电源,DQ接MCU引脚,GND接地,由于DQ引脚为开漏输出,不具有输出高电平的能力,必须要接一个上拉电阻


①新建工程
在RT-Thread Studio中新建基于ART-Pi开发板的模板工程
3.png
4.png

②初始化DS18B20
初始化时序如下:
5.png
MCU拉低总线至少480us,产生复位脉冲,然后释放总线(拉高电平);这时DS8B20检测到请求之后,会拉低信号,大约60~240us表示应答;DS8B20拉低电平的60~240us之间,单片机读取总线的电平,如果是低电平,那么表示初始化成功;DS18B20拉低电平60~240us之后,会释放总线
代码实现:
  1. //复位DS18B20
  2. void DS18B20_Rst(void)
  3. {
  4.     rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT); //输出模式
  5.     rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ
  6.     rt_hw_us_delay(750); //拉低750us(480~960us)
  7.     rt_pin_write(DS18B20_DQ, PIN_HIGH); //拉高DQ
  8. }

  9. //等待DS18B20应答,有应答返回0,无应答返回1
  10. uint8_t DS18B20_Check(void)
  11. {
  12.     uint8_t retry=0;
  13.     //进入接收模式,等待应答信号
  14.     //等待时间
  15.     rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //输入模式
  16.     rt_hw_us_delay(15); //等待15~60us
  17.     while(rt_pin_read(DS18B20_DQ)&&retry<120) //最多再等待120us
  18.     {
  19.         retry++;
  20.         rt_hw_us_delay(1);
  21.     };
  22.     if(retry>=120)
  23.         return 1; //120us未响应,则判断未检测到
  24.     else
  25.         retry=0;
  26.     //DS18B20开始拉低DQ
  27.     while(!rt_pin_read(DS18B20_DQ)&&retry<240) //最长拉低240us
  28.     {
  29.         retry++;
  30.         rt_hw_us_delay(1);
  31.     };
  32.     if(retry>=240)
  33.         return 1;
  34.     return 0;
  35. }

③写DS18B20时序
写时序如下:

6.png
MCU给DS18B20写0时,MCU引脚拉低,延时60us,然后释放总线,延时2us
MCU给DS18B20写1时,MCU引脚拉低,延时2us,然后释放总线,延时60us
在写时序起始后15μs到60μs期间,DS18B20处于采样单总线电平状态。如果在此期间总线为高电平,则向DS18B20写入1;如果总线为低电平,则向DSl8B20写入0
代码实现:
  1. //写字节到DS18B20
  2. void DS18B20_Write_Byte(uint8_t dat)
  3. {
  4.     uint8_t j;
  5.     uint8_t temp;

  6.     rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT); //输出模式
  7.     for(j=1;j<=8;j++)
  8.     {
  9.         temp=dat&0x01;
  10.         dat=dat>>1;
  11.         if (temp) //输出高
  12.         {
  13.             rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ
  14.             rt_hw_us_delay(2); //延时2us
  15.             rt_pin_write(DS18B20_DQ, PIN_HIGH); //拉高DQ
  16.             rt_hw_us_delay(60); //延时60us
  17.         }
  18.         else //输出低
  19.         {
  20.             rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ
  21.             rt_hw_us_delay(60); //延时60us
  22.             rt_pin_write(DS18B20_DQ, PIN_HIGH); //拉高DQ
  23.             rt_hw_us_delay(2); //延时2us
  24.         }
  25.     }
  26.     rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //输入模式
  27. }

④读DS18B20时序
读时序如下:
7.png
MCU拉低电平,延时2us;MCU转为输入模式,延时12us;然后读取单总线当前的电平,延时50us
代码实现:
  1. //从DS18B20读位
  2. uint8_t DS18B20_Read_Bit(void)
  3. {
  4.     uint8_t data;

  5.     rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT); //输出模式
  6.     rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ
  7.     rt_hw_us_delay(2); //延时2us
  8.     rt_pin_write(DS18B20_DQ, PIN_HIGH); //拉高DQ
  9.     rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //输入模式
  10.     rt_hw_us_delay(12); //延时12us
  11.     if(rt_pin_read(DS18B20_DQ)) //读DQ数据
  12.         data=1;
  13.     else
  14.         data=0;
  15.     rt_hw_us_delay(50); //延时50us
  16.     return data;
  17. }

  18. //从DS18B20读字节
  19. uint8_t DS18B20_Read_Byte(void)
  20. {
  21.     uint8_t i, j, dat=0;

  22.     for(i=1;i<=8;i++)
  23.     {
  24.         j=DS18B20_Read_Bit();
  25.         dat=(j<<7)|(dat>>1);
  26.     }
  27.     return dat;
  28. }

⑤温度读取
MCU发送复位信号,发送SKIP ROM命令(0XCC,匹配指令)
发开始转换命令(0X44)
延时等待转换完成(12bit分辨率时需要750ms)
MCU发送复位信号,发送SKIP ROM命令(0XCC)
发读存储器命令(0XBE),读取暂存器内容
连续读出两个字节数据
对读取的温度值进行转换
代码实现:
  1. //开始温度转换
  2. void DS18B20_Start(void)
  3. {
  4.     DS18B20_Rst();
  5.     DS18B20_Check();
  6.     DS18B20_Write_Byte(0xcc);
  7.     DS18B20_Write_Byte(0x44);
  8. }

  9. //读取温度值
  10. float DS18B20_Get_Temp(void)
  11. {
  12.     uint8_t sign; //温度符号,0为-,1为+
  13.     uint8_t TL,TH;
  14.     uint16_t temp;
  15.     float temp1;

  16.     DS18B20_Start ();
  17.     rt_thread_mdelay(800); //等待转换完成
  18.     DS18B20_Rst();
  19.     DS18B20_Check();
  20.     DS18B20_Write_Byte(0xcc);
  21.     DS18B20_Write_Byte(0xbe);
  22.     TL=DS18B20_Read_Byte();
  23.     TH=DS18B20_Read_Byte();
  24.     if(TH>7)
  25.     {
  26.         TH=~TH;
  27.         TL=~TL;
  28.         sign=0; //温度为负
  29.     }
  30.     else
  31.         sign=1; //温度为正
  32.     temp=TH; //高八位
  33.     temp<<=8;
  34.     temp+=TL; //低八位
  35.     temp1=(float)temp*0.0625; //转换实际温度
  36.     if(sign)
  37.         return temp1; //返回温度值
  38.     else
  39.         return -temp1;
  40. }

⑥实现如下:
8.png
本次实现单总线上挂载1个DS18B20测量温度,后续再实现总线上挂载多个DS18B20测量温度。








您需要登录后才可以评论 登录 | 立即注册

最新评论

楼层直达:

SnailWillow

  • 35 主题
  • 155 帖子
  • 1001 积分
  • 身份:版主
  • 论坛新秀
  • E币:1155
快速回复
1
9
广告
关闭 热点推荐上一条 /5 下一条
快速回复 返回列表