一.单总线协议时序对应代码
1.延时函数
//单总线延时函数,约1~2us
void Delay_OneWire(unsigned int t)
{
static unsigned char i;
while(t--)
{
for(i=0;i<12;i++);
}
}
2.初始化
sbit DQ=P1^4;
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1; //总线复位
Delay_OneWire(12);
DQ = 0; //拉低总线(480us~960us)
Delay_OneWire(80);
DQ = 1; //拉高总线(15~60us)
Delay_OneWire(10);
initflag = DQ; //接收返回,0-成功,2-失败
Delay_OneWire(5);
return initflag;
}
3.读/写
//通过单总线向DS18B20写一个字节,先写低位
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0; //拉低总线,需要在15us以内写入数据
DQ = dat&0x01; //写入数据(60~120us)
Delay_OneWire(5);
DQ = 1; //拉高总线
dat >>= 1; //准备写入下一位
}
Delay_OneWire(5);
}
//从DS18B20读取一个字节,先读低位
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0; //拉低总线(1us)
dat >>= 1; //准备读取下一位
DQ = 1; //拉高总线,此处似乎与时序图有差异
if(DQ) //读取总线电平(45us)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
二.DS18B20
1.接线图
2.DS18B20讲解
1.温度寄存器
DS18B20的温度值由两个8位寄存器存储;
其中低字节寄存器的低4位是温度的小数部分,因此最小精度为2^(-4)=0.0625;
低字节寄存器的高4位与高字节寄存器的低3位共同存储整数部分;
高字节寄存器的高5位是符号位。00000—正,11111—负。
3.代码
//读取温度值
unsigned char rd_temperature(void)
{
unsigned int temp;
unsigned char low, high;
float tempterature;
init_ds18b20();
Write_DS18B20(0xCC); //忽略ROM指令
Write_DS18B20(0x44); //启动温度转换指令
Delay_OneWire(200);
init_ds18b20();
Write_DS18B20(0xCC); //忽略ROM指令
Write_DS18B20(0xBE); //读取寄存器指令
Delay_OneWire(200);
low=Read_DS18B20(); //读取低8位
high=Read_DS18B20(); //读取高8位
//11位,最低4位表示小数部分,精度为0.0625
temp=high;
temp=temp<<8|low;
temperature=temp*0.0625; //数字量回归成模拟量
temperature=temperature*10+0.5; //保留一位小数并四舍五入
return (unsigned char)temperature;
}
Tips:
1.读取温度之前关闭总中断,防止中断干扰读取,读完温度再重新打开中断。