Guten Tag.
Habe ein "kleines" Progrämmchen geschrieben b.z.w. bin noch dabei.
Leider ist das Programm jetzt bereits so groß das ich obwohl ich es
möglichst übersichtlich gehalten habe nicht mit 100%iger Sicherheit
überprüfen kann ob ich auch alles richtig gemacht habe (Kein überfluten
des Stack, Sicherung aller benötigten Register und richtige
Rücksicherung ...)
Wie schon gesagt, Überprüfung ist freiwillig.
Was die Kommentare angeht: sehr gut, aber data_kill solltest du auch
besser kommentieren.
Bei Assemblerprogrammen sollte man fast jeden Befehl kommentieren, damit
man auch später (und ev. andere) nachvollziehen kann, warum man das so
gemacht hat.
Nur meine bescheidene Meinung.
Gewöhn Dir sowas garnicht erst an. Aus nem Interrupt raus gibt es nur
das RETI und nichts weiter!
Ins Main zurück springen ist ne Zeitbombe, die Dir irgendwann
explodiert, wenn das Progrämmchen auch nur ein Pfitzelchen größer wird.
Und warten im Interrupt ist auch Pfui-Bäh.
Sei nicht so sparsam mit Kommentaren.
Peter
Hi
>Und warten im Interrupt ist auch Pfui-Bäh.
LCD auch.
Aus langjähriger Assemblererfahrung: Mit dem Ansatz wirst du nicht froh.
Was soll das genau machen? PC-Tastetur einlesen?
MfG Spess
Peter Dannegger schrieb:> Gewöhn Dir sowas garnicht erst an. Aus nem Interrupt raus gibt es nur>> das RETI und nichts weiter!
Wie meinen? (Weil ich teilweise mit: sei -> reti rausgegangen war?)
Sonst bin ich doch immer mit Reti rausgegangen ...
> Ins Main zurück springen ist ne Zeitbombe, die Dir irgendwann>> explodiert, wenn das Progrämmchen auch nur ein Pfitzelchen größer wird.
Springe doch nur einmal ins Main (Loop) nach der Initialisierung und der
Sprung nach 0x00 ist zur Fehlerbehebung (eingrenzung das ich n Reset
habe weil ich an den Pin nicht rankomme).
> Und warten im Interrupt ist auch Pfui-Bäh.
Im Interrupt nutze ich massig Register, welche ich sonst immer sichern
müsste und wieder neu auslesen. Oder kennen sie da eine bessere
Möglichkeit?
> Sei nicht so sparsam mit Kommentaren.
Dachte das Reicht ... weiß nicht was ich da sonst noch hinschreiben
sollte ...
Trotzdem vielen Dank für die Anmerkungen
spess53 schrieb:> Hi>>>>>Und warten im Interrupt ist auch Pfui-Bäh.>>>> LCD auch.>>>> Aus langjähriger Assemblererfahrung: Mit dem Ansatz wirst du nicht froh.>>>> Was soll das genau machen? PC-Tastetur einlesen?>>>> MfG Spess
Beim Warten im Interrupt geht es mir darum das diese Arbeit nicht
unterbrochen werden darf/soll.
Was ist an meinem Ansatz falsch? Was würden sie empfehlen?
Am Mikrocontroller sind eine Tastatur und ein LCD angeschlossen.
Die Tasten der Tastatur werden auf dem Display dargestellt.
Es soll am Ende möglich sein auf dem Display nicht anders als auf dem PC
damit zu schrieben.
Michael Dierken schrieb:> Sonst bin ich doch immer mit Reti rausgegangen ...
Aus jeder Unterroutine darf es nur 1 Ausgang geben. Mehrfache Ausgänge
(und zudem, wenn sie so verteilt sind) brechen dir garantiert das
Genick...
Klar kostet das einen Sprung mehr, aber dafür ist das Leben wesentlich
einfacher und der Stack besser unter Kontrolle!
Michael Dierken schrieb:> Was ist an meinem Ansatz falsch? Was würden sie empfehlen?
Dort hinein gehört die ganze Arbeit:
1
; Hauptprogramm
2
3
Loop:
4
sbis PINB, 2 ; Noch bei Low PINB2 Reset
5
rjmp 0x00
6
rjmp Loop ; Rücksprung Loop da noch leer
In Interrupts wird nur gemacht, was das Hauptprogramm unterbricht (so
sind die Interrupts auch zu ihrem Namen gekommen).
> rjmp 0x00
Achtung: ein Sprung nach Adresse 0 ist KEIN RESET!
Michael Dierken schrieb:>> Sei nicht so sparsam mit Kommentaren.>> Dachte das Reicht ... weiß nicht was ich da sonst noch hinschreiben> sollte ...
Sorry.
Ich nehm alles zurück.
Ich war in Gedanken bei nem anderen Thread.
Vergiß also, was ich gesagt habe.
Peter
Hi
Ok, Interrupt heißt, auf kleinste Ereignisse zu reagieren. Z.B. es kommt
ein Nadelimpuls, dann eine kleine Weile nix. Den Nadelimpuls kannst du
nur sicher mit einem Interrupt erfassen, also kommt in die ISR ein flag,
was dieses Ereignis der Programmschleife übergibt. Das Programm prüft
irgendwann das Flag, bearbeitet das Ereignis und setzt das Flag zurück.
Unterschätze nicht die Geschwindigkeit deines Controllers. Bedenke, bei
1 MHz und 2 Taktzyklen pro Befehl dauert die Befehlsbearbeitung mal
grade zwei µSek. Wenn deine Programmschleife 1000 befehle ababeitet,ist
die Zykluszeit zwei mSek. Ich glaube nicht, das du so schnell schreiben
kannst, das selbst bei 1/10 Tastendruck (Puls-Pause) der Controller die
Zeichen nicht erfassen kann.
Gruß oldmax
Hi
Hab noch was vergessen...
Du setzt einen Interrupt ein, um schnell reagieren zu können und dann
programmierst du in die ISR eine Wartezeit. Meinst du nicht auch bei ein
wenig Überlegung, das diese Vorgehensweise nicht wirklich richtig sein
kann. ISR - schnell. Also, Ereignis erfassen, zuordnen und wieder raus.
Und nicht stundenlang überlegen, mach ich was oder nicht....
so, jetzt sollte es gut sein.
Gruß oldmax
Das Programm arbeitet so das es bei Beginn eines Zeichens (Fallende
Flank Clock) einen Interrupt auslöst welcher das Startbit abfragt. Ist
dies da so fährt er vor und wartet auf 8 Datenbits ...
Sollte das Startbit fehlerhaft sein (z.B. High) oder er die 8Bit +
Parität + Stop empfangen habe sowie Parität geprüft und Zeichen ans
Display ausgegeben so geht er wieder zurück ins Hauptprogramm.
Die Erkennung des nächsten Zeichens läuft immer über den interrupt
sodass ich nicht dauernt den Pin abfragen muss.
Ja aber ... wenn ich im Programm auf den nächsten Interrupt warte muss
ich die Register immer im SRAM sichern und nachher wieder zurücksichern
und ich müsste einen Timer setzen um ein abbrechen der Daten zu
erkennen.
Hi
Versuchst du eine Soft - UART zu programmieren ? Es ist ja ok, wenn man
schnelle Signale per ISR erfasst, aber innerhalb einer ISR warten macht
keinen Sinn. Stell dir vor, du erkennst in der ISR einen Flankenwechsel.
Wie lange dauert es, bis der nächst eintrifft ? Hast du genug zeit, so
setze dit in der ISR ein Flag und verlasse diese. Es braucht nur die
Push und Pop's für die verwendeten Register sowie für's Statusregister.
Das Haupprogramm hat nun die Aufgabe, die Signalauswertung zu
übernehmen. Da braucht aber nix gepusht und gepoppt zu werden.
Bspl. einer beliebigen ISR
1
X_ISR:
2
Push Temp
3
In Temp, SReg
4
Push Temp
5
LDS Temp, Flags
6
Or Temp, 0b00000001
7
STS Flags, Temp
8
POP Temp
9
Out SREG, Temp
10
POP Temp
11
RETI
Wie du siehst, wird nur ein Bit un eine Variable "Flags" geschrieben....
Im Hauptprogramm kannst du nun dieses Bit abfragen und in ein
Unterprogramm verzweigen:
1
Main:
2
....
3
LDS Temp, Flags
4
Andi Temp, 0b00000001
5
BREQ Next
6
RCALL Meine_Reaktion_Auf_ISR
7
Next:
8
....
9
RJmp Main
10
11
Meine_Reaktion_auf_ISR:
12
....
13
....
14
RET
Vielleicht hilft dir dieses kleine Beispiel.
Gruß oldmax
ich verstehe leider nicht wie du das meinst.
Die Zeit zwischen den Flankenwechsel ist unterschiedlich lang und ich
muss zeitweise mit 3 Werten "gleichzeitig" arbeiten.
Mit UART hat das erstmal noch garnichts zu tun (habe den nur zur
Fehlersuche mit konfiguriert).
Ansonsten läuft das Programm ja so das es in den Interrupt geht und dann
das Unterprogramm startet wo es Programm dann weiter läuft.
Ich kann gerne wie ihr meint so machen das ich nach jedem Empfangenen
Bit wieder in das Hauptprogramm springe, müsste dann aber wissen wie ich
einen Abbruch des Datenstranges (z.B. bei Abziehen der Tastatur)
erkennen kann.
Michael Dierken schrieb:> ich verstehe leider nicht wie du das meinst.
wenn wir das richtig sehen liefert deine Tastatur (PS2??) ein serielles
Datenpaket. Du kannst dazu den UART deines AVR nutzen (in der syncronen
Betriebsart).
Sascha