PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : DS1820 gibt immer 85°C (0xAA00) aus



Spessi
26.02.2009, 16:25
Hallo,
seit gestern Abend ärger ich mich nun schon mit dem 1-Wire-Bus rum. Eigentlich ist ja alles recht einfach und es steht auch ausführlich im Datasheet von Application Note beschrieben.
Der DS1820 (Parasite Mode!) sendet beim Reset seinen Responce Pulse, wird also erkannt. Auch die Seriennummer wird korrekt ausgelesen. Starte ich nun allerdings einen Convert-Vorgang und gebe dann den Scratchpad aus, dann gibt er ihn so aus, wie er eigentlich beim Power-Up ist (laut DS) - es hat sich also nichts geändert.
Nachdem ich den Convert starte lege ich zusätzlich 5V (strong pullup) auf dem 1-Wire-Bus von einem Port-Pin aus an, da er sonst zuviel Strom für den Parasite-Mode zieht (im Datasheet wurde das ganze mit einem MOSFET umgesetzt, aber sollte ja das gleiche sein). Dann warte ich etwas mehr als 750ms und schalte die zusätzlichen 5V wieder ab. Sollte ja alles passen soweit. Aber funktionieren tut es nicht.

Hier mal der Quellcode, nicht erschrecken, das ist durch das ewige Rumprobieren, weil es nicht funktionierte, etwas durcheinander. Das Wesentliche (des Problems) ist in der: ds1820_read_temperature



#include <p18f2620.h>
#include "delays.h"

#pragma config OSC = INTIO67 //Intern Osci
#pragma config PWRT = ON
#pragma config WDT = OFF //Watchdog Timer
#pragma config LVP = OFF //Low Voltage ICSP

unsigned char temp;

/* prototypes */
void usart_init(void);
void usart_txc(char c);
void usart_txs(const rom char* s);
unsigned char ow_read();
void ow_high();
void ow_low();
unsigned char ow_reset_pulse();
void ow_write_bit(unsigned char write_bit);
void ow_write_byte(unsigned char write_data);
unsigned char ow_read_bit(void);
unsigned char ow_read_byte(void);
void usart_tx_hex_ascii(unsigned char display_data);
unsigned char ds1820_read_temperature(void);

void usart_init(void) {
SPBRG = 12; // 9600bps
TXSTAbits.SYNC = 0; // asynchronous
RCSTAbits.SPEN = 1; // enable usart
TXSTAbits.TXEN = 1; // enable transmit
}

void usart_txc(char c) {
TXREG = c;
while(!TXSTAbits.TRMT);
}

void usart_txs(const rom char* s) {
while(*s) {
usart_txc(*s);
s++;
}
}

void usart_tx_hex_ascii(unsigned char display_data) { /* not my work ;) c&p */
unsigned char temp;
temp = ((display_data & 0xF0)>>4);
if (temp <= 0x09)
usart_txc(temp+'0');
else
usart_txc(temp+'0'+0x07);

temp = display_data & 0x0F;
if (temp <= 0x09)
usart_txc(temp+'0');
else
usart_txc(temp+'0'+0x07);
}



unsigned char ow_read() {
unsigned char read_data=0;
TRISCbits.TRISC4 = 1;
if(PORTCbits.RC4 == 1)
read_data = 1;
else
read_data = 0;
return read_data;
}

void ow_high() {
LATCbits.LATC4 = 0;
TRISCbits.TRISC4 = 1;
}

void ow_low() {
LATCbits.LATC4 = 0;
TRISCbits.TRISC4 = 0;
}

unsigned char ow_reset_pulse() {
unsigned char presence_detect;
ow_low();
Delay10TCYx(96); /* 480us */
ow_high();
Delay10TCYx(14); /* 70us */
presence_detect = ow_read();
Delay10TCYx(82); /* 410us */
ow_high();
return presence_detect;
}


