Date post: | 20-Dec-2015 |
Category: |
Documents |
View: | 218 times |
Download: | 0 times |
04/18/23 1
One-Wire Bus
Digital Thermometer Example
04/18/23 2
Maxim DS1822 1-Wire Temperature Sensor
04/18/23 3
04/18/23 4
04/18/23 5
04/18/23 6
04/18/23 7
04/18/23 8
04/18/23 9
04/18/23 10
04/18/23 11
04/18/23 12
04/18/23 13
04/18/23 14
C Program that implements Digital Thermometer using
DS18S20 1-Wire Bus Sensor
04/18/23 15
#include <hidef.h> /* common defines and macros */#include <mc9s12c128.h> /* derivative information */#include "lcd_subroutines.h"#pragma LINK_INFO DERIVATIVE "mc9s12c128"
//DS18S20 (Dallas Semiconductor 1-wire Bus Temperature Sensor)//Pins Used: LCD Panel 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
04/18/23 16
#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 float. // (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;
04/18/23 17
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();
04/18/23 18
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 + 0x30; //Decompose "temp" into three decimal ASCII digits temp = temp/10; middlechar = temp%10 + 0x30; temp = temp/10; mschar = temp%10 + 0x30;
04/18/23 19
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 pointLCD_DTA(fractchar);
//Display fractional part (0.0 or 0.5 deg C)delay6us(30000);
//Wait about 0.2 seconds between temperature samples}
}
04/18/23 20
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++);}
}
04/18/23 21
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 lowdelay6us(80); //Wait for 480 USDQDDR = 0; //Allow DQ to be pulled highdelay6us(12); //Wait for 70 USpresence = 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);
}
04/18/23 22
unsigned char read_bit_one_wire(void) //Read one bit{ unsigned char i;
DQ = 0;DQDDR = 1; //Pull DQ low to start timeslotDQDDR = 0; //Then let DQ line be pulled high.delay6us(2); //delay 12 us from start of timesloti = DQ;return(i); //return value of DQ line (as set by temp sens)
}
04/18/23 23
void write_bit_one_wire(char bitval) //Write one bit{ DQ = 0;
DQDDR = 1; //Pull DQ low to start timeslotif(bitval == 1) DQDDR = 0; //Let DQ go high to write a 1delay6us(18); //delay 108 usDQDDR = 0; //Let DQ line go high to end cycle
}
04/18/23 24
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
delay6us(18); //Wait for rest of timeslot }return(value);
}
04/18/23 25
void write_byte_one_wire(char val) //Write a byte to the 1-wire device{
unsigned char i;unsigned char temp;
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}
delay6us(18);}
04/18/23 26
How a single bit of an 8-bit port may be accessed (read or written) in C
• Let us focus on PTM0, as an example
• Then “PTM_PTM0 = 1;” will set just bit #0 of Port M, or “while(PTM_PTM0);” will hang up until bit #0 of Port M goes low.
• Look at the MC9S12C128.h header file (under Libraries in the Project View).
• Note the following excerpts from this file:
04/18/23 27
At very top of this header file……..
/* Types definition */typedef unsigned char byte;typedef unsigned int word;typedef unsigned long dword;typedef unsigned long dlong[2];
#define REG_BASE 0x0000 /* Base address for the I/O register block */
04/18/23 28
/*** PTM - Port M I/O Register; 0x00000250 ***/typedef union { byte Byte; struct { byte PTM0 :1; /* Port M Bit 0 */ byte PTM1 :1; /* Port M Bit 1 */ byte PTM2 :1; /* Port M Bit 2 */ byte PTM3 :1; /* Port M Bit 3 */ byte PTM4 :1; /* Port M Bit 4 */ byte PTM5 :1; /* Port M Bit 5 */ byte :1; byte :1; } Bits; struct { byte grpPTM :6; byte :1; byte :1; } MergedBits;} PTMSTR;
04/18/23 29
extern volatile PTMSTR _PTM @(REG_BASE + 0x00000250);#define PTM _PTM.Byte#define PTM_PTM0 _PTM.Bits.PTM0#define PTM_PTM1 _PTM.Bits.PTM1#define PTM_PTM2 _PTM.Bits.PTM2#define PTM_PTM3 _PTM.Bits.PTM3#define PTM_PTM4 _PTM.Bits.PTM4#define PTM_PTM5 _PTM.Bits.PTM5#define PTM_PTM _PTM.MergedBits.grpPTM