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

📄 ds182x.c

📁 ds18b20 thermometer with lcd, ds18b20 thermometer with lcd, ds18b20 thermometer with lcd
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************\
*           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 + -