ich kann zwar kein C aber überleg dir ma folgendes:
WENN (PORTX=1) THEN
TimerStart
ENDIF
und in den overflow vom timer dann halt wen porty ein high bekommt
denke mal
Hallo,
also, ich habe 2 Taster, T1 und T2. Wenn ich auf T1 drücke soll der AVR anfangen die Zeit zu stoppen bis T2 gedrückt wird (auf 0.01 sek genau wenn es so genau geht ).
Wie programmiere ich sowas am besten?
Da ich noch nicht lage mit AVRs arbeite hab ich da keine Idee wie ich das machen könnte...
Viele Grüße,
Johannes
ich kann zwar kein C aber überleg dir ma folgendes:
WENN (PORTX=1) THEN
TimerStart
ENDIF
und in den overflow vom timer dann halt wen porty ein high bekommt
denke mal
Hm, an Timer habe ich auch schon gedacht, aber ich weiß leider nicht, wie die genau funktionieren, bzw. wie ich die mit C starte/stoppe etc...
16Bit Timer verwenden.
Dann zwei Interruptroutinen:
Die erste für die Tastendrücke. Wenn die T0 gedrückt wird, werden die Ergebnisregister und das Timerregister zurück gesetzt. Wenn T1 gedrückt wird, wird auf das Ergebnis der aktuelle Timerwert aufaddiert und in eine andere Variable weggeschrieben.
Die zweite Reagiert auf einen Timerüberlauf und zählt das Ergebnissregister hoch.
Bei einem Mega168 kommt man so auf eine Genauigkeit von
ca. 1/20MHz/8 (wegen Verzögerungen in den Interruptroutinen, max. 8 Takte zum Interruptvektor ausführen und Timerregister lesen) und einen Zählbereich von 65536/20Mhz * 32bit = 14073748,8355328s also ca. 3909 Stunden.
Die genaue Funktion der Timer kannst Du in den Datenblättern von Atmel nachlesen. Da gibt es meistens auch Beispiele in C
Ok, dann fang ich als erstes mit den Interrupts an.
Ich wollte an INT0 und INT1 je einen Taster anschließen... Brauche ich da Pullups/Pulldowns?
Im Datenblatt vom AVR (mega hab ich aber kein Beispiel gefunden, wie ich das dann genau programmieren muss, kann mir da bitte jemand mal ein Beispiel zeigen?
Viele Grüße,
Johannes
Ja, am einfachsten:
Einen Pullup von 10k und einen Kondensator 47n nach Masse. Den Taster vom Pin ebenfalls nach Masse. So ist die Taste entprellt und Du sparst Dir das Entprellen in Software.
Die Konfiguration ist dann für den INT0 bzw. INT1 "Interrupt on falling edge"
Es gibt Beispiele für die Interruptprogrammierung in den AVR GCC Turtorials hier im Wiki oder auf mikrocontroller.net
Etwas einfacher geht's hier, weil du 2 verschiedene Taster hast auf denen je nur eine Funktion liegt: zu Entprellen brauchst du eigentlich nicht (schon garnicht bei einer Auflösung von 10ms).
Die internen PullUps aktivieren und die Taster vom jeweiligen Port nach Masse.
Falls der Start-Taster kurz prellt, wirst du den Timer zweimal oder öfter kurz hintereinander starten, was aber nicht weiter stören sollte.
Falls du entprellen willst geht das auch einfach dadurch, daß du in INT0 (Start) den INT0 deaktivierst und INT1 (Ende) aktivierst. Und erst in INT1 wird INT0 wieder aktiviert und INT1 deaktiviert.
Disclaimer: none. Sue me.
Stimmt, elegante Lösung, das spart ein paar Bauteile.
Hallo,
ich bekomme das mit den Interrupts nicht ganz hin, hier mal der Code:
Aber wenn ich INT0 mit VCC verbinde passiert gar nix...Code:#define F_CPU 16000000 #include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> #include "usart.c" ISR(INT0_vect) { usart_print("INT0\n"); } int main() { usart_init(); sei(); usart_print("Warte auf Interrupt...\n"); while(1) ; }
Viele Grüße,
Johannes
Es geht aber ohne weiteres auch genauer. Nachdem der Interrupt des ersten Tasters ausgelöst wurde, wird dierser sofort deaktiviert und der Interrupt des zweiten Tasters enabled. Ein Nachprellen auf dem ersten Taster löst somit keine Interruptroutine mehr aus.Falls der Start-Taster kurz prellt, wirst du den Timer zweimal oder öfter kurz hintereinander starten, was aber nicht weiter stören sollte.
MFG Moritz
www.free-webspace.biz/update
Lesezeichen