C语言程序>>DS18B20

 

/*
 * 功能描述:DS18B20(单个)驱动程序
 *    温度精度:正温度,1位小数,无校验
 *     EEPROM 0:温度LSB 1:温度MSB 2:TH 3:TL 4:精度寄存器(9~12)8:CRC
 *     采用默认值:转换精度默认为12 位,而分辨率是0.625
 *    DS18B20 复位-->执行ROM 指令-->执行DS18B20 功能指令。
 * 硬件平台:ATmega128a 外部晶振:7372800
 * 编译环境:WinAVR2011 + AVR Studio4.18
 * 作    者:蔡亚辉
 * 编写时间:2011-08-03
 * 修改记录:
 * 版    本:V1.0
 */

#ifndef __DS18B20_H__
#define __DS18B20_H__

#define DS18B20_DQ    PA0

#define DS18B20_DDR    DDRA
#define DS18B20_PORT   PORTA
#define DS18B20_PIN    PINA

/* 外部调用函数 */
extern unsigned char ds18b20_read_temprature(unsigned int *p_data);

#endif

/*
 * 功能描述:DS18B20(单个)驱动程序
 *    温度精度:正温度,1位小数,无校验
 *     EEPROM 0:温度LSB 1:温度MSB 2:TH 3:TL 4:精度寄存器(9~12)8:CRC
 *     采用默认值:转换精度默认为12 位,而分辨率是0.625
 *    DS18B20 复位-->执行ROM 指令-->执行DS18B20 功能指令。
 * 硬件平台:ATmega128a 外部晶振:7372800
 * 编译环境:WinAVR2011 + AVR Studio4.18
 * 作    者:蔡亚辉
 * 编写时间:2011-08-03
 * 修改记录:
 * 版    本:V1.0
 */

#include <avr/io.h>
#include <util/delay.h>
#include "ds18b20.h"

#define ds18b20_dq_ddr_in()  DS18B20_DDR &= ~(1<<DS18B20_DQ)
#define ds18b20_dq_ddr_out() DS18B20_DDR |= (1<<DS18B20_DQ)

#define ds18b20_dq_set()  DS18B20_PORT |= (1<<DS18B20_DQ)
#define ds18b20_dq_cle()  DS18B20_PORT &= ~(1<<DS18B20_DQ)
#define ds18b20_dq_get()  DS18B20_PIN & (1<<DS18B20_DQ)

/* DS18B20 ROM指令 */
#define ds18b20_read_rom()     ds18b20_write_byte(0x33)   /* 读取ROM */
#define ds18b20_match_rom()    ds18b20_write_byte(0x55)   /* 匹配ROM */
#define ds18b20_skip_rom()   ds18b20_write_byte(0xcc)    /* 跳过ROM */
#define ds18b20_search_rom()   ds18b20_write_byte(0xf0)   /* 搜索ROM */
#define ds18b20_alarm_rom()    ds18b20_write_byte(0xec)   /* 报警搜索 */

/* DS18B20 暂存器指令 */
#define ds18b20_write_scratchpad()    ds18b20_write_byte(0x4e)  /* 写暂存器 */
#define ds18b20_read_scratchpad()     ds18b20_write_byte(0xbe)  /* 读暂存器 */
#define ds18b20_copy_scratchpad()     ds18b20_write_byte(0x48)  /* 拷贝暂存器 */
#define ds18b20_convert_t()           ds18b20_write_byte(0x44)  /* 启动温度转换 */
#define ds18b20_recall_e2()           ds18b20_write_byte(0xb8)  /* 重读E2 */
#define ds18b20_read_power_supply()   ds18b20_write_byte(0xb4)  /* 读取供电方式 */

/* ds18b20初始化 0:复位成功 1:复位失败*/
static unsigned char ds18b20_reset(void)
{
 unsigned char read_data = 0;

 /* 控制器产生复位信号 */
 ds18b20_dq_ddr_out();
 ds18b20_dq_cle();
 _delay_us(500);     /* 480us~960us */
 ds18b20_dq_set();
 ds18b20_dq_ddr_in();
 _delay_us(80);       /* 15~60us  */    
 
 /* ds18b20产生存在信号 0:复位成功 1:复位失败 */  
 read_data = ds18b20_dq_get();
 _delay_us(500);      

   ds18b20_dq_ddr_out();
 ds18b20_dq_set();

 return(read_data);
}

/* ds18b20读一字节 */
static unsigned char ds18b20_read_byte(void)
{
 unsigned char i = 0;
 unsigned char read_data = 0;

 for (i = 0;i < 8;i++)   /* LSB -> MSB */
 {
  read_data >>= 1;

  ds18b20_dq_ddr_out();
  ds18b20_dq_set();
  _delay_us(1);    /* 两次读时间片间隔大于1us */ 
  ds18b20_dq_cle();   /* 开始一个读时间片 */
  _delay_us(4);
  ds18b20_dq_set();
  ds18b20_dq_ddr_in();
  _delay_us(10);    /* 读时间片开始后15us内主机对数据线进行采样 */

  if(ds18b20_dq_get())
  {
   read_data |= 0x80;
  }

  _delay_us(60);    /* 60us~120us */   
 }

 return (read_data);
}

/* ds18b20写一字节 */
static void ds18b20_write_byte(unsigned char data) 
{    
 unsigned char i = 0;

 for (i = 0;i < 8;i++)   /* LSB -> MSB */
 {
  ds18b20_dq_ddr_out();
  ds18b20_dq_set();
  _delay_us(1);    /* 两次写时间片间隔大于1us */
  ds18b20_dq_cle();
  _delay_us(4); 

  if (data&0x01)     
  {
   ds18b20_dq_set();
  }
  else
  {
   ds18b20_dq_cle();
  }

  _delay_us(80);    /* 60us~120us */
  ds18b20_dq_set();
  data >>= 1;
 } 
}

/* ds18b20启动转换 */ 
static unsigned char ds18b20_start(void)
{
 if (ds18b20_reset()) return 1; /* ds18b20初始化 0:复位成功 1:复位失败*/

 ds18b20_skip_rom();    /* ds18b20跳过地ROM */
  ds18b20_convert_t();    /* ds18b20启动转换 */
 _delay_us(5);

 return 0;
}

/* ds18b20读取温度值 0 成功 1失败 */
unsigned char ds18b20_read_data(unsigned int *p_data)
{
 unsigned char temp_l = 0;
 unsigned char temp_h = 0;   
 unsigned int temp = 0;

 if (ds18b20_start()) return 1; /* ds18b20启动转换 */
 if (ds18b20_reset()) return 1; /* ds18b20初始化 0:复位成功 1:复位失败*/
   
  ds18b20_skip_rom();    /* ds18b20跳过地址 */
  ds18b20_read_scratchpad();   /* ds18b20读取温度寄存器 */
 temp_l = ds18b20_read_byte(); /* 温度低位 */
 temp_h = ds18b20_read_byte(); /* 温度高位 */ 
 if (ds18b20_reset()) return 1; /* ds18b20初始化 0:复位成功 1:复位失败*/

 temp = temp_h;
 temp <<= 8;
 temp |= temp_l;

 temp = temp*0.625;

 if ((temp_h&0x80) == 0x80) return 1;/* 不检测负温度 */

 *p_data = temp;
 return 0;
}

/* ds18b20读取温度值*/
unsigned char ds18b20_read_temprature(unsigned int *p_data)
{
 unsigned int temp = 0;

 if (!ds18b20_read_data(&temp))
 {
  *p_data = temp;
  return 0;
 }
 else
 {
  return 1;
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值