温度传感器DS18B20:
初始化时序图如下图所示:
u8 ds18b20_init(void){
ds18b20_reset();
return ds18b20_check();
}
void ds18b20_reset(void){
DS18B20_PORT = 0;
delay_10us(75);
DS18B20_PORT = 1;
delay_10us(2);
}
u8 ds18b20_check(void){
u8 time_temp=0;
while(DS18B20_PORT && time_temp<20){ //检测低电平
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //没有响应
else time_temp = 0;
while(!DS18B20_PORT && time_temp<20){ //检测高电平
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //没有响应
return 0;
}
读时序:
u8 ds18b20_read_bit(void){
u8 dat = 0;
DS18B20_PORT = 0;
_nop_(); _nop_();
DS18B20_PORT=1;
_nop_();_nop_();
if(DS18B20_PORT)dat = 1;
else dat = 0;
delay_10us(5);
return dat;
}
u8 ds18b20_read_byte(){
u8 i=0;
u8 temp=0;
u8 dat = 0;
for(i=0;i<8;i++){
temp = ds18b20_read_bit();
dat >>=1; //先读低位再读高位
dat |= temp<<7;
}
return dat;
}
写时序:
void ds18b20_write_byte(u8 dat){
u8 i=0;
u8 temp=0;
for(i=0;i<8;i++){
temp = dat&0x01;
dat>>=1;
if(temp){
DS18B20_PORT = 0;
_nop_(); _nop_();//两个机器周期
DS18B20_PORT = 1;
delay_10us(6);
}else{
DS18B20_PORT = 0;
delay_10us(6);
DS18B20_PORT = 1;
_nop_(); _nop_();//两个机器周期
}
}
}
读取温度:
DS18B20 的典型温度读取过程为:复位→发 SKIP ROM 命令(0XCC)→发开始转
换命令(0X44)→延时→复位→发送 SKIP ROM 命令(0XCC)→发读存储器命令
(0XBE)→连续读出两个字节数据(即温度)→结束。
void ds18b20_start(){
ds18b20_reset();
ds18b20_check();
ds18b20_write_byte(0xcc);
ds18b20_write_byte(0x44);
}
float ds18b20_read_temperture(void){
u8 dath=0;
u8 datl=0;
u16 value;
float temp = 0;
ds18b20_start();
ds18b20_reset();
ds18b20_check();
ds18b20_write_byte(0xcc);
ds18b20_write_byte(0xbe);
datl = ds18b20_read_byte();
dath = ds18b20_read_byte();
value = (dath<<8) + datl;
if((value&0xf800) == 0xf800){
value = ~value + 1;
temp = value*(-0.0625);
}else{
temp = value*0.0625;
}
return temp;
}
完整代码:
#include "ds18b20.h"
#include "intrins.h"
void ds18b20_reset(void){
DS18B20_PORT = 0;
delay_10us(75);
DS18B20_PORT = 1;
delay_10us(2);
}
u8 ds18b20_check(void){
u8 time_temp=0;
while(DS18B20_PORT && time_temp<20){ //检测低电平
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //没有响应
else time_temp = 0;
while(!DS18B20_PORT && time_temp<20){ //检测高电平
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //没有响应
return 0;
}
u8 ds18b20_read_bit(void){
u8 dat = 0;
DS18B20_PORT = 0;
_nop_(); _nop_();
DS18B20_PORT=1;
_nop_();_nop_();
if(DS18B20_PORT)dat = 1;
else dat = 0;
delay_10us(5);
return dat;
}
u8 ds18b20_read_byte(){
u8 i=0;
u8 temp=0;
u8 dat = 0;
for(i=0;i<8;i++){
temp = ds18b20_read_bit();
dat >>=1; //先读低位再读高位
dat |= temp<<7;
}
return dat;
}
void ds18b20_write_byte(u8 dat){
u8 i=0;
u8 temp=0;
for(i=0;i<8;i++){
temp = dat&0x01;
dat>>=1;
if(temp){
DS18B20_PORT = 0;
_nop_(); _nop_();//两个机器周期
DS18B20_PORT = 1;
delay_10us(6);
}else{
DS18B20_PORT = 0;
delay_10us(6);
DS18B20_PORT = 1;
_nop_(); _nop_();//两个机器周期
}
}
}
void ds18b20_start(){
ds18b20_reset();
ds18b20_check();
ds18b20_write_byte(0xcc);
ds18b20_write_byte(0x44);
}
u8 ds18b20_init(void){
ds18b20_reset();
return ds18b20_check();
}
float ds18b20_read_temperture(void){
u8 dath=0;
u8 datl=0;
u16 value;
float temp = 0;
ds18b20_start();
ds18b20_reset();
ds18b20_check();
ds18b20_write_byte(0xcc);
ds18b20_write_byte(0xbe);
datl = ds18b20_read_byte();
dath = ds18b20_read_byte();
value = (dath<<8) + datl;
if((value&0xf800) == 0xf800){
value = ~value + 1;
temp = value*(-0.0625);
}else{
temp = value*0.0625;
}
return temp;
}