Forum: Mikrocontroller und Digitale Elektronik [Atmega8] Probleme mit Timer1


von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

Leider sind meine ersten Gehversuche in C nicht sehr von Erfolg gekrönt. 
Ich möchte die PWM eines ADXL-Beschleunigungsensors einlesen. Das hat in 
Assembler auch schon gelungen. Nun das gleiche in C, bitte fragt mich 
nicht warum...
Das Problem ist nun, dass die Timerwerte nur in gewissen Bereichen schön 
mit der Neigung des Sensors ändern. Es gibt aber auch Bereiche wo die 
eingelesenen Timerwerte riesige Sprünge machen obwohl der Sensor nur 
sehr wenig mehr bzw. weniger geneigt wird.
Ein Timerüberlauf ist es nicht, da auch mit grösserem Vorteiler das 
gleiche zu beobachten ist. Auch in Assembler hat es mit prescaler = 1 
funktioniert.
Ist es möglich, dass es an den Variablendeklarationen liegt?
Oder seht ihr sonst irgendwo einen Fehler?

Ich habe noch extra viel Kommentare in den Code geschrieben, in der 
Hoffnung, dass ihr seht was ich da überhaupt machen will. Gerne könnt 
ihr auch den Programmierstil bemängeln, aber lieber erst das Problem 
lösen...

Die Interrupts werden in der Richtigen Reihenfolge ausgeführt und auch 
die Verzweigungen werden schön abwechselnd ausgeführt, das habe ich per 
UART-Ausgabe verifiziert.

Das angehängte File ist nur ein Ausschnitt des Gesamtprogramms, das mit 
dem ADXL zu tun hat. Möglicherweise geht ein copy-paste und compilieren 
nicht reibungslos.

Danke für alle Tipps

von Karl H. (kbuchegg)


Lesenswert?

Tu dir selbst einen Gefallen und schau dir an, wie
man sowas mit einem Input Capture Interrupt richtig
und vor allem wesentlich einfacher löst.


von Stefan (Gast)


Lesenswert?

OK, ich habe mir das (ich gestehe: nur kurz) angeschaut. Dabei gibt es 2 
Probleme:
1. Ich habe die Platine schon geätzt --> Ich konnte notfalls die beiden 
Leitungen unterbrechen und dann zwei Verbindungen einlöten.
2. Muss ich ja die Eingänge ohnehin umschalten, dass er auf low->high 
"captured" und dann wieder auf high->low capture umschalten und dann 
muss ich die beiden Timerwerte die ich einmal für di steigende und 
einmal für die fallende Flanke erhalte subtrahieren. --> Das Programm 
wird nur unwesentlich einfacher (oder sehe ich das falsch?)

Oder habe ich das falsch verstanden?

Danke für die Hilfe

von Karl H. (kbuchegg)


Lesenswert?

> oder sehe ich das falsch

Das Prinzip siehst du schon richtig.
Die Schlussfolgerung kann ich aber nicht teilen.
Ein ICP ist schon um einiges leichter (auch leichter
zu verstehen und nachzuvollziehen) als deine '2 Interrupts
die sich gegenseitig steuern und die Pins unter dem A....
umdefinieren' Lösung.

von Stefan (Gast)


Lesenswert?

OK, du magst das nicht, und ich habs schon auf die andere Seite 
eingespurt ;) Hoffentlich komme ich nicht neben die Fahrbahn...
Im Simulator getestet habe ich bemerkt, dass z.B. INT0 nach INT1 
ausgeführt wird wenn während dem INT0 ein Ereignis eingetreten ist, 
dass ihn auslösen muss. Ich werde mal versuchen mit den Interruptflags 
löschen ein besseres Ergebnis zu erzielen. OK, jetzt wirds definitiv 
unübersichtlich, aber vielleicht funktionierts ja...
Merkwürdigerweise hats in ASM auch ohne dies funktioniert..

von Stefan (Gast)


Lesenswert?

OK, es funktioniert nun, wenn ich am Ende der else-anweisung die 
Interruptflags lösche.

von Sonic (Gast)


Lesenswert?

>Im Simulator getestet habe ich bemerkt, dass z.B. INT0 nach INT1
>ausgeführt wird wenn während dem INT0 ein Ereignis eingetreten ist,

Nicht ganz. Die Liste der Interruptvektoren wird immer von oben nach 
unten mit Priorität abgearbeitet. das heißt, wenn währen der Ausführung 
der INT0-ISR noch ein INT0 auftritt und das Flag gesetzt wird, läuft er 
nach Verlassen der INT0-ISR wieder in dieselbe! Ein anderer INT wird 
dann nie ausgeführt.

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.