OneWire Bus Digital Thermometer Example 1252020 1 Maxim
One-Wire Bus Digital Thermometer Example 12/5/2020 1
Maxim DS 1822 1 -Wire Temperature Sensor 12/5/2020 2
12/5/2020 3
12/5/2020 4
12/5/2020 5
12/5/2020 6
12/5/2020 7
12/5/2020 8
12/5/2020 9
12/5/2020 10
12/5/2020 11
12/5/2020 12
12/5/2020 13
C Program that implements Digital Thermometer using DS 18 S 20 1 -Wire Bus Sensor 12/5/2020 14
#include <hidef. h> /* common defines and macros */ #include <mc 9 s 12 c 128. h> /* derivative information */ #include "lcd_subroutines. h" #pragma LINK_INFO DERIVATIVE "mc 9 s 12 c 128" //DS 18 S 20 (Dallas Semiconductor 1 -wire Bus Temperature Sensor) //Pins Used: LCD Panel PTT 7: 2, Temp Sensor: PTM 0. //This example works for any LCD Module made by Optrex, Hitachi, etc. //This example is based on information in the DS 18 S 20 datasheet //and Dallas Semiconductor App Note #162 "Interfacing the DS 18 x 20 1 -wire temp //sensor in a microcontroller environment" //Chip Type: 9 S 12 C 128 //Bus Clock Frequency: 24 MHz //Written by KEH 12/5/2020 15
#define DQ PTM_PTM 3 //Use PTM 3 as the one-wire bus line, define it as "DQ" #define DQDDR DDRM_DDRM 3 //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 float. // (The DQ line is quickly pulled high through a // 4. 7 kohm pullup resistor. ) // But if DQDDR = 1, => DQ line is quickly pulled LOW. void INIT_PLL(void); unsigned char one_wire_reset(void); void delay 6 us(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; 12/5/2020 16
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(0 xcc); //skip ROM Command //(Only allowed when there is only 1 device on bus) write_byte_one_wire(0 x 44); //Start Conversion delay 6 us(18); while(one_wire_reset()); //Hang here if 1 -wire sensor not present write_byte_one_wire(0 xcc); //Skip ROM Command write_byte_one_wire(0 x. BE); //Read Scratch Pad inside Temp Sensor lsbtemp = read_byte_one_wire(); //First two bytes from scratchpad //hold Centigrade Temp. msbtemp = read_byte_one_wire(); 12/5/2020 17
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 { //(this fractional part is either 0. 5 deg C or 0. 0 deg C. ) fractchar = '0'; } temp = temp>>1; //Now the integer in "temp" is the Centigrade degrees lschar = temp%10 + 0 x 30; //Decompose "temp" into three decimal ASCII digits temp = temp/10; middlechar = temp%10 + 0 x 30; temp = temp/10; mschar = temp%10 + 0 x 30; 12/5/2020 18
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) delay 6 us(30000); //Wait about 0. 2 seconds between temperature samples } } 12/5/2020 19
void delay 6 us(unsigned int nr 6 us) //Wait for nr of 6 us intervals in argument { unsigned int i, j; for (i = 0; i < nr 6 us; i++) { for(j=0; j<22; j++); } } 12/5/2020 20
unsigned char one_wire_reset(void) { //Begin each transfer sequence with // one_wire_reset by calling this rtn. unsigned char presence; DQ = 0; DQDDR = 1; //Pull DQ line low delay 6 us(80); //Wait for 480 US DQDDR = 0; //Allow DQ to be pulled high delay 6 us(12); //Wait for 70 US presence = DQ; //Read state of DQ //(hopefully presence pulse being sent by temp sensor!) delay 6 us(68); //Wait 410 US for presence pulse to finish. return(presence); } 12/5/2020 21
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. delay 6 us(2); //delay 12 us from start of timeslot i = DQ; return(i); //return value of DQ line (as set by temp sens) } 12/5/2020 22
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 delay 6 us(18); //delay 108 us DQDDR = 0; //Let DQ line go high to end cycle } 12/5/2020 23
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; //Read byte in one bit at a time delay 6 us(18); //Wait for rest of timeslot } return(value); } 12/5/2020 24
void write_byte_one_wire(char val) { unsigned char i; unsigned char temp; //Write a byte to the 1 -wire device for(i=0; i<8; i++) //Write byte, one bit at a time { temp = val>>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 } delay 6 us(18); } 12/5/2020 25
How a single bit of an 8 -bit port may be accessed (read or written) in C • Let us focus on PTM 0, as an example • Then “PTM_PTM 0 = 1; ” will set just bit #0 of Port M, or “while(PTM_PTM 0); ” will hang up until bit #0 of Port M goes low. • Look at the MC 9 S 12 C 128. h header file (under Libraries in the Project View). • Note the following excerpts from this file: 12/5/2020 26
At very top of this header file……. . /* Types definition */ typedef unsigned char byte; typedef unsigned int word; typedef unsigned long dlong[2]; #define REG_BASE 0 x 0000 */ 12/5/2020 /* Base address for the I/O register block 27
/*** PTM - Port M I/O Register; 0 x 00000250 ***/ typedef union { byte Byte; struct { byte PTM 0 : 1; /* Port M Bit 0 */ byte PTM 1 : 1; /* Port M Bit 1 */ byte PTM 2 : 1; /* Port M Bit 2 */ byte PTM 3 : 1; /* Port M Bit 3 */ byte PTM 4 : 1; /* Port M Bit 4 */ byte PTM 5 : 1; /* Port M Bit 5 */ byte : 1; } Bits; struct { byte grp. PTM : 6; byte : 1; } Merged. Bits; } PTMSTR; 12/5/2020 28
extern volatile PTMSTR _PTM @(REG_BASE + 0 x 00000250); #define PTM _PTM. Byte #define PTM_PTM 0 _PTM. Bits. PTM 0 #define PTM_PTM 1 _PTM. Bits. PTM 1 #define PTM_PTM 2 _PTM. Bits. PTM 2 #define PTM_PTM 3 _PTM. Bits. PTM 3 #define PTM_PTM 4 _PTM. Bits. PTM 4 #define PTM_PTM 5 _PTM. Bits. PTM 5 #define PTM_PTM. Merged. Bits. grp. PTM 12/5/2020 29
- Slides: 29