单片机外设驱动-DS18B20温度传感器
DS18B20介绍
单总线数字温度传感器DS18B20几乎成了各类单片机甚至ARM实验板的标配模块。
不管是嵌入式的学习还是蓝桥杯的备赛,都应熟悉DS18B20的工作原理,掌握DS18B20的基本操作,也就是把传感器的温度数据正确读出来。
DS18B20单线通信功能是分时完成的,它有严格的时隙概念,如果出现序列混乱,器件将不响应主机。
DS18B20的协议
步骤1: 复位初始化
步骤2: ROM操作指令
步骤3: DS18B20功能指令
<1> CCH:跳过ROM指令,忽略64位ROM地址,直接向DS18B20发起各种温度转换指令。
<2> 44H:温度转换指令,启动DS18B20进行温度转换,转换时间最长为500ms(典型值为200ms),结果保存在高速RAM中。
<3> BEH:读暂存器指令,读取高速暂存存储器9个字节的内容。
读取DS18B20温度的基本操作
1. 主机对DS18B20进行复位初始化。
2. 主机向DS18B20写0xCC命令,跳过ROM。
3. 主机向DS18B20写0x44命令,开始进行温度转换。
4. 等待温度转换完成。
5. 主机对DS18B20进行复位初始化。
6. 主机向DS18B20写0xCC命令,跳过ROM。
7. 主机向DS18B20写0xBE命令,依次读取DS18B20发出的从第0一第8,共九个字节的数据。
DS18B20电路原理图
可以看出DS18b20的接线得却十分简单,但需要注意的是,当传感器与单片机相连时,要加一个4.7K的上拉电阻(5K左右即可)
DS18B20驱动
//DS18B20初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80); // 延时大于480us
DQ = 1;
Delay_OneWire(10); // 14
initflag = DQ; // initflag等于1初始化失败
Delay_OneWire(5);
return initflag;
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0; i<8; i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0; i<8; i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//DS18B20温度采集程序:整数
unsigned char rd_temperature(void)
{
unsigned char low,high;
char temp;
init_ds18b20();
Write_DS18B20(0xCC); //跳过ROM指令
Write_DS18B20(0x44); //启动温度转换
Delay_OneWire(200);
init_ds18b20();
Write_DS18B20(0xCC); //跳过ROM指令
Write_DS18B20(0xBE); //读取寄存器
low = Read_DS18B20(); //低字节
high = Read_DS18B20(); //高字节
/** 精度为1摄氏度 */
temp = high<<4;
temp |= (low>>4);
return temp;
}
//DS18B20温度采集程序:浮点数
float rd_temperature_f(void)
{
unsigned int temp;
float temperature;
unsigned char low,high;
init_ds18b20();
Write_DS18B20(0xCC); //跳过ROM指令
Write_DS18B20(0x44); //启动温度转换
Delay_OneWire(200);
init_ds18b20();
Write_DS18B20(0xCC); //跳过ROM指令
Write_DS18B20(0xBE); //读取寄存器
low = Read_DS18B20(); //低字节
high = Read_DS18B20(); //高字节
/** 精度为0.0625摄氏度 */
temp = (high&0x0f);
temp <<= 8;
temp |= low;
temperature = temp*0.0625;
return temperature;
}
举一个例子来说明这个处理的具体过程:
假设DS18B20的温度采样结果是:LSB = 0x96,MSB = 0x01。
温度数据变量T_dat为16位无符号int整型,初始值为0x0000。
执行T_dat = MSB;语句后, T_dat 的值为:0x0001。
执行T_dat <<= 8;语句后, T_dat 的值为:0x0100。
执行T_dat = T_dat | LSB;语句后, T_dat 的值为:0x0196。
通过高5位的符号扩展位判断,进行正温度的处理算法,正常来说,应该是:
T_dat = 0x0196 × 0.0625 = 406 × 0.0625 = 25.375 摄氏度。
实验效果
用手摸一会温度传感器数值就上去了 额…我是不是有点虚 ,,Ծ‸Ծ,,