📄 ds18b20_driver.c
字号:
//------------------------------------------------------------------------------
// 文件名:DS18B20_driver.c
// 说明: DS18B20驱动头文件
// 功能: 实现1-wire器件的读写
// 使用方法: void Delay_nus(unsigned int n); //延时n微秒函数
// unsigned char reset_18B20(void); //18B20复位
// void write_bit_18B20(char bitval); //写一位到18B20
// unsigned char read_bit_18B20(void); //读一位从18B20
// void write_byte_18B20(unsigned char data); //写一字节到18B20
// unsigned char read_18B20(void); //读一字节到18B20
//
// 运行平台: AVR 8bit (M128已验证)
// 依存关系: DS18B20_driver.h DS18B20基本驱动头文件(函数声明)
// 移植人: 刘大川
// 最后修改: 2008-6-3
//------------------------------------------------------------------------------
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "DS18B20_driver.h"
#define CL_DQ PORTD&=~(1<<PD0)
#define SET_DQ PORTD|=(1<<PD0)
#define SET_OUT DDRD|=(1<<PD0)
#define SET_IN DDRD&=~(1<<PD0)
#define IN_DQ PIND&(1<<PD0)
//------------------------------------------------------------------------------
// 延时N微秒程序 供控制读写DS18B20时序使用
//------------------------------------------------------------------------------
void Delay_nus(unsigned int n){
while(n--){
_delay_us(1);
}
}
//------------------------------------------------------------------------------
// 1-wire总线复位
//------------------------------------------------------------------------------
unsigned char reset_18B20(void)
{
char bus_flag;
cli();
SET_DQ;
SET_OUT;
Delay_nus(2);
CL_DQ;
Delay_nus(550); //拉低至少480us时间
SET_DQ; //释放
SET_IN; //输入
Delay_nus(60);
//while(IN_DQ); //等待回复
bus_flag = IN_DQ;
Delay_nus(240); //回复的低电平在60到240US
SET_OUT;
SET_DQ; //回到初始DQ=1;
sei();
if(bus_flag){
return FALSE;
}else{
return TRUE;
}
}
//------------------------------------------------------------------------------
// 写一位到总线
//------------------------------------------------------------------------------
void write_bit_18B20(char bitval)
{
SET_OUT;
CL_DQ;
Delay_nus(2);
if(bitval){ //写数据,从低位开始
SET_DQ;
}else{
CL_DQ;
}
Delay_nus(40); //15~60us
SET_DQ;
Delay_nus(10);
}
//------------------------------------------------------------------------------
// 读一位从总线
//------------------------------------------------------------------------------
unsigned char read_bit_18B20(void)
{
unsigned char k;
SET_OUT;
CL_DQ; //读时间片开始,拉低总线至少1us
Delay_nus(2);
//SET_DQ;
SET_IN;
Delay_nus(5);
k=IN_DQ; //读数据,从低位开始
Delay_nus(10);
SET_DQ;
SET_OUT;
if(k){
return 1;
}else{
return 0;
}
}
//------------------------------------------------------------------------------
// 写一个字节到总线
//------------------------------------------------------------------------------
void write_byte_18B20(unsigned char data)
{
unsigned char i;
cli();
for(i=0;i<8;i++)
{
/*
CL_DQ;
Delay_nus(2);
if(data&(1<<i)){ //写数据,从低位开始
SET_DQ;
}else{
CL_DQ;
}
Delay_nus(60); //15~60us
SET_DQ;
Delay_nus(10);
*/
write_bit_18B20(data&(1<<i));
}
SET_DQ;
sei();
return;
}
//------------------------------------------------------------------------------
// 读一个字节
//------------------------------------------------------------------------------
unsigned char read_byte_18B20(void)
{
unsigned char temp,n;
cli();
temp=0;
for(n=0;n<8;n++)
{
/*
//主机读过程
CL_DQ; //读时间片开始,拉低总线至少1us
Delay_nus(1);
SET_DQ;
SET_IN;
Delay_nus(4);
k=IN_DQ; //读数据,从低位开始
SET_OUT;
*/
if(read_bit_18B20()){
temp|=(1<<n);
}else{
temp&=~(1<<n);
}
Delay_nus(70); //60~120us
}
sei();
return (temp);
}
//------------------------------------------------------------------------------
// 应用函数部分! 供外部调用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// 单器件:读器件ID
//------------------------------------------------------------------------------
void get_ID(char * id_addr)
{
unsigned char i;
reset_18B20();
write_byte_18B20(0x33);
for(i=0;i<8;i++){
id_addr[i] = read_byte_18B20();
}
return;
}
//------------------------------------------------------------------------------
// 单器件/多器件:开始转换
//------------------------------------------------------------------------------
void convert_T(void)
{
if(reset_18B20()){
write_byte_18B20(0xcc);
write_byte_18B20(0x44);
}
}
//------------------------------------------------------------------------------
// 单器件:读温度,返回INIT8U型温度数据(原始数据)
//------------------------------------------------------------------------------
unsigned int read_T(void)
{
unsigned int value=0;
if(reset_18B20()){
write_byte_18B20(0xcc);
write_byte_18B20(0xbe);
}
value = (unsigned int)read_byte_18B20();
value += ((unsigned int)(read_byte_18B20()))<<8;
return(value);
}
//------------------------------------------------------------------------------
// 多器件:读指定id的温度
//------------------------------------------------------------------------------
unsigned int read_id_T(char * id_addr)
{
unsigned int value = 0;
unsigned char i;
//复位总线
reset_18B20();
//匹配ROM
write_byte_18B20(0x55);
//发ID
for(i=0;i<8;i++)
{
write_byte_18B20(id_addr[i]);
}
//发读温度命令
write_byte_18B20(0xbe);
//读2字节温度值
value = (unsigned int)read_byte_18B20();
value += ((unsigned int)(read_byte_18B20()))<<8;
return(value);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -