Forum: Mikrocontroller und Digitale Elektronik Ping mit ATMega8 erzeugen


von Stefan654 (Gast)


Angehängte Dateien:

Lesenswert?

Hi zusammen,

ich generiere mit meinem ATMega8 auf nem STK500 Board einen 40kHz Takt, 
10 Perioden lang "zu Fuß".
Funktioniert auch wunderbar. Allerdings ist mein erster Highpegel 64us 
lang, anstatt den geforderten 12,5us. Nach dem ersten Highpegel, also ab 
dem ersten Lowpegel, stimmts. Ich setze aber definitiv einen Startwert 
im TCNT0=216 (rechnerisch 206 bei 4MHz, praktisch passt aber 216)

Wenn man nun die 64us zurück rechnet, gehe ich davon aus, dass er den 
Startwert beim ersten Impuls nicht verwendet (also 4MHz/256 = 64us). 
Wäre ein sehr großer Zufall, wenns ein anderes Problem wäre.
Wenn ich das Prog im AVR Studio simuliere, funktioniert es auch 
einwandfrei!

Ich poste mal den Code in ASM im Anhang, etwas durcheinander momentan, 
aber ich hab auch etwas "rumgetestet", sollte aber selbsterklärend sein.

Hoffe jemand kann mir helfen. Bin nämlich so ein bisschen am irre werden 
grade.....

Danke
Stefan

von Karl H. (kbuchegg)


Lesenswert?

Der Aufruf einer Interrupt-Funktion ist technisch gesehen ein rcall, nur 
dass ihn die Hardware auslöst.
Um aus einer Interrupt Funktion auszusteigen, wird daher ein reti 
gemacht und kein rjmp zu irgendeinem Label. Das macht ja auch im 
Allgemeinen Sinn, denn du weisst ja nicht, welcher Programmteil gerade 
durch den Interrupt unterbrochen wurde, willst aber haben, dass es genau 
an dieser Stelle wieder weiter geht.
Dazu muss aber auch der Stackpointer initialisiert werden!
Und das sei am Ende der Interrupt Funktion kannst (sollst) du dir auch 
sparen. Das erledigt der reti aus gutem Grund gleich mit.

> Ich setze aber definitiv einen Startwert
> im TCNT0=216

Beim allerersten mal. Ja
Wenn aber deine Sequenz einmal durchgelaufen ist, wird an der Stelle 
ENDE kein neuer Wert gesetzt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Deine Interruptbehandlung ist, nun sagen wir mal: aussergewöhnlich...

Üblich wäre ein Rücksprung mit reti.
Sieh dir doch mal andere Programme an, wie es dort gemacht wird.

EDIT:
Na gut, Zweiter... ;-)

von Stefan654 (Gast)


Lesenswert?

> Beim allerersten mal. Ja
> Wenn aber deine Sequenz einmal durchgelaufen ist, wird an der Stelle
> ENDE kein neuer Wert gesetzt.

Mmmmhhhh ok vielen Dank. War ich einfach nur dämlich.....

Ja die Interrupts...^^ Ich weiß, dass es "ungewöhnlich" ist, aber bei 
meinem kurzen Prog weiß ich ja immer genau, an welcher Stelle und zu 
welchem Zeitpunkt welcher Interrupt kommt. Von daher kann eigentlich 
nicht viel schief gehen. Ich werd das ganze aber natürlich noch umbauen

Also vielen Dank für die schnelle und ausführliche Hilfe! Vorbildlich!

Gruß
Stefan

von Karl H. (kbuchegg)


Lesenswert?

Stefan654 wrote:
> Ja die Interrupts...^^ Ich weiß, dass es "ungewöhnlich" ist, aber bei
> meinem kurzen Prog weiß ich ja immer genau, an welcher Stelle und zu
> welchem Zeitpunkt welcher Interrupt kommt. Von daher kann eigentlich
> nicht viel schief gehen.

Doch.
Kann es und wird es.

Dass du mit einem rjmp zurück zur Hauptschleife gehst, interessiert die 
Hardware herzlich wenig. Die legt fleissig bei jedem Interrupt die 
Returnadresse auf dem Stack ab. Und das macht sie, und macht sie und 
macht sie ... bis dann irgendwann der Stack in eine SRAM Sektion 
gewandert ist, in der deine Variablen liegen.
Dumm gelaufen

> Ich werd das ganze aber natürlich noch umbauen
Nicht im nachhinein umbauen. Gleich richtig schreiben.
reti sschreibt sich doch auch viel schneller als /sei   rjmp .../

von Stefan654 (Gast)


Angehängte Dateien:

Lesenswert?

Ok, habs nu nochmal abgeändert und wieder dazu gebracht, dass zu machen, 
was ich will.
Ob es nun der "Norm" entspricht, ist die andere Frage. Aber dazu werdet 
ihr mir bestimmt was sagen ;)
Mit Sicherheit ist das alles nicht elegant, bin aber auch erstmal auf 
Funktion aus.

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
Noch kein Account? Hier anmelden.