Bascom LCD Anzeige PC4004LRU von Powertip

Welches Programm ist das jetzt? Wie kommst Du mit den Werten auf 0,3°C?
Es ist das Programm aus #42
Nachtrag: wie sieht das ganze bei wärmeren Temperaturen aus, also bei mehr als 5°C?
Es läuft ohne Fehler.
Angehängt die Logdatei von heutemorgen bei 14,2°C

Habe noch mal nachgelesenum eine erhöte auflösung zu erreichen kann man das 7 Byte (Count_Remain) mit auswerten, dies enhält werte zwischen 1 und 16 , die Burkhard Kainka als 16tel Grad interpretiert.

Hier die Berechnung von ihm, das scratchpad habe ich eingefügt :



CodeBox BascomAVR
 1wreset
  1wwrite &H55
  1wwrite Id2(1) , 8
  1wwrite &HBE
  Rom(1) = 1wread(8)
  Temp = Rom(1) / 2
  Temp = Int(temp)
  Tempdif = 16 - Rom(7)
  Tempdif = Tempdif / 16
  Temp = Temp + Tempdif
  Print Fusing(temp , "#.#&");
  Print "    ";
   Print
   Print "ds1820_scratchpad(1)=" ; Bin(Rom(1)) ; "'LSB"
   Print "ds1820_scratchpad(2)=" ; Bin(Rom(2)) ; "'MSB"
   Print "ds1820_scratchpad(3)=" ; Bin(Rom(3)) ; "'User1"
   Print "ds1820_scratchpad(4)=" ; Bin(Rom(4)) ; "'User2"
   Print "ds1820_scratchpad(5)=" ; Bin(Rom(5)) ; "'Res1"
   Print "ds1820_scratchpad(6)=" ; Bin(Rom(6)) ; "'Res2"
   Print "ds1820_scratchpad(7)=" ; Bin(Rom(7)) ; "'Cnt_Rem"
   Print "ds1820_scratchpad(8)=" ; Bin(Rom(8)) ; "'Cnt_Per_C"
   Print "ds1820_scratchpad(9)=" ; Bin(Rom(9)) ; "'CRC"
   Print
 

Anhänge

  • output_2018-05-20_08-36-23.log.txt
    2,4 KB · Aufrufe: 2
Zuletzt bearbeitet:
Habe noch mal nachgelesenum eine erhöte auflösung zu erreichen kann man das 7 Byte (Count_Remain) mit auswerten, dies enhält werte zwischen 1 und 16 , die Burkhard Kainka als 16tel Grad interpretiert.
Hat er wo geschrieben?
Das sollte nur beim DS18S20 so sein. Wie ich bereits mehrfach gesagt habe: der 18S20 arbeitet intern mit 12 Bit. Acht Bit vor dem Komma, vier hinter dem Komma. Nach dem Komma geht's weiter wie vor dem Komma: ein Bit nach rechts ist die Hälfte, ein Bit nach links das doppelte. Binärsystem halt. Das letzte Vorkommabit entspricht "Eins", das erste Nachkommabit "Einhalb", das zweite "Einviertel", das dritte "Einachtel", das vierte "Einsechzehnteltel".Beim einfachen auslesen werden die oberen Neun (als 8 und das erste Nachkomma) im MSB..LSB bereitgestellt. Das entspricht der Darstellung im 1820. Die vier Nachkommabits sind außerdem in Count_Remain abgelegt, der Beschreibung nach rechtsorientiert. Also das sechzehntel Bit steht auf der 1, das halb-Bit auf der acht. Wenn Du das nur ausliest, hast Du das sechzehnfache. Deswegen teilst Du Tempdif durch 16. Im DS18S20 liefert Count_per_C genau deswegen immer(!) 16.

Wie gesagt - der 18S20 mißt anders, liefert aber die Ergebnisse kompatibel zum 1820.

