barkerben
Joined: 19 Jan 2006 Posts: 22
|
DS18S20 being stubborn |
Posted: Sat Feb 04, 2006 3:49 pm |
|
|
Hello...
I've been trying all day to interface a DS18S20 temperature sensor to a PIC18F452. I have done my best to follow the steos in the data sheet to the letter but always read -1 degrees. The fact that I'm not shivering suggests otherwise :-)
The probe can run in parasitic mode but for now I'm running it of the board supply for simplicity - no charging during temperature conversion etc.
I don't know if anyone else has used this before. There were some other posts, but I started my own code becuse, looking at the datasheet, and with the help of the CCS example code, it looked straighforward...
Any thoughts?
Code: |
#include <18F452.h>
#fuses HS,NOPROTECT,NOLVP
#define PC_TX PIN_D2
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PC_TX,stream=PC) //TX line to level converter and PC
#include <string.h>
#include <stdlib.h>
#define TOUCH_PIN PIN_D1
void touch_write_byte(BYTE);
BYTE touch_read_byte();
void main() {
signed int16 temperature; //Signed 16 bit word to store temperature in
#BYTE high_byte = temperature
#BYTE low_byte = temperature + 1
while (TRUE) {
output_low(TOUCH_PIN);
delay_us(500); //Master issues reset pulse, then releases line
output_float(TOUCH_PIN);
touch_write_byte(0xCC); //We only have one device, so use 'skiprom' command for simlicity - all (one) devices are addressed
touch_write_byte (0x44); //Master issues command to start temperature conversion
delay_ms(1000); //Wait for temp. conversion (750ms max from data sheet)
output_low(TOUCH_PIN);
delay_us(500); //Master issues reset pulse, then releases line
output_float(TOUCH_PIN);
touch_write_byte(0xCC); //Address all probes (we only have 1)
touch_write_byte (0xBE); //Ask it to send us scratchpad register
high_byte = touch_read_byte(); //There are 9 bytes sent, but for now we only nee the first two - the basic temperature
low_byte = touch_read_byte(); //So issue a reset after the second byte has been read
output_low(TOUCH_PIN);
delay_us(500); //Master issues reset pulse, then releases line
output_float(TOUCH_PIN);
fprintf (PC,"\r\nTemperature: %Ld C",temperature);
delay_ms (1000);
}
}
BYTE touch_read_byte() {
BYTE i,data;
//see page 13 0f data sheet
for(i=1;i<=8;++i) {
output_low(TOUCH_PIN); //Start of read time slot. First, hold line low for 5us (min 1)
delay_us(5);
output_float(TOUCH_PIN); //Now release the line so that the slave can send. Send will last for 15us from falling edge of time slot
shift_right(&data,1,input(TOUCH_PIN)); //Read a 1 or 0 from the line.
delay_us(20); //Hold for 20us to ensure master has read bit and to provide recovery time between slots
//loop around 8 times to get an entire byte
}
return(data);
}
void touch_write_byte(BYTE data) {
BYTE i;
//see page 12 0f data sheet
for(i=1;i<=8;++i) { //Loop around 8 times to read an entire byte
output_low(TOUCH_PIN); //Start of write time slot
delay_us(10);
output_float(TOUCH_PIN); //release within 15us to start slot
if(shift_right(&data,1,0)) { //we shift a bit out of the data byte, ad see if it is a 1 or a 0
output_high(TOUCH_PIN); //if it is a 1, then we send the pin high
delay_us(60); //and leave it high for 60us
} else {
output_low(TOUCH_PIN); //else, it must be a 0, so we senf the pin low
delay_us(60); //and again leave it for 60us
}
output_float(TOUCH_PIN); //release line
delay_us(50); //recovery time
}
}
|
|
|