-         

Ergebnis 1 bis 3 von 3

Thema: Timerproblem

  1. #1
    Erfahrener Benutzer Begeisterter Techniker Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    41
    Beiträge
    398

    Timerproblem

    Anzeige

    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

  2. #2
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    27
    Beiträge
    3.517
    Blog-Einträge
    9
    Hi,

    also generell kannst du in einer ISR alles machen was du willst. Bei der ISR passiert ja nichts anderes als das ein Interruptbit gesetzt wird und dadurch springt der Programmzähler zu einer Vektoradresse die für diese Interruptquelle deffiniert ist und an dieser Vektoradresse steht dann ein Sprungbefehl zu der Startadresse deiner eigentlichen ISR wo dann der Code steht.
    Klar kannst du dann in einer ISR einen anderen Timer starten oder den Timer der die ISR verändert hat "bearbeiten".
    Die Timer kannst du generell immer "bearbeiten". Das ist nicht so das die dann keine Änderungen zulassen
    Nur eventuell treten diese Änderungen dann nicht sofort in Kraft.
    Und du kannst in einer Timer-ISR auch den Timer stoppen der diese ISR ausgelöst hat (z.B. wenn du einen Puls messen willst machst du das auch so. Bei der steigenden Flanke wird eine ISR abgearbeitet wo ein Timer gestartet wird und bei einer fallenden Flanke wird der Timer gestoppt und dann hast du die Zeit wie lange der Impuls High war).
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  3. #3
    Erfahrener Benutzer Begeisterter Techniker Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    41
    Beiträge
    398
    Danke Daniel!

Ähnliche Themen

  1. DS1820 CRC-Fehler - Timerproblem?
    Von goof1980 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 17.06.2008, 17:41
  2. Timerproblem (Phasenanschnitt)
    Von dansteu im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 02.11.2006, 18:36
  3. ATMega32 Timerproblem
    Von michaelF im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 24.01.2006, 22:36
  4. Timerproblem TIFR
    Von Lektor im Forum AVR Hardwarethemen
    Antworten: 1
    Letzter Beitrag: 23.04.2005, 09:21

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •