⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds18b20_driver.c

📁 一个DS18B20的库文件
💻 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 + -