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

Code:
OCR0A = x-1;	TIMSK0 |= (1 << OCIE0A);
Die Timer0 ISR macht ihre Aktion und soll dann sich selbst wieder stoppen mit

Code:
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?

Der Atmega168 läuft mit 16 MHz.

Hier ist mein Code:
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();
		}
	}
}
Gruß
Georg