Member since Jun 2014
1 post
|
![]()
Subject: Interrupts, Nebenläufigkeit
Hallo,
ich habe zwei Fragen hinsichtlich der Übung zu den Interrupts (Ampel), zumal ich die Übung und die Abgabe leider verpasst habe. Zunächst verstehe ich nicht, warum die Interrupts in der letzten while-Schleife des unten angehängten Programm-Ausschnitts nicht ausgelöst werden. Zusätzlich wollte ich fragen, ob die Interruptbehandlungen, so wie sie implementiert wurden, sinnvoll sind. War das Timer-Programm so gedacht (ich habe die Aussage: Die Callbackfunktion des Timer modules wird aus dem Interrupt-Kontext aufgerufen nicht ganz verstanden). Ist der Tastendruckinterrupt sinnvoll implementiert, mit der Abfrage hinsichtlich des Canceln des Timers? Ich habe keine andere Möglichkeit gesehen, Nebenläufigkeitsprobleme zu vermeinden. Eine andere Möglichkeit wäre gewesen, das Canceln des Timers außerhalb der Interruptbehandlung zu machen, aber dann bekommt man meines Erachtens nach Nebenläufigkeitsprobleme. /*-------------------------------------------------------------------------------------------------------*/ #include <avr/sleep.h> #include <avr/interrupt.h> #include <avr/io.h> #include <timer.h> #include <7seg.h> #include <led.h> volatile static uint8_t INT_event = 0; // volatile nötig volatile static uint8_t TIM_event = 0; // volatile nötig static uint8_t INT_TIM_event = 0; // volatile nicht nötig, wird einfach bei Timer ein gesetzt und muß nicht jeweils neu geladen werden static ALARM *ALARM_Vec; /* Interruptausführung definieren */ ISR (INT0_vect) { // Interrupt für PD2 if (INT_TIM_event) { sb_timer_cancelAlarm(ALARM_Vec); } INT_event = 1; } void T1_Int_func(void) { TIM_event = 1; } // Timer-Interrupt-Behandlung, sollte man noch static machen, und in der Callfunction casten... /* Programmstart */ void main(void) { set_sleep_mode(SLEEP_MODE_IDLE); // Sleep Modes: Idle sleep_enable(); // Sleep-Modus aktivieren /* Init: PortD konfigurieren, Interrupt für PortD scharf schalten*/ DDRD &= ~(1 << PD2); // PD2 als Eingang nutzen... PORTD |= (1 << PD2); // pull-up-Widerstand aktivieren MCUCR |= (1<<ISC00); // ISC00 nullen ISC01 ISC00 S.70 Manual: MCUCR |= (1<<ISC01); // ISC01 1-setzen 1 0 falling edge while(1){ GICR |= (1<< INT0); // demaskiere=enable INT0<->PD2 sb_led_on(GREEN0); sb_led_on(RED1); sei(); ALARM_Vec = sb_timer_setAlarm ( T1_Int_func, 5000, 0 ); sb_timer_cancelAlarm(ALARM_Vec); INT_TIM_event = 1; cli(); while(~INT_event && ~TIM_event) { // das hier nur als Beispiel, weder Tastendruck noch Ablauf des Timers haben Effekt sei(); sleep_cpu(); } INT_event = TIM_event = INT_TIM_event = 0; sb_led_off(GREEN0); sb_led_off(RED1); // zum Testen ob die Interrupts tatsächlich ausgelöst werden } } |
Member since May 2011
109 posts
|
![]()
Hi
Das geht schon mal nicht. Du setzt grad das Bit auf 1. Dann ist es nicht falling edge was den Interrupt auslöst. Geht sowas überhaupt?? WAs mir noch aufällt: Du schaltest die LEDs aus, dann spingt die While an den Anfang, wo die LEDs sofort wieder angeschaltet werden. Mach mal irgendeine Warteoperation rein, um den Schaltvorgang sichtbar zu machen. Ohen Warten ist das zu schnell fürs Auge - und du meinst dann dass der Vorgang nie ausgeführt wird. |
Member since Feb 2011
239 posts
|
![]()
Mich macht das ~ in
while (~INT_event && ~TIM_event) stutzig. Ist dir der Unterschied zwischen bitweisem und logischem Nicht, also zwischen ~x und !x bewusst?In C wird alles, was nicht 0 ist, als "true" gewertet. Denkaufgabe: Bei INT_event=1, welchen Wert ergibt ~INT_event (Bits hinschreiben)? Ist dieser Wert logisch true oder false? Wie ist es bei INT_event=0? Ist das das gewünschte Verhalten? Wie verändert sich das Verhalten, wenn man statt ~ hier ! verwendet? |
Powered by the Unclassified NewsBoard software, 20110527-dev,
© 2003-8 by Yves Goergen