Atmel AVR: Vergangene Zeit messen



  • Hi,
    ich möchte gerne beim Atmel AVR Atxmega 32A4U messen, wieviel Zeit zwischen zwei Punkten vergangen ist.

    Mein Ansatz ist folgender:

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <stdio.h>
    
    #define F_CPU 2000000UL     
    
    static volatile uint8_t overflow_counter = 0;
    static const periode_value = 0xFFFF;
    
    ISR(TCC0_OVF_vect)
    {
    	overflow_counter++;
    }
    
    static uint16_t get_system_clock() {
    	if (CLK.CTRL == CLK_SCLKSEL_RC2M_gc) {
    		return 2000000;
    	} else if (CLK.CTRL == CLK_SCLKSEL_RC32M_gc) {
    		return 32000000;
    	} else if (CLK.CTRL == CLK_SCLKSEL_RC32K_gc) {
    		return 32000;
    	} else {
    		// Unsupported. Please extend this function...
    		exit(1);
    	}
    }
    
    static uint16_t get_division_factor_of_TCC0() {
    	if (TCC0.CTRLA == TC_CLKSEL_DIV1_gc) {
    		return 1;
    	} else if (TCC0.CTRLA == TC_CLKSEL_DIV2_gc) {
    		return 2;
    	} else if (TCC0.CTRLA == TC_CLKSEL_DIV8_gc) {
    		return 8;
    	} else if (TCC0.CTRLA == TC_CLKSEL_DIV64_gc) {
    		return 64;
    	} else if (TCC0.CTRLA == TC_CLKSEL_DIV256_gc) {
    		return 256;
    	} else if (TCC0.CTRLA == TC_CLKSEL_DIV1024_gc) {
    		return 1024;
    	} else {
    		// Unsupported. Please extend this function...
    		exit(1);
    	}
    }
    
    static double get_elapsed_time(uint16_t start, uint16_t end) {
    	if (overflow_counter > 0) {
    		// An overflow occurred before. Return 0xFFFF, which shall indicate, that it can't be measured how much time has been elapsed.
    		overflow_counter = 0;
    		return 0xFFFF;
    	}
    
    	double time_per_clock_cycle = 1.0 / get_system_clock() / get_division_factor_of_TCC0();
    	double time_diff = end - start;
    	double elapsed_time = time_per_clock_cycle * time_diff;
    
    	return elapsed_time;
    }
    
    int main(void)
    {
    	PMIC_CTRL = PMIC_LOLVLEN_bm; /* LOW LEVEL Interrupt on */
    	TCC0.CTRLA = TC_CLKSEL_DIV8_gc;
    	TCC0.INTCTRLA = TC_OVFINTLVL_LO_gc;
    	TCC0.PER = periode_value;
    	TCC0.INTFLAGS = TC0_OVFIF_bm;
    
    	sei();
    	uint16_t start = TCC0_CNT;
    	_delay_ms(200);
    	uint16_t end = TCC0_CNT;
    
    	double ellapsed_time = get_elapsed_time(start, end);
    
        while(1)
        {
            //TODO:: Please write your application code 
        }
    }
    

    Um meine Funktion zu testen, habe ich ein Delay von 200 ms eingebaut. Leider kommt beim Debuggen immer 0,09213223 sek raus.
    Mache ich irgendetwas falsch?!

    L. G.
    Steffo



  • Hast du die Optimierung eingeschaltet?
    Ist der CPU-Takt wirklich nur 2 MHz ?

    Du kannst ja mal bei denen vorbei schaue, die sich damit auskennen: http://www.mikrocontroller.net/



  • Optimierung ist an und der Takt liegt wirklich bei 2 MHz. 😞

    EDIT: Habe jetzt mal mein Problem bei Mikrocontroller.net gepostet. Mal gucken, was die dazu sagen...


Log in to reply