DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器(如热敏电阻),具有功能强大、硬件简单、易扩展、抗干扰性强等特点
测温范围:-55°C 到 +125°C通信接口:1-Wire(单总线)
其它特征:可形成总线结构、内置温度报警功能、可寄生供电
通过DQ线对该器件进行通讯
单总线:
单总线(1-Wire BUS)是由Dallas公司开发的一种通用数据总线
一根通信线:DQ异步、半双工
单总线只需要一根通信线即可实现数据的双向传输,当采用寄生供电时,还可以省去设备的VDD线路,此时,供电加通信只需要DQ和GND两根线
单总线电路规范:
- 设备的DQ均要配置成开漏输出模式
- DQ添加一个上拉电阻,阻值一般为4.7KΩ左右(前两条原因同I2C多机通讯)
- 若此总线的从机采取寄生供电,则主机还应配一个强上拉输出电路
不采用寄生供电:
采用寄生供电:
单总线时序结构:
ROM指令:对64 BIT ROM进行操作
功能操作:对RAM暂存器进行操作
数据帧:
sbit OneWire_DQ = P3^7;
/**
* @brief 单总线初始化
* @param
* @retval 从机应答返回0,反之返回1
*/
unsigned char OneWire_Init(){
unsigned char i, AckBit;
OneWire_DQ = 1; // 初始化DQ
OneWire_DQ = 0; // 拉低DQ
i = 219; while (--i);// 主机延时481us
OneWire_DQ = 1; // 主机释放总线
i = 29; while (--i); // 主机延时70us,等待从机操作
AckBit = OneWire_DQ;
i = 219; while (--i);// 主机延时481us,等待从机释放总线
return AckBit;
}
/**
* @brief 单总线发送一位
* @param Bit 待发送的位
* @retval
*/
void OneWire_SendBit(unsigned char Bit){
unsigned char i;
OneWire_DQ = 0; // 拉低DQ
i = 3; while (--i); // 主机延时13us
OneWire_DQ = Bit; // 放入总线
i = 22; while (--i); // 主机延时54us,等待从机操作
OneWire_DQ = 1; // 主机释放总线
}
/**
* @brief 单总线接收一位
* @param
* @retval 接收来的位
*/
unsigned char OneWire_ReceiveBit(){
unsigned char i, Bit;
OneWire_DQ = 0; // 拉低DQ
i = 2; while (--i); // 延时10us
OneWire_DQ = 1; // 主机释放总线
i = 2; while (--i); // 延时10us,等待从机操作
Bit = OneWire_DQ; // 读取总线值
i = 21; while (--i); // 延时50us,等待从机释放总线
return Bit;
}
/**
* @brief 单总线发送一个字节
* @param Byte 待发送的字节
* @retval
*/
void OneWire_SendByte(unsigned char Byte){
unsigned char i;
for(i = 0; i < 8; i++){
OneWire_SendBit(Byte & (0x01 << i));
}
}
/**
* @brief 单总线接收一个字节
* @param
* @retval 接收来的字节
*/
unsigned char OneWire_ReceiveByte(){
unsigned char i, Byte = 0;
for(i = 0; i < 8; i++){
if(OneWire_ReceiveBit()){Byte |= 0x01 << i;}
}
return Byte;
}
//DS18B20指令
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE
/**
* @brief 更新温度暂存器
* @param
* @retval
*/
void DS18B20_ConvertT(){
OneWire_Init();
OneWire_SendByte(DS18B20_SKIP_ROM); // skip rom
OneWire_SendByte(DS18B20_CONVERT_T); // 更新暂存器
}
/**
* @brief 读取温度暂存器中的温度值
* @param
* @retval 温度的浮点型
*/
float DS18B20_ReadT(){
unsigned char TLSB, TMSB;
int temp;
float T;
OneWire_Init();
OneWire_SendByte(DS18B20_SKIP_ROM); // skip rom
OneWire_SendByte(DS18B20_READ_SCRATCHPAD); // 读取暂存器
TLSB = OneWire_ReceiveByte(); // 读取
TMSB = OneWire_ReceiveByte();
temp = (TMSB << 8) | TLSB; // 组合结果,高8位和低8位
T = temp / 16.0; // 低4位表示小数,所以把第5位放到个位上(二进制左移一位等效于十进制乘二)
return T;
}
显示float:
if(t < 0){
t = -t;
LCD_ShowChar(1, 1, '-');
}else{
LCD_ShowChar(1, 1, '+');
}
LCD_ShowNum(1, 2, t, 3);
LCD_ShowChar(1, 5, '.');
LCD_ShowNum(1, 6, (unsigned long)(t * 10000) % 10000, 4);
}