Hallo, stehe vor folgender Aufgabe: Ich will in einer Interruptroutine über einen Zeitraum von 300µs 600 Messwerte von einem parallelen 8Bit A/D-Wandler, der an einem Port des ATMega1284p hängt ins SRAM schieben um diese anschließend weiterzuverarbeiten. Der Interrupt wird nur etwa alle 80ms ausgelöst, so dass ich zwischen den Interrupts genügend Zeit habe die Daten weiterzuverabeiten. Ich programmiere üblicherweise in C. Meine Frage: Kann man die Aufgabe mit C oder Inline-Assembler bewältigen? AVR läuft mit 16MHz. Somit hätte ich pro Sample 8 Takzyklen Zeit. Bin in Assembler nicht wirklich fit, hab mir aber gerade mal die Instruktiontable angesehen und komme zu folgendem Resultat: loop: IN Rd, A --> 1 Zyklus ST Z+, Rr --> 2 Zyklen CPI Z, 800 --> 1 Zyklun BRNE loop --> 1,2 Zyklen Also gesamt 5-6 Zyklen. Damit könnte ich 2,67MSps in den SRAM schieben, ist das korrekt? Danke.
CPI Z, 800 ist wohl etwas umfangreicher. Ein CPIW gibt es nicht. INIT Z MOV Rcount,200 loop: IN Rd, A --> 1 Zyklus ST Z+, Rr --> 2 Zyklen IN Rd, A --> 1 Zyklus ST Z+, Rr --> 2 Zyklen IN Rd, A --> 1 Zyklus ST Z+, Rr --> 2 Zyklen IN Rd, A --> 1 Zyklus ST Z+, Rr --> 2 Zyklen DEC Rcount --> 1 Zyklus BRNE loop --> 1,2 Zyklen 14 Zyklen pro 4 Bytes. (3,5 per Byte) mov rH, HIBYTE(800) loop: IN Rd, A --> 1 Zyklus ST Z+, Rr --> 2 Zyklen CPI ZL,LOBYTE(800) --> 1 Zyklus CPC ZH,rH --> 1 Zyklus BRNE loop --> 1,2 Zyklen 6 Zyklen pro 1 Byte. Die Methode nennt sich entrollen von Schleifen.
Tobias schrieb: > loop: > IN Rd, A --> 1 Zyklus > ST Z+, Rr --> 2 Zyklen > CPI Z, 800 --> 1 Zyklun > BRNE loop --> 1,2 Zyklen > > Also gesamt 5-6 Zyklen. Damit könnte ich 2,67MSps in den SRAM schieben, Löse die Schleife auf. Kostet Flash, ist aber deutlich schneller. Die Anzahl der Werte kannst über die Einsprungadresse berechnen PC = loop_n + (loop_nm1-loop_n) *(n-x) loopn: IN Rd, A --> 1 Zyklus ST Z+, Rr --> 2 Zyklen loop_nm1: IN Rd, A --> 1 Zyklus ST Z+, Rr --> 2 Zyklen ... IN Rd, A --> 1 Zyklus ST Z+, Rr --> 2 Zyklen tue was anderes
Hallo, Tobias schrieb: > Ich will in einer Interruptroutine über einen Zeitraum von 300µs 600 das heißt alle 500ns stehen neu Daten an wie wird denn das synchronisiert? nach 80ms kommt der int und dann werden für 300µs 600bytes aufgenommen? keine Ahnung wie das in C aufgerufen wird oder beendet wird (InlineAsm) Das mit dem CPI Z,800 geht so nicht da CPI nur 8bit breit vergleichen kann... rein in asm: .equ Datastart = $0060 ;speicherpunkt/zelle Einsprung vom C rcall init_ZPOINTER loop: IN RD,A ;1 Zyk ST Z+,Rr ;2 Zyk CPI ZL,LOW(DataStart+600) ;1 Zyk BRNE loop ;1-2 Zyk CPI ZH,High(DataStart+600) ;1 Zyk BRNE loop ;1-2 Zyk = Rücksprung zu C init_ZPOINTER: ldi zh,high(DataStart) ldi zl,low(DataStart) ret
Für die 600 Meßwerte steht genug RAM zur Verfügung. Der Quarz sollte dann eine passende Frequenz (20 MHz z.B.) haben um mit NOP die entrollte Schleife vom Timing her zu frisieren. Hauptproblem wird die Verzögerung durch den Interrupteinstieg sein. Und die Verarbeitunggeschwindigkeit.
Hallo, vielen Dank für die Antworten. 6 Zyklen / Sample sollte also möglich sein. Dann gehe ich das Thema so an. chris schrieb: > das heißt alle 500ns stehen neu Daten an wie wird denn das > synchronisiert? Für die Synchronisierung mit dem ADC würde ich einen vom CPU-Takt abgeleiteten Takt generieren und über die Output Compare Unit ausgeben. Am Anfang der Interruptroutine will ich dann ebenfalls in Assembler das sampling der Daten auf den den Takt synchronisieren. chris schrieb: > nach 80ms kommt der int und dann werden für 300µs 600bytes aufgenommen? Korrekt. Die Daten werden anschließend verrechnet. Bei den Messwerten handelt es sich um einen Zündspannungsverlauf. Es sollen die Zündspannung, die Brenndauer und die Brennspannung sowie Anomalien des Signals vermessen werden. Dennis Heynlein schrieb: > Hauptproblem wird die Verzögerung durch den Interrupteinstieg sein. Da sehe ich in meiner Anwendung kein Problem, da die ersten 5µs des Signals für mich uninteressant sind. Starten will ich das Sampling über eine eigene Komparatorschaltung ebenfalls Interruptgesteuert. Ein zeitlicher Versatz eines gesampleten Datenblocks zum nächsten um ein paar µs spielt keine Rolle. Dennis Heynlein schrieb: > Und die Verarbeitunggeschwindigkeit. 80ms reichen mir hier auch mit Weiterverarbeitung in C völlig aus.
Dennis Heynlein schrieb: > CPI Z, 800 ist wohl etwas umfangreicher. Ach komm, CPI + CPC kostet gerade mal einen Zyklus mehr als bei 8Bit. Sind dann 7 Zyklen, also ist noch ein NOP nötig, um auf 8 zu kommen.
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.