Hallo zusammen!
Momentan erzeugen meine 3 Timer konstant IRQs. Das funktioniert auch im CTC Mode.
Das Problem: Jetzt möchte ich aber in der ISR des Timer1 den Timer0 bzw Timer 2 starten. Diese sollen "Singleshot" Timer sein. Bisher habe ich diese am Anfang vor der while(1) Schleife Prescale etc initialisiert. um jetzt den Timer zu starten, setze ich jetzt in der Timer1 ISR
Die Timer0 ISR macht ihre Aktion und soll dann sich selbst wieder stoppen mitCode:OCR0A = x-1; TIMSK0 |= (1 << OCIE0A);
Geht das prinzipell oder ist das unmöglich dass der Atmega168 in einer TimerISR einen anderen Timer startet? Bzw seine "eigenen" IRQ register beschreibt?Code:TIMSK0 &= ~(1 << OCIE0A);
Der Atmega168 läuft mit 16 MHz.
Hier ist mein Code:
GrußCode:#include <stdlib.h> #include <stdint.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <util/delay.h> #include "i2cmaster.h" #include "uart.h" // ----------------------------------------------------- // defines for better readability // ----------------------------------------------------- // Leds #define led_alive_on() (PORTC |= (1<<PC0)) #define led_alive_off() (PORTC &= ~(1<<PC0)) // timer #define start_timer0(x) { OCR0A = x-1; TIMSK0 |= (1 << OCIE0A);} #define start_timer2(x) { OCR2A = x-1; TIMSK2 |= (1 << OCIE2A);} #define stop_timer0() (TIMSK0 &= ~(1 << OCIE0A)) #define stop_timer2() (TIMSK2 &= ~(1 << OCIE2A)) // EEPROMs #define EEPROM_SERVO_1 0b01010000 #define EEPROM_SERVO_2 0b01010001 // Baud rate #define UART_BAUD_RATE 38400 // ----------------------------------------------------- // global variables // - communication of IRQ routines with main loop // - communication if pin change irqs with impuls generation // ----------------------------------------------------- // status of live led volatile bool b_live_led = false; volatile uint16_t gi_cnt = 0; // ----------------------------------------------------- // io handling // ----------------------------------------------------- void init_io() { DDRB = 0b00000000; // All inputs DDRC = 0b11111111; // All outputs DDRD = 0b11111000; // mixed in-/outputs PORTB = 0b11111001; // set inputs to high PORTC = 0b00000000; // set outputs to low PORTD = 0b00000111; // set inputs to high } // ----------------------------------------------------- // Timer handling // ----------------------------------------------------- void init_timer(void) { // prescalefactor settings is equal at timer 0 and 1. Timer 2 is different // ((16.000.000 MHz / 64) = 250 kHz Prescaleclock; // ---------------------------- // Timer 1 // ---------------------------- TCCR1A = 0; // CTC Mode TCCR1B = ((1<<WGM12) | (1<<CS01) | (1<<CS00)); // prescale factor 64 OCR1A = 2500-1; TIMSK1 |= (1 << OCIE1A); // ---------------------------- // Timer 0 // ---------------------------- TCCR0A = 0; // CTC Mode TCCR0B = ((1<<WGM12) | (1<<CS11) | (1<<CS10)); // prescale factor 64 // ---------------------------- // Timer 2 // ---------------------------- TCCR2A = 0; // CTC Mode TCCR2B = ((1<<WGM12) | (1<<CS22)); // prescale factor 64 } // Timer ISR ISR(TIMER1_COMPA_vect) { // Debug if (++gi_cnt > 100) { led_alive_on(); start_timer0(250); gi_cnt = 0; } } // set servo output off for servo 1 ISR(TIMER0_COMPA_vect) { led_alive_off(); stop_timer0(); #if 0 // regular ISR // set output off for servo 1 servo1_off(); stop_timer0(); #endif } ISR(TIMER2_COMPA_vect) { led_alive_off(); stop_timer0(); return; #if 0 // regular ISR // set output off for servo 2 servo2_off(); stop_timer2(); #endif } // ----------------------------------------------------- // main loop // - handle modes // - handle I2C storage, save and read // ----------------------------------------------------- int main(void) { // io port directions init_io(); // init timer at 1ms rate init_timer(); // init the UART library uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU)); // allow all interrupts sei(); // endless loop while(1) { // check mode switch static uint8_t s_old_mode_switch_status = 0; static uint8_t s_new_mode_switch_status = 0; s_new_mode_switch_status = is_mode_switch_on(); if (s_new_mode_switch_status && !s_old_mode_switch_status) { gb_mode++; if (gb_mode > MODE_REPLAY) gb_mode = MODE_DIRECT; } s_old_mode_switch_status = s_new_mode_switch_status; // mode direct if (gb_mode == MODE_DIRECT) { // leds led_mode_direct_on(); led_mode_capture_off(); led_mode_replay_off(); // only display active led for debug purpose } // mode capture else if (gb_mode == MODE_CAPTURE) { // leds led_mode_direct_off(); led_mode_capture_on(); led_mode_replay_off(); } // mode replay else if (gb_mode == MODE_REPLAY) { // leds led_mode_direct_off(); led_mode_capture_off(); led_mode_replay_on(); } } }
Georg







Zitieren

Lesezeichen