Melde mich nun mit dem nächsten Problem zurück
Timer1 habe ich jetzt glaub ich verstanden. Jetzt habe ich folgenden Code ausprobiert:
An PortB.3 hängt eine LED, welche ganz brav wie im Tutorial im Abstand von einer Sekunde ein- und ausgeknipst wird. Das funktioniert auch ->Der Timer funktioniert an sich. Allerdings will ich die sound(...)-Funktion auch nur eine Sekunde ausführen. Das soll nach einer Sekunde durch das Unwahr-Machen der while-Schleife passieren. Warum funktioniert das nicht? Das Programm soll einfach nur einmal nach einer Sekunde die while-Schleife (und damit auch die sound-Funktion) beenden und die LED an PortB.3 weiterblinken lassen.Code:#include <avr/io.h> #include <avr/signal.h> #include <avr/interrupt.h> #include <avr/delay.h> #define INTERRUPTS_PER_SECOND 1000 int laenge, sound_on; // Wird durch jeden IRQ eins hochgezählt static volatile uint16_t irq_count = 0; // Wert für das OutputCompare-Register (OCR1A) #define OCR_VAL (F_CPU / INTERRUPTS_PER_SECOND -1) // Initialisierung der Hardware void ioinit( void ) { DDRB |= ( 1 << PB3 ); DDRD |= ( 1 << PD6 ); // Initialisiert Timer1, um jede Sekunde 1000 IRQs auszulösen // ATmega: Mode #4 für Timer1 und voller MCU-Takt (Prescale=1) TCCR1A = 0; TCCR1B = ( 1 << WGM12 ) | ( 1 << CS10 ); // OutputCompare1A Register setzen OCR1A = ( uint16_t ) ( ( uint32_t ) OCR_VAL ); // OutputCompare1A Interrupt aktivieren TIMSK |= ( 1 << OCIE1A ); } // Die Interrupt Service Routine (ISR) wird INTERRUPTS_PER_SECOND mal // pro Sekunde ausgeführt. irq_count zählt die Aufrufe und blinkt die LED // wenn 1 Sekunde vergangen ist. SIGNAL( SIG_OUTPUT_COMPARE1A ) { uint16_t count; // irq_count um 1 erhöhen und count = 1+irq_count; if( count >= laenge ) { count = 0; PORTB ^= ( 1 << PB3 ); sound_on = 0; //Sound soll durch die while-Schleife in sound(...) abgeschaltet werden } irq_count = count; } void sound( int length ) { laenge = length; sound_on = 1; while( sound_on != 0 ) //während sound_on = 1 ist, soll irgend eine Frequenz erzeugt werden. sobald sound_on = = ist, soll die Schleife unterbrochen werden. { PORTD ^= ( 1 << PD6 ); _delay_ms( 100 ); sei(); } } // Das Hauptprogramm (Einsprungpunkt) int main( void ) { //Peripherie initialisieren ioinit(); PORTB |= ( 1 << PB3 ); sound( 1000 ); while(1); }
Eigentlich müsste das doch von der Idee her funktionieren? Tut es aber nicht...
u.A.w.g., Manni







Zitieren

Lesezeichen