void ow_write_bit(unsigned char write_bit) {
if(write_bit) { /* writing a '1' */
ow_low();
Delay10TCYx(1); /* 5us */
ow_high();
Delay10TCYx(1); /* 5us */
}
else { /* writing a '0' */
ow_low();
Delay10TCYx(12); /* 60us */
ow_high();
Delay10TCYx(12); /* 60us */
}
}

void ow_write_byte(unsigned char write_data) {
unsigned char loop;
for(loop=0;loop<8;loop++) {
ow_write_bit(write_data & 0x01); /* Send LS-bit first */
write_data >>=1; /* shift data for the next bit to send */
}
}

unsigned char ow_read_bit(void) {
unsigned char read_data;
ow_low();
Delay10TCYx(1); /* 5us */
ow_high();
Delay10TCYx(2); /* 10us */
read_data = ow_read();
Delay10TCYx(11); /* 55us */
return read_data;
}

unsigned char ow_read_byte(void) {
unsigned char loop, result = 0;
for (loop=0;loop<8; loop++) {
result >>= 1; /* shift result 'out of the way' ;) */
if (ow_read_bit())
result |= 0x80; /* if result is one, then set MSB */
}
return result;
}

unsigned char ds1820_read_temperature(void) {
unsigned char temperature[9];

if(ow_reset_pulse()) /* first reset */
return 1;
ow_write_byte(0xCC); /* skip rom */

ow_write_byte(0x44); /* start convert */
TRISCbits.TRISC5 = 0; /* strong pullup on */
Delay10KTCYx(170); /* 750ms ... Tconv */
TRISCbits.TRISC5 = 1; /* strong pullup off */

if(ow_reset_pulse()) /* second reset */
return 1;
ow_write_byte(0xCC); /* skip rom */
ow_write_byte(0xBE); /* read Scratchpad */

usart_txs("\r\nTemperature: ");
for(temp=0;temp<=8;temp++)
temperature[temp] = ow_read_byte(); /* store in var */
for(temp=0;temp<=8;temp++)
usart_tx_hex_ascii(temperature[temp]); /* put it in hex->ascii on usart */

if(ow_reset_pulse()) /* third reset */
return 1;
return 0;
}


void main(void) {
unsigned char serialnumber[8];
OSCCON = 0x73; // 8mhz internal
TRISCbits.TRISC5 = 1;
LATCbits.LATC5 = 1;
ow_high();
usart_init();
usart_txs("=== Welcome to Thermostation v1.0 ===\r\nRunning at 8MHz on internal oscillator\r\n");
usart_txs("DS1820 detected: ");
if(!ow_reset_pulse())
usart_txs("yes\r\n");
else
usart_txs("no\r\n");
ow_write_byte(0x33); /* Command to send the serial number */
usart_txs("Serial number: ");
for(temp=0;temp<8;temp++)
serialnumber[temp] = ow_read_byte();
for(temp=0;temp<8;temp++)
usart_tx_hex_ascii(serialnumber[temp]);

if(ow_reset_pulse())
usart_txs("\r\nSomething went wrong\r\n");
while(1) {
if(ds1820_read_temperature()!=0)
usart_txs("\r\nLost connection. Try to reconnect\r\n");
Delay10KTCYx(100);
}
}

Die Ausgabe am PC:


=== Welcome to Thermostation v1.0 ===
Running at 8MHz on internal oscillator
DS1820 detected: yes
Serial number: 100356C1010800C0
Temperature: AA004B46FFFF0C1087
Temperature: AA004B46FFFF0C1087
Temperature: AA004B46FFFF0C1087
Temperature: AA004B46FFFF0C1087
Temperature: AA004B46FFFF0C1087
Temperature: AA004B46FFFF0C1087
[... geht immer so weiter ...]

Da wo AA00 steht sollte normal die Temperatur stehen, aber AA00 bedeutet 85°C und das passt definitiv nicht.

