Ich möchte mit AVR ein Linear rückgekoppeltes Schieberegister programmieren um damit in einer Modellbahnwelt die lichter "zufällig" an und aus zu schalten. Ich finde aber leider keinen ansatz wie ich das programmieren muss. hat zufällig jemand den Quellcode dafür, bzw. ein ähnliches beispiel?
Wo genau liegt das Problem? Wenn Du weißt, welche Bits rückgekoppelt werden müssen, dann ist der Rest doch trivial: Einmal schieben und die EXOR-verknüpften Bits hinten dranhängen.
kann ich den einzelne bits exor'en oder nur zwei register?
Matthias P. wrote:
> kann ich den einzelne bits exor'en oder nur zwei register?
Du musst Dir die Werte so schieben, dass die zu verknüpfenden Bits an
der selben Position liegen (idealerweise an Position 0). Dann das
(bitweise) EXOR drauf loslassen, das Ergebnis mit 1 verUNDen und zum
Schieberegister dazuODERn...
Matthias, Google nach LFSR und lese den gleichlautenden Artikel bei Wikipedia. Da steht alles was du benötigst. Google findet für dich auch listen mit sogenannten TAPS, also den Abgriffen zum xodern für unterschieldliche Bit-Anzahlen. Jochen Müller
Matthias, Das X-Odern ist eine sog. Parity-Berechnung. Es geht also nur darum, ob die Anzahl der Rückführbits die 1 sind gerade oder ungerade ist. Das lässt sich in Assembler sehr leicht machen: für jeden Bitabgriff wird ein Zähler erhöht wenn das bit=1 ist. dann wird der zähler rechts ins carry geschoben, bit-0 des zählers ist also im carry. das carry wird dann rechts in das lfsr-byte geschoben. wichtig: lfsr klappt nur, wenn das lfsr-byte anfangs ungleich null ist, also eine initialisierung einbauen. ;======================== ; 8Bit LFSR für data ;======================== LFSR: clr count sbrc data,7 inc count sbrc data,5 inc count sbrc data,4 inc count sbrc data,3 inc count ror count rol data brne lfsrx ldi data,128 lfsrx: ret Jochen Müller
Hier mal was für C
1 | volatile static uint8_t Feld[3]; |
2 | |
3 | void takt(void) |
4 | {
|
5 | int i; |
6 | uint8_t tmp_sreg; // temporaerer Speicher fuer das Statusregister |
7 | |
8 | tmp_sreg = SREG; // Statusregister (also auch das I-Flag darin) sichern |
9 | cli(); // Interrupts global deaktivieren |
10 | |
11 | i= (Feld[2] & 1<<7) ^ (Feld[2] & 1<<4); |
12 | |
13 | Feld[2]<<=1; |
14 | |
15 | if(Feld[1] & 1<<7) |
16 | Feld[2]++; |
17 | |
18 | Feld[1]<<=1; |
19 | |
20 | if(Feld[0] & 1<<7) |
21 | Feld[1]++; |
22 | |
23 | Feld[0]<<=1; |
24 | |
25 | if(i) |
26 | Feld[0]++; //ergebins dex xor reinschreiben |
27 | |
28 | SREG = tmp_sreg; // Interrupt Status-Register wieder herstellen |
29 | }
|
30 | |
31 | void main (void) |
32 | {
|
33 | Feld[0]=1; |
34 | Feld[1]=0; |
35 | Feld[2]=0; |
36 | |
37 | for(;;) |
38 | {
|
39 | takt(); |
40 | |
41 | //Feld[0]-[2] auf Ausgänge schreiben
|
42 | |
43 | //ein bißchen warten
|
44 | |
45 | }
|
46 | }
|
Danke für die Hilfe! denke ich habs verstanden, werde da mal ein bisschen rumschreiben, mir hat der richtige denkanstoß gefehlt... jetzt sollte es klappen Danke nochmal!
Hier noch was für avr-gcc. Ich verwende den Pseudozufalls-Algorithmus wie im c-File. Nach dem Start wird durch den zufälligen RAM-Inhalt eine seed berechnet, alles andere ist Arithmetik über nem endlichen Galois-Feld der Charakteristik 2, also sehr effizient zu berechnen. Hier noch der Header:
1 | #ifndef _PARIT_15_H_
|
2 | #define _PARIT_15_H_
|
3 | |
4 | extern uint16_t prandom(void); |
5 | |
6 | #endif // _PARIT_15_H_
|
Die avr-libc besitzt eine erprobte Implementierung eines LFSR-basierten rand() bzw. random().
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.