ATmega16L学习板18B20测试程序

 ATmega16L学习板18B20测试程序
   晶振频率: 8MHz
   编译:  ICCAVR 6.31
   编写:  hanzhaowei@2911.net
********************************************************************/

#include <iom16v.h>
#include <macros.h>
#include "../include/board.h"

/*===================================================================
// 函数功能: DS18B20数据校验函数
// 形参:  void
// 返回:  unsigned char 校验结果
// 编写:  2004/8/25
// 备注:  CRC公式为:CRC = X^8 + X^5 + X^4 + 1
===================================================================*/
unsigned char crccheck(unsigned char *p,unsigned char len)
{
 unsigned char bit0,cbit,r,temp,i,j,byte;
 temp = 0;
 for(j = 0; j < len; j++)
 {
  byte = p[j];
  for(i = 0; i < 8; i++)
  {
          cbit = temp & 0x01;
          bit0 = byte&0x01;
          temp >>=   1;
          r = cbit ^ bit0;
          if(r == 1)
           temp ^= 0x8c;
          byte >>= 1;
         }
     }
 return temp; 
}

/*===================================================================
// 函数功能: us延时函数
// 形参:  void
// 返回:  void
// 编写:  2004/8/25
===================================================================*/
void delay_us(unsigned int time)
{    
 do
 {
  time--;
 } 
 while (time>1);
}

/*===================================================================
// 函数功能: 判断总线应答
// 形参:  void
// 返回:  unsigned char true为应答
// 编写:  2004/8/25
===================================================================*/
unsigned char ds1820_ack(void)
{
 unsigned char ack;
 DDRC |= DQ;
 PORTC &= ~DQ;
 delay_us(500);       // reset
 PORTC |= DQ;
 DDRC &= ~DQ;
 delay_us(45);
 ack = DQ & PINC;
 delay_us(500);       // host receive
 if(ack)
  return true;
 else
  return false;
}

/*===================================================================
// 函数功能: 从 1-wire 总线上读取一个字节
// 形参:  void
// 返回:  unsigned char 读到的值
// 编写:  2004/8/25
===================================================================*/
unsigned char read_byte(void)
{
 unsigned char i;
 unsigned char value = 0;
 for(i = 8; i > 0; i--)
 {
  value >>= 1;      // low bit first
  DDRC |= DQ;
  PORTC &= ~DQ;      // pull DQ low to start timeslot
  delay_us(3);
  PORTC |= DQ;
  DDRC &= ~DQ;      // release bus
  delay_us(10);
  if(DQ & PINC)
   value|=0x80;
  delay_us(100);
  DDRC |= DQ;
  delay_us(5);      // time interval
 }
 return(value);
}

/*===================================================================
// 函数功能: 向 1-WIRE 总线上写一个字节
// 形参:  value  写到总线上的值
// 返回:  void
// 编写:  2004/8/25
===================================================================*/
void write_byte(unsigned char value)
{
 unsigned char i;
 DDRC |= DQ;
 for(i = 8; i > 0; i--)
 {
  if(value & 0x01)
  {
   PORTC &= ~DQ;     // pull DQ low to start timeslot
   delay_us(10);
   PORTC |= DQ;
   delay_us(100);
  }
  else
  {
   PORTC &= ~DQ;     // pull DQ low to start timeslot
   delay_us(100);
   PORTC |= DQ;
   delay_us(10);
  }
  value >>= 1;
 }
}

/*===================================================================
// 函数功能: 读取温度
// 形参:  *temperature 温度存储空间
// 返回:  unsigned char true为有效
// 编写:  2004/8/25
===================================================================*/
unsigned char Read_Temperature(unsigned int *temperature)
{
 unsigned char i;
 union{
  unsigned char c[2];
  unsigned int x;
 }temp;
 unsigned char temporary[9];

 ds1820_ack();
 write_byte(0xCC);      // Skip ROM
 write_byte(0x44);      // Start Conversion
 for(i = 0; i < 16; i++)
  delay_us(50000);
 ds1820_ack();
 write_byte(0xCC);      // Skip ROM
 write_byte(0xBE);      // Read Scratch Pad
 for(i = 0; i < 9; i++)
  temporary[i] = read_byte();
 temp.c[0] = temporary[0];
 temp.c[1] = temporary[1];
 
 if(crccheck(temporary,9))
  return false;
 else
 { 
  *temperature = temp.x;
  return true;
 }
}

/*===================================================================
// 函数功能: 读取Rom Code
// 形参:  *temp  DS18B20的Rom Code存储空间
// 返回:  unsigned char true为有效
// 编写:  2004/8/25
===================================================================*/
unsigned char Read_RomCode(unsigned char *temp)
{
 ds1820_ack();
 write_byte(0x33);
 temp[0] = read_byte();
 temp[1] = read_byte();
 temp[2] = read_byte();
 temp[3] = read_byte();
 temp[4] = read_byte();
 temp[5] = read_byte();
 temp[6] = read_byte();
 temp[7] = read_byte();
 if(crccheck(temp,8))
  return false;
 else
  return true;
}

/*===================================================================
// 函数功能: 匹配DS18B20
// 形参:  *p DS18B20的Rom Code
// 返回:  void
// 编写:  2004/8/25
===================================================================*/
void ds1820_match(unsigned char *p)
{
 unsigned char i;
 ds1820_ack();
 write_byte(0x55); 
 for(i=0;i<8;i++)
  write_byte(p[i]);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值