Würde mich freuen wenn mir jemand helfen kann.

Gruß Spessi

linux_80
26.02.2009, 23:20
bringt der DS1820 nicht die 85°, wenn der noch keine Messung gemacht hat, nach dem Power-up :-k
Also entweder nach dem Starten der Messung zu schnell den Wert gelesen, oder dem DS1820 geht der Saft aus !

Spessi
27.02.2009, 00:29
Moin.
Also, hab jetzt mal nen DS1820 direkt mit Strom versorgt (kein Parasite-Power) und da gehts problemlos. Aber die Timings stimmen doch alle, ich kann's mir echt nicht erklären.

linux_80
27.02.2009, 01:03
Die Wartezeit sollte reichen, hab das mit 700ms schon erfolgreichen gemacht.
Da ich die PICs nicht kenne, weiss ich nicht wie das mit dem Pullup hinhaut.

Hast Du das mal mit nur einem externen Pullup 4k7 probiert ?
https://www.roboternetz.de/wissen/index.php/Bascom_und_1-Wire#Parasit.C3.A4re_Stromversorgung

Spessi
27.02.2009, 01:31
Ja, habe ich auch schon probiert. Geht auch nicht. Steht ja auch extra im Datasheet, dass man einen "Strong Pullup", also eigentlich einen MOSFET, der 5V direkt auf den 1-Wire-Bus schaltet, dazulegen soll, wenn die Konvertierung startet.

Spessi
04.03.2009, 18:02
Ich pushe ja nur ungern, aber hat denn keiner ne Idee?
Mit direkter Stromversorgung klappt das ganze wunderbar, nur im Parasite-Mode liefert er mir immer die Start-Up Werte des Scratchpads. Seriennummer auslesen etc. klappt also in beiden Varianten.
Wenn ich den Konvertierungsvorgang starte schalte ich einen I/O vom PIC direkt als Ausgang (zusätzlich zu dem 4,7k Ohm R) auf den 1-Wire-Bus, der "Strong Pullup" ist also vorhanden.

Wäre schön wenn das irgendwie noch lösbar wäre. Es kommt mir so vor als würde ihm während dem Konvertieren einfach der Strom ausgehen (im internen C) und er resettet. Aber das ist ja durch die zugeschaltete Leitung eigentlich nicht möglich.


Grüße

hannes01
05.03.2009, 22:37
Hallo Spessi
Ich habe einen18B20 P erfolgreich laufen ,nehme für den strong pullup auch einen IO pin sogar noch mit einem 1000 Ohm wiederstand dazwischen zur Strombegrenzung .Du hast allerdings nur 10µs Zeit um den
strong pullup zu schalten.Ich gebe allerdings den Konvertierungsvorgang 800ms Zeit (12Bit).Ich meine mal in einen Datenblatt gesehen zu haben das der VDD pin bei parasite power auf GND gelegt werden muß find die Datei nur gerade nicht muß mal googlen

hannes01
05.03.2009, 23:00
Hier mal die Datei
ÄHH wie bekommt man denn hier eine Datei angehängt?
Schau mal bei Dallas Maxim unter AN203
MFG
Hannes

Spessi
05.03.2009, 23:56
Hallo,
ja das mit VDD an GND steht auch im Datasheet, das habe ich gemacht.


ow_write_byte(0x44); /* start convert */
TRISCbits.TRISC5 = 0; /* strong pullup on */
Delay10KTCYx(170); /* 750ms ... Tconv */
TRISCbits.TRISC5 = 1; /* strong pullup off */

Wie du hier siehst starte ich den Konvertierungsvorgang und schalte _direkt_ danach den IO dazu. Das sollte doch keine 10µS dauern, oder?

Hab auch schon 1000ms Wartezeit gemacht, war das gleiche Ergebnis.

Danke für deine Antwort, vielleicht findet man ja noch das Problem.

Gruß