Re: CRC Berechnung von Temp.Sensor DS18B20 Kategorie: Programmierung C (von Ernst H. - 27.02.2011 19:10) | ||
Als Antwort auf Re: CRC Berechnung von Temp.Sensor DS18B20 von Joerg - 27.02.2011 17:56 | ||
| ||
> > > > // Beispielprogramm um den DS18S20 Temperatur Sensor von Dallas Maxim zu lesen > > > > // mit Berechnung der CRC Prüfsumme - bei Fehler extra Zeile > > > > char Text[40]; > > > > int ret,Heiz,i,Secure; > > > > int temp, Heiztemp; > > > > byte rom_code[8]; > > > > byte scratch_pad[9]; //'9ehemals > > > > byte Serienschutz[8]; > > > > char Fehler; > > > > byte CRC_Wert; > > > > #define One_Wire_Port 35 //'e3, hier das Port für den Sensor > > > > > > > > > > > > > > > > > > > > void main(void) > > > > { > > > > do > > > > { > > > > ret = OneWire_Reset(One_Wire_Port); > > > > if (ret == 0) > > > > { > > > > Text= "Kein Sensor gefunden"; > > > > Msg_WriteText(Text); > > > > goto Ende; > > > > } > > > > // �ndern der Konfiguration (Default 12 Bit) nun 9 Bit > > > > // OneWire_Write(0xcc) ' ROM überspringen Kommando > > > > OneWire_Write(0x4e); // Master issues Write Scratchpad command > > > > OneWire_Write(0x7F); // Master sends three data bytes to scratchpad ..TH > > > > OneWire_Write(0xFF); // sicherheitshalber niedrigste Temp in Tl .....TL > > > > // OneWire_Write(0b00011111) // für 9 Bit und config Bitanzahl ..9-12 > > > > // OneWire_Write(0b00111111) // für 10 Bit > > > > // OneWire_Write(0b01011111) // für 11 Bit > > > > OneWire_Write(0b01111111); // für 12 Bit > > > > ret = OneWire_Reset(One_Wire_Port); // #define One_Wire_Po > > > > if (ret == 0) > > > > { > > > > Text= "Kein Sensor gefunden"; > > > > Msg_WriteText(Text); > > > > goto Ende; > > > > } > > > > OneWire_Write(0xcc); //' ROM überspringen Kommando > > > > OneWire_Write(0x44); //' starte Temperatur Messung Kommando > > > > > > > > AbsDelay(1000); > > > > > > > > OneWire_Reset(One_Wire_Port); // ' PortA.7 > > > > OneWire_Write(0xcc); //' ROM überspringen Kommando > > > > OneWire_Write(0xbe); //' lese scratch_pad Kommando > > > > for (i=0; i<9; i++) //' komplettes scratchpad lesen > > > > { > > > > scratch_pad[i]= OneWire_Read(); > > > > Msg_WriteText(" " ); > > > > Msg_WriteWord(i ); > > > > Msg_WriteText(":=" ); > > > > Msg_WriteHex(scratch_pad[i]); > > > > } > > > > //'SCRATCHPAD (Power-up State) > > > > //'byte 0 Temperature LSB (50h) > > > > //'byte 1 Temperature MSB (05h) EEPROM > > > > //'byte 2 TH Register or User Byte 1* TH Register or User Byte 1 > > > > //'byte 3 TL Register or User Byte 2* TL Register or User Byte 2 > > > > //'byte 4 Configuration Register* Configuration Register > > > > //'byte 5 Reserved (FFh) > > > > //'byte 6 Reserved (0Ch) > > > > //'byte 7 Reserved (10h) > > > > //'byte 8 CRC* > > > > Msg_WriteText(" crc=" ); > > > > CRC_Wert=CRC_8(); > > > > Msg_WriteHex(CRC_Wert); //Berechnete CRC ausgeben > > > > Fehler = CRC_Wert - scratch_pad[8]; > > > > if (Fehler == 0) Msg_WriteText(" ok" ); > > > > else > > > > { > > > > Msg_WriteChar(13); > > > > Msg_WriteText(" Fehler=" ); > > > > Msg_WriteInt(Fehler); > > > > } > > > > Msg_WriteChar(13); > > > > Text = "Temperatur: "; > > > > Msg_WriteText(Text); > > > > temp = scratch_pad[1] * 256 + scratch_pad[0]; > > > > Msg_WriteFloat(temp /16.0); //'hier das Komma wichtig .. für 12Bit > > > > //'mit DS1822 > > > > Msg_WriteChar(99); > > > > Msg_WriteText(" Dez=" ); > > > > Msg_WriteWord(scratch_pad[0] ); > > > > Msg_WriteChar(13); > > > > > > > > } > > > > while(1); > > > > > > > > Ende: // Label Ende > > > > > > > > } > > > > > > > > > > > > > > > > byte CRC_8(void) > > > > { > > > > int Schleifen_count; > > > > byte Pruf_Byte, CRC, Bit_Count, Wert_Bit; > > > > CRC = 0; > > > > for (Schleifen_count = 0; Schleifen_count < 8; Schleifen_count++) > > > > { // die 8 Byte werden berechnet (0-7) > > > > Bit_Count = 8; > > > > Pruf_Byte = scratch_pad[Schleifen_count]; > > > > do > > > > { // jedes Bit wird extra hinzuberechnet > > > > Wert_Bit = (CRC ^ Pruf_Byte) & 0x01; > > > > if ( Wert_Bit == 0x01 ) CRC = CRC ^ 0X18; // 0X18= X^8+X^5+X^4+X^0 > > > > CRC = 0x7F & (CRC >> 1); > > > > if ( Wert_Bit == 0x01 ) CRC = CRC | 0x80; > > > > Bit_Count--; > > > > Pruf_Byte = Pruf_Byte >> 1; > > > > } while (Bit_Count > 0); > > > > } > > > > return CRC; > > > > } > > > > > > Hallo, > > > > > > ich hatte auch erst diese Variante realisiert. Sie braucht nur sehr viel Rechenzeit. > > > Ich habe mich dann für die Tabellenversion entschieden. > > > Da ich die Tabelle mit 'flash' abgelegt habe, benötigt sie auch kein Ram. > > > > > > Grü�e Joerg > > Hallo Joerg! > > Die Rechenzeit stört mich auch, habe 13ms gemessen das ist enorm. > > > > Ich habe auch Tests wegen Leitungslänge gemacht - mit einen erstaunlichen Ergebnis: > > bei ca 10m 4pol Kabel (für RJ12 Telefonstecker) kein crc Felher entdeckt. > > bei ca 90m (ganze Spule dazwischengeschalten) nur jedes ca 20x ein Fehler. > > Systembedingt habe ich die 5V direkt am Sensor mit 100 Ohm belastet, nach den 90m ist > > dann die Versorgungsspannung nur mehr 3,8V trotzdem nur geringe Probleme!. > > Zu bemerken ist aber das das Kabel aufgespult und nicht verlegt ist. Angeschlossen ist der > > Sensor nicht parisitär, also mit 5V Versorgung - aber ohne Pull Up Widerstände. > > Am Oszi verbessert sich das Impulsverhalten mit 2x 2k2 Pull Up bringt aber nicht viel. > > (die Pull up Wid. gerhören meiner Ansicht auf beiden Seiten - da einmal der Prozessor auf > > Low zieht, dann der Sensor) > > Bei ca 40m Cat 5 verlegten Netzwerkkabel sind die Fehler dann schon häufiger. > > > > > > Ich wäre sehr dankbar wenn Du die Tabellenversion hier Posten würdest - diese 13ms Rechenzeit > > passt mir nämlich nicht ins Konzept. > > > > Vielen Dank! > > Ernst H. > > > > /********************************************************************************* > * Table for CRC calculation > ********************************************************************************/ > flash byte crc8_table[256] = { > 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, > 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, > 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, > 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, > 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, > 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, > 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, > 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, > 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, > 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, > 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, > 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, > 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, > 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, > 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, > 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53}; > > > byte calculate_table_crc8(byte data[], byte n) > { > byte temp, crc, i, tmp; > > crc = 0; > for (i=0; i < n; i++) // loop over all data > { > tmp = crc^data[i]; > crc = crc8_table[tmp]; > } > return(crc); > } > > > > Grü�e Joerg Hallo Joerg! Vielen Dank - funktioniert Perfekt! statt 13ms nur mehr ca 0,9ms - super!. Fertiges Programm zum Testen und vergleichen: //' Beispielprogramm um den DS18S20 Temperatur Sensor von Dallas Maxim zu lesen //' mit Berechnung der CRC Prüfsumme - bei Fehler extra Zeile //' //' Fertiges Programm - einfach kopieren und starten //' Sensor an E.3 anschlie�en, zum messen: C.2 zuerst crc berechnet..ca 13ms, //' dann crc mit Tabellenberechnung (von Joerg) ca 0,9ms !!! char Text[40]; int ret,Heiz,i,Secure; int temp, Heiztemp; byte rom_code[8]; byte scratch_pad[9]; //'9ehemals char Fehler; byte CRC_Wert; #define One_Wire_Port 35 //'e3, hier das Port für den Sensor void main(void) { Port_DataDirBit(18,1 ); //'C.2 zum Zeitmessen als Ausgang Port_DataDirBit(19,1 ); //'C.3 zum Zeitmessen als Ausgang do { ret = OneWire_Reset(One_Wire_Port); if (ret == 0) { Text= "Kein Sensor gefunden"; Msg_WriteText(Text); goto Ende; } //' �ndern der Konfiguration (Default 12 Bit) nun 9 Bit //' OneWire_Write(0xcc) ' ROM überspringen Kommando OneWire_Write(0x4e); // Master issues Write Scratchpad command OneWire_Write(0x7F); // Master sends three data bytes to scratchpad ..TH OneWire_Write(0xFF); // sicherheitshalber niedrigste Temp in Tl .....TL //' OneWire_Write(0b00011111) // für 9 Bit und config Bitanzahl ..9-12 //' OneWire_Write(0b00111111) // für 10 Bit //' OneWire_Write(0b01011111) // für 11 Bit OneWire_Write(0b01111111); // für 12 Bit ret = OneWire_Reset(One_Wire_Port); //' #define One_Wire_Po if (ret == 0) { Text= "Kein Sensor gefunden"; Msg_WriteText(Text); goto Ende; } OneWire_Write(0xcc); //' ROM überspringen Kommando OneWire_Write(0x44); //' starte Temperatur Messung Kommando AbsDelay(1000); OneWire_Reset(One_Wire_Port); // ' PortA.7 OneWire_Write(0xcc); //' ROM überspringen Kommando OneWire_Write(0xbe); //' lese scratch_pad Kommando for (i=0; i<9; i++) //' komplettes scratchpad lesen { scratch_pad[i]= OneWire_Read(); Msg_WriteText(" " ); Msg_WriteWord(i ); Msg_WriteText(":=" ); Msg_WriteHex(scratch_pad[i]); } //'SCRATCHPAD (Power-up State) //'byte 0 Temperature LSB (50h) //'byte 1 Temperature MSB (05h) EEPROM //'byte 2 TH Register or User Byte 1* TH Register or User Byte 1 //'byte 3 TL Register or User Byte 2* TL Register or User Byte 2 //'byte 4 Configuration Register* Configuration Register //'byte 5 Reserved (FFh) //'byte 6 Reserved (0Ch) //'byte 7 Reserved (10h) //'byte 8 CRC* Msg_WriteText(" crc=" ); Port_WriteBit(18,1 ); //'C.2 zum Zeitmessen auf High CRC_Wert=CRC_8(); Port_WriteBit(18,0 ); //'C.2 zum Zeitmessen auf Low Msg_WriteHex(CRC_Wert); //'Berechnete CRC ausgeben Msg_WriteText(" Tab=" ); Port_WriteBit(18,1 ); //'C.2 zum Zeitmessen auf High CRC_Wert = calculate_table_crc8(scratch_pad,8); Port_WriteBit(18,0 ); //'C.2 zum Zeitmessen auf Low Msg_WriteHex(CRC_Wert); //'Berechnete CRC nach Tabelle ausgeben Fehler = CRC_Wert - scratch_pad[8]; if (Fehler == 0) Msg_WriteText(" ok" ); else { Msg_WriteChar(13); Msg_WriteText(" Fehler=" ); Msg_WriteInt(Fehler); } Msg_WriteChar(13); Text = "Temperatur: "; Msg_WriteText(Text); temp = scratch_pad[1] * 256 + scratch_pad[0]; Msg_WriteFloat(temp /16.0); //'hier das Komma wichtig .. für 12Bit //'mit DS1822 Msg_WriteChar(99); Msg_WriteText(" Dez=" ); Msg_WriteWord(scratch_pad[0] ); Msg_WriteChar(13); } while(1); Ende: //' Label Ende } byte CRC_8(void) { int Schleifen_count; byte Pruf_Byte, CRC, Bit_Count, Wert_Bit; CRC = 0; for (Schleifen_count = 0; Schleifen_count < 8; Schleifen_count++) { //' die 8 Byte werden berechnet (0-7) Bit_Count = 8; Pruf_Byte = scratch_pad[Schleifen_count]; do { //' jedes Bit wird extra hinzuberechnet Wert_Bit = (CRC ^ Pruf_Byte) & 0x01; if ( Wert_Bit == 0x01 ) CRC = CRC ^ 0X18; //' 0X18= X^8+X^5+X^4+X^0 CRC = 0x7F & (CRC >> 1); if ( Wert_Bit == 0x01 ) CRC = CRC | 0x80; Bit_Count--; Pruf_Byte = Pruf_Byte >> 1; } while (Bit_Count > 0); } return CRC; } //'************************************************************************ //' * Table for CRC calculation //'************************************************************************ flash byte crc8_table[256] = { 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53}; byte calculate_table_crc8(byte data[], byte n) { byte temp, crc, i, tmp; crc = 0; for (i=0; i < n; i++) //' loop over all data { tmp = crc^data[i]; crc = crc8_table[tmp]; } return(crc); } Gruss Ernst H. | ||
Antwort schreiben Antworten: |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum