// Bedienung des Thermometers. void ds_send_bit(bit); void DS1822_sendbyte(byte); bit ds_read_bit(); byte ds_read_byte(); // Parameter für Übertragung #define READDUR 10 #define WRITE_1 2 #define WRITE_0 75 #define TIMESLOT 80 #define RESET_PULSE 500 // DS1822 Kommandos #define READROM 0x33 #define MATCHROM 0x55 #define SKIPROM 0xcc #define CONVERT 0x44 #define WRSCRATCH 0x4e #define RDSCRATCH 0xbe #define COPYSCRATCH 0x48 #define RECALL 0xb8 #define RDPOWER 0xB4 byte romcode[8]; // Enthält den ROM Code des DS1822 // Reset Pulse senden, 1=DS1822 antwortet, 0=antwortet nicht byte DS1822_Reset() { int16 to; DS1822_PIN = 0; // Bus runterziehen DS1822_DIR = 0; delay_us(RESET_PULSE); DS1822_PIN = 1; // Bus hoch delay_us(5); // Warten bis Slave reagiert DS1822_DIR = 1; // Jetzt Bus auf Antwort prüfen to = 300; while (DS1822_PIN) { if (--to==0) return(0); delay_us(1); } delay_us(480); return (1); } // Fragt ROM Code ab // Rückgabe: 1=ok, 0=Fehler byte DS1822_ReadROM() { byte i; // Resetten if (!DS1822_Reset()) return(0); // Kommando absetzen DS1822_sendbyte(READROM); for (i=0;i<8;i++) romcode[i] = ds_read_byte(); // Stimmt der Family Code? if (romcode[0]!=0x28) return(0); return(1); } // Initialisiere den Temperatursensor // Fragt ROM Code ab und setzt 12 Bit Auflösung // Rückgabe: 1=ok, 0=Fehler byte DS1822_Init() { byte i; // Resetten if (!DS1822_Reset()) return(0); // 12 Bit Auflösung setzen DS1822_Reset(); DS1822_sendbyte(SKIPROM); DS1822_sendbyte(WRSCRATCH); DS1822_sendbyte(0); DS1822_sendbyte(0); DS1822_sendbyte(0x60); delay_us(10); return(1); } // Liest Temperatur aus byte DS1822_ReadTemp(int16 *temp,int8* vorz) { int16 adwert,lo,hi; byte sign; // Resetten if (!DS1822_Reset()) return(0); // Kommando absetzen DS1822_sendbyte(SKIPROM); DS1822_sendbyte(CONVERT); // Warte bis DS188 fertig gewandelt hat while (!ds_read_bit()); // Auslesen einleiten DS1822_Reset(); DS1822_sendbyte(SKIPROM); DS1822_sendbyte(RDSCRATCH); // Nur Temperatur auslesen lo = ds_read_byte(); hi = ds_read_byte(); adwert = ((hi<<8)|lo)*10; // Ausgabe in Dezi-Grad 296 = 29,6° // Übertragung beenden DS1822_Reset(); // Vorzeichen auswerten sign = (adwert & 0x8000) >> 16; if (sign) adwert ^= 0xffff; // Temperatur ermitteln aus den Daten, bei 12 Bit /16 teilen, bei // 11 bit / 8, bei 10 bit / 4 usw. *temp = adwert/16; *vorz = sign; return(1); } // -------------------------------------------------------------------------- // Sendet 1 Byte an den DS1822, LSB zuerst void DS1822_sendbyte(byte data) { byte i,k; for (i=0;i<8;i++) { k = data & 0x01; // LSB ausmaskieren data = data>>1; // Daten rechts schieben ds_send_bit(k); } } // Sendet eine 0 oder 1 auf dem 1-wire Bus // b darf nur 1 oder 0 sein void ds_send_bit(byte b) { DS1822_DIR = 0; // Port auf Ausgang DS1822_PIN = 0; // Bus runterziehen if (b) { // 1 senden delay_us(WRITE_1); // Wartezeit für 1 DS1822_DIR = 1; // Bus loslassen delay_us(TIMESLOT-WRITE_1); // Timeslot abwarten } else { // 0 senden delay_us(WRITE_0); // Wartezeit für 0 DS1822_DIR = 1; // Bus loslassen delay_us(TIMESLOT-WRITE_0); // Timeslot abwarten } delay_us(3); // Kleine Lücke lassen } // Empfängt ein Byte vom DS1822 byte ds_read_byte() { byte i,data; data = 0; for (i=0;i<8;i++) { if (ds_read_bit()) bit_set(data,i); } return(data); } // Empfängt ein Bit vom DS1822 byte ds_read_bit() { bit data; DS1822_DIR = 0; // Port auf Ausgang DS1822_PIN = 0; // Bus runterziehen delay_us(WRITE_1); DS1822_DIR = 1; // Port auf Eingang delay_us(READDUR); // Warten bis DS1822 reagiert data = DS1822_PIN; // 1 oder 0 einlesen // Timeslot abwarten delay_us(TIMESLOT-READDUR-WRITE_1); return(data); }