/********************************************************************\ Name: DS28EA00.c Created by: Stefan Ritt Contents: Driver for DS28EA00 1-wire temperature sensor \********************************************************************/ #include #include #include #include #include #include "mscbemb.h" #include "DS28EA00.h" #include "fe_cc.h" /* DS28EA00 command codes */ #define CMD_WRITE_SCRATCHPAD 0x4E #define CMD_READ_SCRATCHPAD 0xBE #define CMD_COPY_SCRATCHPAD 0x48 #define CMD_CONVERT_TEMP 0x44 #define CMD_READ_POWER_MODE 0xB4 #define CMD_RECALL_EEPROM 0xB8 #define CMD_PIO_ACCESS_READ 0xF5 #define CMD_PIO_ACCESS_WRITE 0xA5 #define CMD_CHAIN 0x99 #define CMD_CHAIN_OFF 0x3C #define CMD_CHAIN_OFF_INV 0xC3 #define CMD_CHAIN_ON 0x5A #define CMD_CHAIN_ON_INV 0xA5 #define CMD_CHAIN_DONE 0x96 #define CMD_CHAIN_DONE_INV 0x69 #define CMD_READ_ROM 0x33 #define CMD_MATCH_ROM 0x55 #define CMD_SEARCH_ROM 0xF0 #define CMD_COND_SEARCH_ROM 0xEC #define CMD_COND_READ_ROM 0x0F #define CMD_SKIP_ROM 0xCC #define CMD_OVERDRIVE_SKIP_ROM 0x3C #define CMD_OVERDRIVE_MATCH_ROM 0x69 // port pins sbit DS28EA00_OUT = P5 ^ 6; sbit DS28EA00_IN = P5 ^ 5; // inverted output #define DS28EA00_HIGH 0 #define DS28EA00_LOW 1 // ROM address list in user_data extern USER_DATA user_data; // number of devices static unsigned char n_dev; extern unsigned char get_n_interrupt(); /*------------------------------------------------------------------*/ unsigned char DS28EA00_reset() { unsigned char i; SFRPAGE = CONFIG_PAGE; // reset pulse 500 us DS28EA00_OUT = DS28EA00_LOW; delay_us(600); // tRSTL DS28EA00_OUT = DS28EA00_HIGH; // wait for presence pulse delay_us(75); // tMSP // chip present if line low i = (DS28EA00_IN == 0); delay_us(500); // tRSTH // set high DS28EA00_OUT = DS28EA00_HIGH; return i; } /*------------------------------------------------------------------*/ void DS28EA00_write_bit(unsigned char b) { // set high DS28EA00_OUT = DS28EA00_HIGH; // set low DS28EA00_OUT = DS28EA00_LOW; if (b) { DELAY_US(15); // tW1L } else { DELAY_US(105); // tW0L } // set high DS28EA00_OUT = DS28EA00_HIGH; if (b) { DELAY_US(105); // tSLOT(120us) - tW1L } else { DELAY_US(15); // tSLOT(120us) - tW0L } } /*------------------------------------------------------------------*/ void DS28EA00_write_byte(unsigned char byte) { unsigned char i; for (i=0 ; i<8 ; i++) DS28EA00_write_bit((byte & (1< 0); } /*------------------------------------------------------------------*/ unsigned char DS28EA00_read_bit() { unsigned char b; DS28EA00_OUT = DS28EA00_HIGH; DS28EA00_OUT = DS28EA00_LOW; DELAY_US(10); // tRL // release line DS28EA00_OUT = DS28EA00_HIGH; DELAY_US(10); // tMSR - tRL b = DS28EA00_IN; DELAY_US(80); // tSLOT - tMSR return b; } /*------------------------------------------------------------------*/ unsigned char DS28EA00_read_byte() { unsigned char i, d; for (i=d=0 ; i<8 ; i++) d = d | (DS28EA00_read_bit() ? (1< 0; } /*------------------------------------------------------------------*/ void DS28EA00_read(float *ptemp) { unsigned char i, d, dev; unsigned char byte1, byte2, n_interrupt; float t; // read each device sequentially for (dev=0 ; dev<16 ; dev++) { // skip empty slots if (user_data.ow_adr[dev][0] == 0) { ptemp[dev] = -999; continue; } watchdog_refresh(0); d = DS28EA00_reset(); if (!d) { // no devices on bus -> return -999 ptemp[dev] = -999; continue; } n_interrupt = get_n_interrupt(); DS28EA00_write_byte(CMD_MATCH_ROM); for (i=0 ; i<8 ; i++) DS28EA00_write_byte(user_data.ow_adr[dev][i]); DS28EA00_write_byte(CMD_READ_SCRATCHPAD); byte1 = DS28EA00_read_byte(); byte2 = DS28EA00_read_byte(); // result is only valid if we did not get interrupted if (get_n_interrupt() == n_interrupt) { t = (float) ((short)(byte1 | (byte2 << 8))) * 85 / 0x550; ptemp[dev] = floor(t * 10.0 + 0.5) / 10.0; } } // start new conversion watchdog_refresh(0); DS28EA00_reset(); DISABLE_INTERRUPTS; DS28EA00_write_byte(CMD_SKIP_ROM); DS28EA00_write_byte(CMD_CONVERT_TEMP); ENABLE_INTERRUPTS; watchdog_refresh(0); }