Beim 1820 liefert Count_per-C nicht zwingend 16 - da wäre also nicht immer durch sechzehn zu teilen. Entsprechend liefert Count_Remain auch nicht nur Werte zwischen 0 und 16, sondern werte zwischen 0 und Count_per_C (wobei das mir bei negativen Werten noch nicht ganz klar ist - ggf im Zweierkomplement...)

Ich komme bei beiden Logs überall auf CRC-Fehler - beim Log aus #47 paßts:hmmmm:

Wenn ich heut noch zu komme, veranschauliche ich mal die Idee meines weiteren Rechenweges (also mit 16bit Ganzzahl (bzw Festkomma) statt Single.

P.S.: bei der Ausgabe der Scratch-Abbilder fehlt hinter dem "=" immer ein "&B", also zB hier

CodeBox BascomAVR
 Print "ds1820_scratchpad(1)=" ; Bin(Rom(1)) ; "'LSB"
sollte es so aussehen

CodeBox BascomAVR
 Print "ds1820_scratchpad(1)=&B" ; Bin(Rom(1)) ; "'LSB"

Dann kann man den Block zum simulieren kopieren...
 
Zuletzt bearbeitet:
Hat er wo geschrieben?
Es ist das Buch Basiskurs Bascom-AVR 1.Auflage von 2011, auf Seite 129 "Mikrocontroller-Interfaces" Spricht er vom DS1820,
auf Seite 130 ist eine Verdrahtungszeichnug mit der Darstellung des DS18S20 und auf Seite135 beschreibt er die Bessere auflösung mit 1/16 °C, in der Passenden Bascom Datei ist ein DS1820 Bezeichnet.
 
Zuletzt bearbeitet:
Heute ist schönes Wetter geniesst es, die DS1820 laufen nicht weg.
Hatte Samstag bereits angefangen, das mal zusammenzuschreiben - so, daß ich es hier halbwegs erkennbar (und hoffentlich nachvollziehbar) einfügen kann. ('n vollgekritzelten Schmierzettel will ich nicht hochladen - der möglicherweise kommende uploadFilter ( :stupid: ) erkennt da dann noch'n Picasso oder sowas...)
Gestern und heute morgen (senile Bettflucht?) sind mir noch ein paar Details dazu eingefallen/aufgefallen, die ich nachher ergänze (der Rechner ist noch aus) - dann stell ich das hier ein.
Der Trick ist im wesentlichen, daß die Daten bereits imScratch-Abbild bereitliegen, also irgendwo geordnet im SRAM. Und zwar als Bytes. Zum Teil sind die signed zu behandeln, einige als 8- andere als 16Bit-Variablen. Statt viel rumzurechnen greife ich eher sinnig Auf die bereits liegenden Daten zu - bzw lasse Bascom das mit Overlay tun (Overlay erzeugt keine neuen Daten im SRAM, sondern nur einen (neuen/anderen) Zugriff auf dort befindliche Daten. So kannst Du zB einen Integer als Word behandeln, das Highbyte einer Variable als Lowbyte einer anderen, ...)
Der Bascom-Code wird also mehrere Overlay-Definitionen enthalten (die aber keinen Maschinencode erzeugen sondern nur die Behandlung der folgenden Instruktionen festlegen) und wenige tatsächliche Operationen (eine Integerdivision (16Bit-signed/8Bit-unsigned), eine Addition (16Bit+16Bit) und eine Addition einer Konstante (die sich als Zuweisung realisieren läßt. Und das Abschneiden des Halbkelvin-Bits wie ich es oben schon hatte -> 16bit einmal rechtsschieben). Alles ganzzahlige Operationen.
 
Hab als Beispiel mal dieses Telegramm aus einem der Logs genommen, das dort angegebene Ergebnis war mit Singles berechnet:

CodeBox BascomAVR
ds1820_scratchpad(1)=00110001'LSB
ds1820_scratchpad(2)=00000000'MSB
ds1820_scratchpad(3)=01001011'User1
ds1820_scratchpad(4)=01000110'User2
ds1820_scratchpad(5)=11111111'Res1
ds1820_scratchpad(6)=11111111'Res2
ds1820_scratchpad(7)=00000111'Cnt_Rem
ds1820_scratchpad(8)=00010000'Cnt_Per_C
ds1820_scratchpad(9)=10001101'CRC

'24.3125 C

Mein Rechenweg beginnt mit dem Scratch-Array, allerdings sind die Indizees um eins verschoben (um vorn ein Dummy frei zu haben). Quasi das Array eins größer dimensioniert, und die 1wire-Daten dann ab Index=2 eingeschrieben.
Code:
|Array(1)|Array(2)|Array(3)|Array(4)|Array(5)|Array(6)|Array(7)|Array(8)|Array(9)|Array(10)        <-ScratchPad-Array im SRAM allokiert
| Dummy  |  LSB   |  MSB   | User1  | User2  |  Res1  |  Res2  |Cnt_Rem |Cnt_p_C |  CRC   |        <-diese Sensordaten landen hier
|00000000|00110001|00000000|01001011|01000110|11111111|11111111|00000111|00010000|10001101|        <-Beispieldaten (binär)
|  0x00  |  0x31  |  0x00  |  0x4B  |  0x46  |  0xFF  |  0xFF  |  0x07  |  0x10  |  0x8D  |        <-hex
|        |  LSB   |  MSB   |        |        |        |        |        |        |        |        <-Integervariable R_Tmp (nur Overlay)
|        |  0x31  |  0x00  |        |        |        |        |        |        |        |        <-R_tmp=0x0031=49dez
R_Tmp einmal unter Beachtung des Signs rechtsschieben entspricht ganzzahliger Integerdivision durch 2
Dabei wird erst das MSByte nach rechts geschoben (ASR), das LSBit landet im Carryflag,
danach das LSByte mit dem Carryflag nach rechts gerollt (ROR). Das Halb-Kelvin_bit fällt dabei
ins Carryflag und wird ignoriert.
|00000000|00011000|00000000|01001011|01000110|11111111|11111111|00000111|00010000|10001101|        <-Ergebnis
|        |  0x18  |  0x00  |        |        |        |        |        |        |        |        <-R_Tmp=0x0018=24dez
|  LSB   |  MSB   |        |        |        |        |        |        |        |        |        <-Integervariable R_Tmp256 (nur Overlay)                                        
|  0x00  |  0x18  |        |        |        |        |        |        |        |        |        <-R_Tmp256=0x1800=6144dez=R_Tmp*256 ;-)
Den Quotienten Count_Remain/Count_per_C multiplizieren wir mit demselben Trick (Overlay-Variable)
mit 256.
|        |        |        |        |        |        |  LSB   |  MSB   |        |        |        <-Integervariable Cnt_R256 (nur Overlay)
|        |        |        |        |        |        |  0xFF  |  0x07  |        |        |        <-LSB löschen
|        |        |        |        |        |        |  0x00  |  0x07  |        |        |        <-Cnt_R256=0x0700=256*Cnt_R=256*0x07 ;-)
|        |        |        |        |        |        |        |        |  LSB   |        |        <-Bytevariable Cnt_p_C (nur Overlay)
|        |        |        |        |        |        |        |        |  0x10  |        |
16Bit-Division (Integer/Byte) Cnt_R256/Cnt_p_C, Ergebnis nach Cnt_R256 schreiben
|        |        |        |        |        |        |  0x70  |  0x00  |        |        |        <-16bit-Division 0x0700/0x10=0x0070
(Beim DS18S20 müßte man ja immer durch 16 teilen, das ließe sich einfacher mit vier Shifts
erreichen (also viermal durch zwei = 4 Takte) - beim DS1820 ist Divisor aber nicht immer 16)
|        |        |        |        |        |        |        |        |        |        |
Zu R_Tep wären 0,75dez zu addieren, wir rechnen aber mit dem 256fachen also addieren wir
die Konstante 192dez (=0xC0=&B11000000) zu R_Tmp256
|  0xC0  |  0x18  |        |        |        |        |        |        |        |        |        <-R_Tmp256=R_Tmp256 + 0xC0
Davon jetzt den Quotienten abziehen                                                                <-R_Tmp256=R_Tmp256 - CNT_R256
|  0x50  |  0x18  |        |        |        |        |        |        |        |        |        <-0x18C0-0x0070=0x1850
Fertig!!
Wie ist das jetzt zu interpretieren?
0x1850 ist das 256fache der Temperatur. Für den ganzzahligen Anteil müßte man theoretisch durch
256 teilen - oder eben das MSB als 8bit-Zahl lesen
Im MSB von R_Tmp256 = LSB von R_Tmp (also Array(2)) steht also bereits die Vorkommastelle
0x18 = 24dez
In Array(1) steht entsprechend der Nachkommaanteil 0x50=&B01010000
Wie ist so ein binärer Nachkommaanteil zu verstehen? Wie auch vor dem Komma: eine Stelle nach
links verdoppelt, eine nach rechts halbiert. Das MSB stünde also für 0,5 das zweite von links
für 0,25 usw, das vierte für 0,0625. 0x50 nach dem Komma entspricht also 0,25 + 0,0625 = 0,3125

0x18,50 entspricht also 24,3125
Bei genauem Hinsehen fällt auf, daß Array(0) erstmal mit 0x00 initialisiert wird (in jeder Rechnung initialisiert werden muß), und später "dreiviertel" (0xC0) draufaddiert wird. Statt der Addition später kann man also auch gleich mit 0xC0 initialisieren.
Das erhaltene Ergebins kann jetzt zur weiteren Berechnung verwendet werden, oder wenn nötig (geschickt) in einen String umgewandelt werden.
 
Zuletzt bearbeitet:
Nach mehrmaligem durchlesen verstehe ich es Langsam, einige Rechenschritte sind einleuchtend und bei anderen muss ich mir dies erst anlesen.( Mr.Google )
Ich weis halt noch nicht, wie man den MC mit dem richtigen Rechenschritten Programmiert, mache es auf die herkömmliche weise und das kostet Rechnerzeit
Du hasst es aber in deiner Tabelle echt klasse dargestellt, verdeutlicht.
Aber wie berechnet man den CRC, gibt es da etwas ?
Versuche es mal nachzuvollziehen warum er einen CRC Fehler ausgibt.
 
mit dem richtigen Rechenschritten Programmiert
Ich habe da oben möglichst versucht, Rechenschritte zu vermeiden, indem ich geschickt auf die abgelegten Daten im SRAM zugreifen lasse (Definition der Overlay-Variablen).
Die einzigen Rechenschritte (Programmschritte) sind:
  1. Dummybyte Null setzen
  2. R_Tmp rechtsschieben (also durch zwei teilen)
  3. Lowbyte von Count_R256 löschen
  4. Count_R256 durch Count_per_C teilen (<-- Intergerdivision, aufwändigste Operation)
  5. 0,75*256=192=0xC0 auf R_Tmp256 addieren
  6. Ergebnis von (4) auf R_Tmp256 addieren
Das Dummybyte wird in (1) auf die Konstante Null gesetzt, in (5) wird eine Konstante addiert, die nur das Dummy ändert. Kann man also zusammenfassen, wenn man in (1) Dummy gleich auf 0xC0 setzt, entfällt (5).
(4) ist als Integerdivision die einzige äufwändige Routine - der AVR kann nicht teilen. Aber er kann schieben. Wenn also durch eine Zweierpotenz zu teilen ist (siehe auch (2)), kann er das sehr effizient.

Aber wie berechnet man den CRC, gibt es da etwas ?
Wikipedia zu CRC
Das Generatorpolynom findest Du im Datenblatt des DS18(S)20, außerdem wird dort auf "Note 27: Understanding and Using Cyclic Redundancy Checks with Maxim ịButton Products" hingewiesen, welche Du hier findest.
BASCOMs CRC8()-Funktion ist auf die 1wires von Dallas/Maxim ausgelegt - Du kannst natürlich auch selbst Bits schubsen (wobei da dann Inline-Assembler zu empfehlen wäre - bei der Rechnung oben übrigens auch.).
 
So das ganze mit dem Beispiel aus #67 mal durchexerziert:
Code:
|Array(2)|Array(3)|Array(4)|Array(5)|Array(6)|Array(7)|Array(8)|Array(9)|Array(10)        <-ScratchPad-Array im SRAM allokiert
|  LSB   |  MSB   | User1  | User2  |  Res1  |  Res2  |Cnt_Rem |Cnt_p_C |  CRC   |        <-diese Sensordaten landen hier
|00110001|00000000|01001011|01000110|11111111|11111111|00000111|00010000|10001101|        <-Beispieldaten (binär)
Die Bytes werden in dieser Reihenfolge vom Sensor übertragen, beginnen aber je mit dem
niederwertigsten Bit, also müssen(*) wir die je Flippen.
|10001100|00000000|11010010|01100010|11111111|11111111|11100000|00001000|10110001|        <-Resultierender Bitstrom
100011000000000011010010011000101111111111111111111000000000100010110001                <-ohne Trennzeichen

Das Generatorpolynom ist X^8 + X^5 + X^4 + 1 - besser
1*X^8 + 0*X^7 + 0*X^6 + 1*X^5 + 1*X^4 + 0*X^3 + 0*X^2 + 0*X^1 + 1*x^0 also 100110001

100011000000000011010010011000101111111111111111111000000000100010110001                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
000101001000000011010010011000101111111111111111111000000000100010110001

101001000000011010010011000101111111111111111111000000000100010110001                    <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR 
001111001000011010010011000101111111111111111111000000000100010110001

1111001000011010010011000101111111111111111111000000000100010110001                        <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR 
0110101010011010010011000101111111111111111111000000000100010110001

110101010011010010011000101111111111111111111000000000100010110001                        <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR 
010011011011010010011000101111111111111111111000000000100010110001

10011011011010010011000101111111111111111111000000000100010110001                        <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR 
00000011111010010011000101111111111111111111000000000100010110001

11111010010011000101111111111111111111000000000100010110001                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR 
01100010110011000101111111111111111111000000000100010110001

1100010110011000101111111111111111111000000000100010110001                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0101110100011000101111111111111111111000000000100010110001

101110100011000101111111111111111111000000000100010110001                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
001000101011000101111111111111111111000000000100010110001                 

1000101011000101111111111111111111000000000100010110001                                    <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0001001001000101111111111111111111000000000100010110001

1001001000101111111111111111111000000000100010110001                                    <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0000101010101111111111111111111000000000100010110001

101010101111111111111111111000000000100010110001                                        <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
001100100111111111111111111000000000100010110001

1100100111111111111111111000000000100010110001                                            <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0101000101111111111111111000000000100010110001

101000101111111111111111000000000100010110001                                            <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
001110100111111111111111000000000100010110001

1110100111111111111111000000000100010110001                                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0111000101111111111111000000000100010110001

111000101111111111111000000000100010110001                                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
011110100111111111111000000000100010110001

11110100111111111111000000000100010110001                                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
01101100011111111111000000000100010110001

1101100011111111111000000000100010110001                                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0100000001111111111000000000100010110001

100000001111111111000000000100010110001                                                    <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
000110000111111111000000000100010110001

110000111111111000000000100010110001                                                    <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
010110110111111000000000100010110001

10110110111111000000000100010110001                                                        <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
00101110011111000000000100010110001

101110011111000000000100010110001                                                        <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
001000010111000000000100010110001

1000010111000000000100010110001                                                            <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0001110101000000000100010110001

1110101000000000100010110001                                                            <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0111001010000000100010110001

111001010000000100010110001                                                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
011111011000000100010110001

11111011000000100010110001                                                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
01100011100000100010110001

1100011100000100010110001                                                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0101111110000100010110001

101111110000100010110001                                                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
001001111000100010110001

1001111000100010110001                                                                    <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0000011010100010110001

11010100010110001                                                                        <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
01001100110110001

1001100110110001                                                                        <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
0000000100110001

100110001                                                                                <-Bitstrom linksschieben bis erstes Bit=1
100110001
---------                                                                                <-XOR
000000000    <-Fertig da Bitstrom erschöpft, CRC ist "0" also korrekt
=========


(*) kann man natürlich geschickt umgehen, machen wir aber hier der Übersichtlichkeit
halber nicht (indem man das ganze umdreht, also den Generator flipt, und den Strom nach rechts schiebt)
Der Assemblerer sieht natürlich, daß die neun Stellen des Generators schön gewählt sind. Da vorher der Bitstrom immer geschoben wird, bis'ne "1" am Anfang steht (und der Generator da auch 'ne "1" hat), wird diese Stelle beim XOR immer "0". Also vergessen wir diese beim Generator, und schieben beim Bitstrom stattdessen sooft, bis 'ne "1" aus dem Bitstrom raus ins Carry fällt. Zu verXORren sind somit also nur je 8 Bit (die AVR sind 8bit-MCUs ;) )

Da beim Empfang des Bitstromes schon geschoben wird, wäre es eigentlich sinniger, die CRC gleich da mit zu generieren. Das sollte sich da mit nur wenigen zusätzlichen Takten und Variablen hinzufügen lassen (wobei Bascom ja eh auf die Sample-Fenster wartet). 1wread könnte also eigentlich ohne nennenswerten Mehraufwand nebenbei(!!) die CRC miterledigen, und das Ergebnis als Byte zurückliefern/bereitstellen. Zur Erinnerung: Als ich damals die Takte des Rechenweges überschlagen hatte, kam der CRC8-Check auf etwa 650 Takte.
 
Wikipedia zu CRC
Das Generatorpolynom findest Du im Datenblatt des DS18(S)20, außerdem wird dort auf "Note 27: Understanding and Using Cyclic Redundancy Checks with Maxim ịButton Products" hingewiesen, welche Du hier findest.
BASCOMs CRC8()-Funktion ist auf die 1wires von Dallas/Maxim ausgelegt - Du kannst natürlich auch selbst Bits schubsen (wobei da dann Inline-Assembler zu empfehlen wäre - bei der Rechnung oben übrigens auch.).
Ja das habe ich auch schon alles gelesen, auch die AN27.
Hier bei YouTube habe ich was gefunden, der erklärtes recht gut ->
So das ganze mit dem Beispiel aus #67 mal durchexerziert:
klasse erklärt
 
wäre es eigentlich sinniger,
Für andere Kommunikationsschnittstellen wie UART, I²C oder SPI (seltener auch IrDA) besitzen die AVR Hardware-Module, die den Transfer weitgehend selbständig im Hintergrund erledigen, und Dich nur bei Bedarf zu Interaktionen auffordern. (Gäbe es 'n 1wire-Modul, würde dies mit Sicherheit auch den CRC unterstützen).
Aber es gibt eben kein 1wire-Modul, folglich muß das ganze in Software erfolgen.

Grundsätzlich bestimmt der Master das Bustiming, muß sich dabei natürlich an gewisse Vereinbarungen halten.
Beim Empfang soll er mindestens 1µs den Bus auf Gnd ziehen, der Slave soll dann für 15µs das zu übertragende Bit auf den Bus legen (also Gnd für "0", tristate für "1"). Nachdem der Master also den Bus wieder freigegeben hat, liest (*) er den Bus. Der Master darf das nächste Bit frühestens 1µs nach dem freigeben des Busses initiieren.

In #70 habe ich beim CRC-Rechenweg immer geschrieben: "Bitstrom linksschieben bis erstes Bit=1". Beim Empfang wird ja jedes Bit einzeln empfangen, bzw der AVR schiebt es sich selbst als Master rein. Es ist also so zu verstehen, daß der Master ein Bit nach dem anderen in seine "Variablen" schiebt, zusätzlich aber auch in (bzw durch) ein acht Bit breites Register (nennen wir es CRC-Register). Also jedes empfangene Bit wird in der entsprechenden Variable (letzten Endes im SRAM) abgeladen, zusätzlich(!) in das CRC-Register geschoben. Jedesmal, wenn dabei 'ne "1" rausgeschoben wird (also das Carry kommt), wird das CRC-Register mit dem Generatorpolynom verXORrt (den unteren 8Bit, das neunte Bit im Carry ist "1", der vom Generator auch).

(*) liest heißt, daß der AVR im entsprechenden Zeitpunkt den Zustand des entsprechenden Pinregister-Bits in ein Rechenregister rollen muß, und komplette Bytes ggf ins SRAM kopieren muß (an die Adresse der Variable).
Quick'nDirty geht das, indem man:
  1. das Carryflag löscht (CLC - ein Takt)
  2. das Controllerbein mit SBIC prüft (=wenn das Bein "0" ist, wird automatisch die nächste Instruktion ignoriert - kostet zusammen mit (3) immer zwei Takte)
  3. das Carry setzt (SEC) - Der Beinzustand ist jetzt also im Carry
  4. Das Carry in ein Rechenregister (nennen wir es 1wire-Register) schiebt (bzw rollt). Da die Bits LSB-first kommen also von Links. (ROR - ein Takt)
Vier Takte pro Bit, das ganze muß natürlich in einer Schleife achtmal (jedesmal zum entsprechenden Zeitpunkt) pro Byte gemacht werden, anschließend daß Rechenregister ins SRAM kopiert werden. Es wird abgesehen von Schleifenzählern, Timing-Zählern und dem Pointer ins SRAM nur ein Rechenregister benötigt.
(4) manipuliert seinerseits das Carry, man kann also nicht einfach als (5) das Carry in das CRC-Register rollen (ROL).
Die Schritte (1) bis (3) zu wiederholen ist auch nicht schön, das Bein könnte sich ja inzwischen geändert haben.
Statt mit SBIC auf ein I/O-Register-Bit (das Pinregister) zu prüfen, kann man mit SBRC auf ein Rechenregister-Bit (das 1wire-Register) prüfen. Also nochmal:
  1. das Carryflag löscht (CLC - ein Takt)
  2. das Controllerbein mit SBIC prüft (=wenn das Bein "0" ist, wird automatisch die nächste Instruktion ignoriert - kostet zusammen mit (3) immer zwei Takte)
  3. das Carry setzt (SEC) - Der Beinzustand ist jetzt also im Carry
  4. das Carry in ein Rechenregister (nennen wir es 1wire-Register) schiebt (bzw rollt). Da die Bits LSB-first kommen also von Links. (ROR - ein Takt)
  5. Carry nochmal löschen (1 Takt)
  6. das MSB des 1wire-Registers mit SBRC prüfen (zusammen mit (7) zwei Takte)
  7. Carry setzen
  8. Carry ins CRC-Register rollen (ROL - 1 Takt)
  9. Mit BRCC die nächste Instruktion mit BRCC überspringen wenn eine "0" ins Carry geschoben wurde (kostet zusammen mit der nächsten Instruktion immer 2 Takte)
  10. CRC-Register mit Generator verXORren (EOR)
Zehn Takte pro Bit zuzüglich Schleifen-/Timing-Kram.

Opfert man ein weiteres Rechenregister, kann ein Takt gespart werden.
Zusätzlich zu den abgespeicherten empfangenen Daten liegt also am Ende das Ergebnis der CRC im CRC-Register.

Ein Takt dauert bei 1MHz eine µs - das ganze sollte sich also so bequem während des Empfangens erledigen lassen, wenn der AVR noch langsamer getaktet wird, sinkt lediglich die Baudrate. Bei weniger als etwa ... 250kHz Taktfrequenz (denk ich mal) bekommt man eh langsam Probleme, nach dem Bit-Start-Strobe den Sample-Point beim lesen zu treffen...
(Jaja, ich seh hier schon wieder jemanden 'nen Watchdog-Oszillator als Taktquelle in den Thread werfen, nur so als Herrausforderung - gelt Thomas...)
 
Hallo LotadaC
Nicht das du meinst ich hätte kein Interesse mehr, aber wir standen das ganze Wochenende ohne Internet da.
Habe jetzt ein Oszi da und den Kalibrierofen und werde heute oder Morgen dann mal den Bus abtasten.
Habe schon mal im Normal zustand ein Paar Kurven aufgenommen, als Trigger habe ich Kanal A genommen mit fallender Flanke.
Hast du von Fluke das Programm FlukeView, dann kann ich die Orginaldateien schicken, ansonsten schicke ich *.jpg's.
 

Anhänge

  • Convertieren.jpg
    Convertieren.jpg
    329,3 KB · Aufrufe: 7
  • Reset.jpg
    Reset.jpg
    305,9 KB · Aufrufe: 6
  • Scratchpad.jpg
    Scratchpad.jpg
    538,6 KB · Aufrufe: 7
So habe gerade mal Provisorisch die Tempereturen durchgefahren und siehe da mit dem Temperaturofen gibt es keinen CRC Fehler.
Bis -16°C ging es runter.
 

Anhänge

  • output_2018-05-29_16-14-13.log.txt
    103 KB · Aufrufe: 2
  • Temp-5.188°C.jpg
    Temp-5.188°C.jpg
    567,2 KB · Aufrufe: 5
Hmm… keine Ahnung...
Feuchtigkeits- / Kontaktprobleme?

Dann kannst Du ja die Optimierungen wieder angehen. Wenn Du mit dem Ofen 'ne Temperaturreferenz hast, würde ich das Programm so umstellen, daß (ggf auf Anforderung via Taster etc...) der Sensor ausgelesen wird, anschließend die Ergebnisse der unterschiedlichen Rechenwege (also Deine(n) ursprüngliche(n), meinen aus #46, wenn Du Dir #67 selbst zutraust auch den (Variante aus 46 modifiziert bereits das Array, das Rechtsschieben ist also bereits erledigt))
Dann könnte man mal die Ergebnisse mit der Ofentemperatur vergleichen.

Das Programm wäre insofern auch interessant, um Laufzeiten und ggf Flashbedarf zu vergleichen.

P.S.: hab im Moment selbst nicht viel Zeit...
 
Denke das es mit dem Kältespray zu tun hat, ist ja änlich wie flüssiger Stickstoff.
Es ist wahrscheinlich schlagartig zu kalt, so das die Sensoren ihren Dienst einstellen.
Mit dem Ofen gab es keine Probleme,
Feuchtigkeits- / Kontaktprobleme?
alles mehrfach kontrolliert, weder Feuchtigkeit noch Kontakt Probleme.
Übrigens, die Genauigkeit des Sensors ist schon genial :
Soll-Temperatur = Ofen geregelt = 0°C, Kalibrierter Referenzsensor = -0,12°C und der DS1820 = -0,313°C, mein Aussenthermometer = +1,4°C
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)