温度传感器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;
}