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:
- das Carryflag löscht (CLC - ein Takt)
- 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)
- das Carry setzt (SEC) - Der Beinzustand ist jetzt also im Carry
- 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:
- das Carryflag löscht (CLC - ein Takt)
- 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)
- das Carry setzt (SEC) - Der Beinzustand ist jetzt also im Carry
- 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)
- Carry nochmal löschen (1 Takt)
- das MSB des 1wire-Registers mit SBRC prüfen (zusammen mit (7) zwei Takte)
- Carry setzen
- Carry ins CRC-Register rollen (ROL - 1 Takt)
- 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)
- 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...)