?? ds182x.c
字號:
/*************************************************************************\
* Development board - DS182X 1-Wire Digital Thermometer *
*-------------------------------------------------------------------------*
* Description : The DS1822 digital thermometer provides 9- to 12-bit *
* centigrade temperature measurements and has an alarm *
* function with NV user-programmable upper and lower trigger*
* points. The DS1822 communicates over a 1-Wire bus that by *
* definition requires only one data line (and ground) for *
* communication with a central microprocessor. *
* *
* It has an operating temperature range of -55癈 to +125癈 *
* and is accurate to +-2.0癈 over the range of -10癈 to *
* +85癈. In addition, the DS1822 can derive power directly *
* from the data line ("parasite power"), eliminating the *
* need for an external power supply. *
*-------------------------------------------------------------------------*
* Author(s) : CEBA & www.DFSOFT.cz & www.HW.cz *
* Developed : xx.03.2003 Last Update : 07.11.2003 *
* Version : 1.1.0 *
*-------------------------------------------------------------------------*
* Compiler : AVR-GCC Version : 3.3 *
* Source file : ds182x.c *
* Licence : www.HW.cz - GNU GPL *
*-------------------------------------------------------------------------*
* Target system : Charon II. - ATmega128, Quartz 14.7456 MHz *
* UART - 19200,N,8,1 *
* DS1822 1-Wire Digital Thermometer *
* *
* Pin assignment: *
* Thermometer DS1822 Charon II. - dev. board *
* 1 GND GND *
* 2 DQ Data In/Out PD0 *
* 3 Vcc Vcc *
*-------------------------------------------------------------------------*
* History : *
* 07.11.03 - added support for DS18B20 devices - CEBA *
* 06.11.03 - added support for DS1820, fixed bug with sign bit - CEBA *
* 27.04.03 - source code ported from x51 platform by - CEBA *
* *
* FIXME : *
* - test DS1822 timing with scope *
\*************************************************************************/
#ifndef _DEV_BOARD_DS182X_C
#define _DEV_BOARD_DS182X_C
#include "ds182x.h"
/* forward definitions of local functions */
static void TM_Write_byte(u_char);
static u_char TM_Read_byte(void);
static void TM_Write_bit(u_char);
static u_char TM_Read_bit(void);
static u_char TM_Reset(void);
#if DS_DEBUG
static void hex_dump (u_char *buf, u_int length);
#endif
#define TM_Enter_Critical() NutEnterCritical() /* disable all interrupts */
#define TM_Exit_Critical() NutExitCritical() /* reenable interrupts */
#include <util/delay.h>
u_char tm_romdta[8*MAX_CHIP]; /* storage to hold memory pattern */
u_char tm_lst0; /* last detected zero bit */
/*
* TM_Convert_temperature()
*
* This function converts value from raw into an integer data format.
* Conversion is chosen based on an 8-bit family code.
*
* Assume: 0x10 - DS1820,
* 0x10 - DS18S20 - software compatible with the DS1820.
* 0x22 - DS1822
* 0x28 - DS18B20 - software compatible with the DS1822.
*/
void TM_Convert_temperature(u_char idx, u_int *temp, u_int *frac)
{
switch(tm_romdta[8*idx])
{ case 0x10: if(*temp & 0x01) *frac = 5000; /* 4 decimal char. precision */
else *frac = 0;
*temp >>= 1;
break;
case 0x22:
case 0x28: *frac = ((*temp & (1 << 3)) ? 10000/(1 << 1) : 0) +
((*temp & (1 << 2)) ? 10000/(1 << 2) : 0) +
((*temp & (1 << 1)) ? 10000/(1 << 3) : 0) +
((*temp & (1 << 0)) ? 10000/(1 << 4) : 0);
*temp >>= 4;
break;
default:
#if DS_DEBUG
printf_P(PSTR("\n\rUnknown family code - %02X.\n\r"), tm_romdta[8*idx]);
#endif
*temp = 85;
*frac = 0;
break;
}
if(*temp & 0x80) /* check the sign bit */
{ *temp &= 0x007F; /* clear sign bits */
*temp |= 0x8000; /* set sign bit */
}
}
/*
* TM_Read_temperature()
*
* This function expects a previous call to TM_Search_rom() which
* fills an array of ROM patterns of found devices.
*
* Arguments:
* idx is index to this array.
*
* Returns:
* 0xFFFF (-1) Device not present
* 0x8000 Error during read (improper CRC)
* > 0 Temperature value
*/
u_int TM_Read_temperature(u_char idx)
{
u_char cnt;
u_char crc;
u_int temper;
u_char temp_buf[9];
#define crc_read ((u_char)temp_buf[8]) /* last byte is CRC */
#if (DS_DEBUG && MULTI_DEVICE) || MULTI_DEVICE
u_char *ptr_tmp = &tm_romdta[8*idx];
#endif
/*
if (*ptr_tmp != 0x22)
return -2; // other device type
*/
#if DS_DEBUG && MULTI_DEVICE
hex_dump((char *)ptr_tmp, 8);
#endif
TM_Enter_Critical(); /* disable interrupts */
/* Read previously sampled value ("packet" which last byte is CRC of previous) */
if (TM_Reset())
{ TM_Exit_Critical(); /* reenable interrupts */
return -1; /* device not present (e.g. unplugged) */
}
#if !MULTI_DEVICE
TM_Write_byte(0xCC); /* skip ROM */
#else
TM_Write_byte(0x55); /* match ROM */
cnt = 8;
do
TM_Write_byte(*ptr_tmp++);
while (--cnt);
#endif
TM_Write_byte(0xBE); /* read Scratch Pad */
for(cnt=0; cnt <= 8; cnt++) temp_buf[cnt] = TM_Read_byte();
TM_Exit_Critical(); /* reenable interrupts */
/* check if read byte stream has correct CRC */
crc = 0;
for(cnt=0; cnt<sizeof(temp_buf); cnt++) crc = TM_Crc(crc, temp_buf[cnt]);
#if DS_DEBUG
hex_dump((char *)&temp_buf, sizeof(temp_buf));
#endif
temper = ((temp_buf[1] & 0x0F) << 8) | temp_buf[0];
if (crc)
{
temper |= 0x8000; /* return error (conversion can be pending) */
#if DS_DEBUG
printf_P(PSTR("\n\rTM_read - err:%X(%X!=%X) "), temper, crc, crc_read);
#endif
}
return temper;
}
/*
* TM_Sample_temperature()
*
* This function initiates temperature conversion.
*
* Arguments:
* idx == 0xFF skip ROM and initiate conversion on all devices
*/
void TM_Sample_temperature(u_char idx)
{
u_char *ptr_tmp = &tm_romdta[8*idx];
u_char cnt;
/* Issue command to sample temperature to be prepared for next read */
TM_Enter_Critical(); /* disable interrupts */
TM_Reset();
if (idx == 0xFF)
TM_Write_byte(0xCC); /* skip ROM */
else
{
TM_Write_byte(0x55); /* match ROM */
cnt = 8;
do
TM_Write_byte(*ptr_tmp++);
while (--cnt);
}
TM_Write_byte(0x44); /* start conversion */
TM_Exit_Critical(); /* reenable interrupts */
}
#if !MULTI_DEVICE
/*
* TM_Read_rom()
*
* If there is a single device on a 1-wire bus
* its ROM code can be read by this function.
*
* If more devices are present logical AND of their ROM will be read.
*
* Currently not used. Will be removed from link automatically.
*/
u_char TM_Read_rom(u_char *ptr)
{
u_char stat = 0,
cnt = 8,
crc = 0,
*fam_ptr = ptr;
#if DS_DEBUG
printf_P(PSTR("\n\rReading ROM Code\n\r"));
#endif
TM_Enter_Critical(); /* disable interrupts */
if (!TM_Reset())
{
TM_Write_byte(0x33);
do
*ptr++ = TM_Read_byte(); /* read ROM code */
while(--cnt);
TM_Exit_Critical(); /* reenable interrupts */
cnt = 8;
ptr = fam_ptr;
do
crc = TM_Crc(crc, *ptr++); /* calculate CRC */
while(--cnt);
if ( !crc && *fam_ptr != 0)
stat = 1; /* reading successfully finished */
}
else TM_Exit_Critical(); /* reenable interrupts */
return stat;
}
#endif
/*
* TM_Search_rom()
*
* This function scans all devices up to MAX_CHIP on 1-wire "network".
* It fills passed array with ROM patterns of found devices.
* This array is supposed to be used with TM_Read_temperature().
*/
u_char TM_Search_rom(u_char *ptr)
{
u_char tm_cnt, /* number of found devices (thermometers) */
st;
u_char cnt = MAX_SEARCH;
memset(ptr, (u_char)0, 8 * MAX_CHIP);
tm_lst0 = 0;
tm_cnt = 0;
do
{
st = TM_Search_next(ptr);
#if DS_DEBUG
printf_P(PSTR("st:%u "), st);
#endif
if (st)
{
tm_cnt++;
if ((st == 1) && (tm_cnt < MAX_CHIP))
{
memcpy(ptr + 8, ptr, 8);
ptr += 8;
}
}
else
{
/* if 1-wire bus is empty no device responds, this prevents endless loop */
if (!--cnt)
break;
}
} while ((st != 2) && (tm_cnt < MAX_CHIP));
return (tm_cnt | ((st != 2) ? 0x80 : 0));
}
/*
* TM_Search_next()
*
* Search for a single device.
*/
u_char TM_Search_next(u_char *ptr)
{
u_char i = 0, x = 0, lst_dif = tm_lst0;
u_char mask = 0x01;
u_char tm_rombit;
TM_Enter_Critical(); /* disable interrupts */
if (!TM_Reset())
TM_Write_byte(0xF0);
else
{ TM_Exit_Critical(); /* reenable interrupts */
return 0;
}
ptr--; /* adjust pointer to satisfy algorithm within loop below */
while ((i++ < 64) && (x < 3)) /* 8 bytes */
{
if (!((i-1) % 8))
{
mask = 0x01; /* mask within a byte */
ptr++; /* skip to next byte if 8 bits passed */
}
else
mask <<= 1; /* next bit */
x = ((u_char)TM_Read_bit()) << 1;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -