1.STM32 DS18B20
1.独特的单总线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。大大提高了系统的抗干扰性。
2.测温范围 -55℃~+125℃,精度为±0.5℃。
3.支持多点组网功能,多个DS18B20可以并联在唯一的三线(地,电源,数据线)上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。
4 .工作电源: 3.0~5.5V/DC (可以数据线寄生电源)。
5.在使用中不需要任何外围元件。
6 .测量结果以9~12位数字量方式串行传送。
2.STM32 DS18B20封装
1.
2.
3.STM32 DS18B20硬件连接## 4.STM32 DS18B20
1.是一种单总线,只有一根数据线,是一种半双工通信方式
2.有6种信号,复位脉冲,应答脉冲,写0,写1,读0,和读1。这些信号,除了应答信号以为,都是由主机发送同步信号,而且发送的所有的命令和数据都是低位在前。
5.STM32 DS18B20信号
1.复位信号
单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480 us,,以产生复位脉冲。(脉冲产生)
接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60 us。并进入接收模式(Rx)。
接着DS18B20拉低总线60~240 us,以产生低电平应答脉冲
就是产生脉冲,进入接收,产生应答
2.应答信号
把IO口设置为输入,等待DQ被拉低,或者等待200us超过时间了(直接返回没有应答)
第二个while是判断拉低的应答是否小于240us,如果超过就不是正常的应答
3.写信号
写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。
相反的
写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。
写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。
4.读信号
单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。
所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。
典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。
读一个位
读一个字节
6.STM32 DS18B20获取温度流程
复位 > 等待应答 > 发SKIP ROM命令(0xcc)> 发开始转换命令 > 延时 > 发送SKIP ROM命令
发读存储器命令(0xbe) > 连续读出两个字节数据
7.STM32 DS18B20源码
正点的ds18b20代码
#include "ds18b20.h"
#include "delay.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F429开发板
//DS18B20驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/16
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//
//复位DS18B20
void DS18B20_Rst(void)
{
DS18B20_IO_OUT(); //设置为输出
DS18B20_DQ_OUT=0; //拉低DQ
delay_us(750); //拉低750us
DS18B20_DQ_OUT=1; //DQ=1
delay_us(15); //15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void)
{
u8 retry=0;
DS18B20_IO_IN(); //设置为输入
while (DS18B20_DQ_IN&&retry<200)
{
retry++;
delay_us(1);
};
if(retry>=200)return 1;
else retry=0;
while (!DS18B20_DQ_IN&&retry<240)
{
retry++;
delay_us(1);
};
if(retry>=240)return 1;
return 0;
}
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void)
{
u8 data;
DS18B20_IO_OUT(); //设置为输出
DS18B20_DQ_OUT=0;
delay_us(2);
DS18B20_DQ_OUT=1;
DS18B20_IO_IN(); //设置为输入
delay_us(12);
if(DS18B20_DQ_IN)data=1;
else data=0;
delay_us(50);
return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)
{
u8 i,j,dat;
dat=0;
for (i=1;i<=8;i++)
{
j=DS18B20_Read_Bit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)
{
u8 j;
u8 testb;
DS18B20_IO_OUT(); //设置为输出
for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) // 写1
{
DS18B20_DQ_OUT=0;
delay_us(2);
DS18B20_DQ_OUT=1;
delay_us(60);
}
else //写0
{
DS18B20_DQ_OUT=0;
delay_us(60);
DS18B20_DQ_OUT=1;
delay_us(2);
}
}
}
//开始温度转换
void DS18B20_Start(void)
{
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0x44);// convert
}
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在
u8 DS18B20_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟
GPIO_Initure.Pin=GPIO_PIN_12; //PB12
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化
DS18B20_Rst();
return DS18B20_Check();
}
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250)
short DS18B20_Get_Temp(void)
{
u8 temp;
u8 TL,TH;
short tem;
DS18B20_Start (); //开始转换
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc); // skip rom
DS18B20_Write_Byte(0xbe); // convert
TL=DS18B20_Read_Byte(); // LSB
TH=DS18B20_Read_Byte(); // MSB
if(TH>7)
{
TH=~TH;
TL=~TL;
temp=0;//温度为负
}else temp=1;//温度为正
tem=TH; //获得高八位
tem<<=8;
tem+=TL;//获得底八位
tem=(double)tem*0.625;//转换
if(temp)return tem; //返回温度值
else return -tem;
}