#include /* common defines and macros */ #include /* derivative information */ #include "lcd_subroutines.h" #pragma LINK_INFO DERIVATIVE "mc9s12c128" //DS18S20 (Dallas Semiconductor 1-wire Bus Temperature Sensor) Interfacing Example //9S12C332 pins used: LCD Display: PTT7:2, Temp Sensor: PTM0. //This example works for any LCD Module made by Optrex, Hitachi, etc. //This example is based on information in the DS18S20 datasheet //and Dallas Semiconductor App Note #162 "Interfacing the DS18x20 1-wire temp //sensor in a microcontroller environment" //Chip Type: 9S12C128 //Bus Clock Frequency: 24 MHz //Written by KEH on 10/28/2007 #define DQ PTM_PTM3 //Use PTM3 as the one-wire bus line, define it as "DQ" #define DQDDR DDRM_DDRM3 //Define "DQDDR" as DDRM bit #3, which controls state of DQ. //Throughout this program, we shall keep DQ set to 0, // and thus if DQDDR = 0 => DQ line floats // (The DQ line is quickly pulled high through a 4.7kohm pullup resistor.) // But if DQDDR = 1, => DQ line is quickly pulled LOW. void INIT_PLL(void); unsigned char one_wire_reset(void); void delay6us(unsigned int); void write_byte_one_wire(char); unsigned char read_byte_one_wire(void); void write_bit_one_wire(char); unsigned char read_bit_one_wire(void); char lschar,middlechar,mschar,fractchar; int temp; char scratchdat[10],msbtemp,lsbtemp; void main(void) { unsigned char j; INIT_PLL(); LCD_INIT(); for(;;) { DQDDR = 0; //DQ is pulled high through 4.7 kilohm external pullup resistor. while(one_wire_reset()); //Hang here if 1-wire sensor not present write_byte_one_wire(0xcc); //skip ROM Command //(Only allowed when there is only 1 device on bus) write_byte_one_wire(0x44); //Start Conversion delay6us(18); while(one_wire_reset()); //Hang here if 1-wire sensor not present write_byte_one_wire(0xcc); //Skip ROM Command write_byte_one_wire(0xBE); //Read Scratch Pad inside Temp Sensor lsbtemp = read_byte_one_wire(); //First two bytes from scratchpad hold Centigrade Temp. msbtemp = read_byte_one_wire(); for(j=0;j<7;j++) //Read the rest of the scratchpad, even though we scratchdat[j] = read_byte_one_wire(); //will do nothing with it. temp = lsbtemp + (msbtemp<<8); //Variable "temp" holds temperature in 0.5 deg C units if (temp & 1 == 1) { fractchar = '5'; } //Look at LSB of "temp" to determine fractional part else { //(either 0.5 deg C or 0.0 deg C.) fractchar = '0'; } temp = temp>>1; //Now integer in "temp" is in degrees C lschar = temp%10 + 0x30; //Decompose "temp" into three decimal ASCII digits temp = temp/10; middlechar = temp%10 + 0x30; temp = temp/10; mschar = temp%10 + 0x30; LCD_ADDRESS(0); //Home the LCD panel display. LCD_DTA(mschar); //Display integer part of temp LCD_DTA(middlechar); LCD_DTA(lschar); LCD_DTA('.'); //Insert decimal point LCD_DTA(fractchar); //Display fractional part (0.0 or 0.5 deg C) delay6us(30000); //Wait about 0.2 seconds between temperature samples } } void delay6us(unsigned int nr6us) //Wait for nr of 6us intervals in argument { unsigned int i,j; for (i = 0; i < nr6us; i++) { for(j=0;j<22;j++); } } unsigned char one_wire_reset(void) //Begin each transfer sequence with one_wire_reset { unsigned char presence; DQ = 0; DQDDR = 1; //Pull DQ line low delay6us(80); //Wait for 480 US DQDDR = 0; //Allow DQ to be pulled high delay6us(12); //Wait for 70 US presence = DQ; //Read state of DQ //(hopefully presence pulse being sent by temp sensor!) delay6us(68); //Wait 410 US for presence pulse to finish. return(presence); } unsigned char read_bit_one_wire(void) //Read one bit { unsigned char i; DQ = 0; DQDDR = 1; //Pull DQ low to start timeslot DQDDR = 0; //Then let DQ line be pulled high. delay6us(2); //delay 15 us from start of timeslot i = DQ; return(i); //return value of DQ line (as set by temp sens) } void write_bit_one_wire(char bitval) //Write one bit { DQ = 0; DQDDR = 1; //Pull DQ low to start timeslot if(bitval == 1) DQDDR = 0; //Let DQ go high to write a 1 delay6us(18); //delay 108 us DQDDR = 0; //Let DQ line go high to end cycle } unsigned char read_byte_one_wire(void) //Read a byte from 1-wire device { unsigned char i; unsigned char value = 0; for(i=0;i<8;i++) { if(read_bit_one_wire()) value=value | 1<>i; //Shift ith bit into LSB position temp = temp & 1; //Mask out LSB bit value write_bit_one_wire(temp); //Write it to temp sensor } delay6us(18); }