Hallo Zusammen,
ich habe mit meinem ATMEL-ARM9 (at91sam) ein TimerInterrupt Problem. Ich
brauche einen Timer, der mir einen Takt einer bestimmten Frequenz
vorgibt. Die Taktung funktioniert schon. Jedoch habe ich das Problem,
dass eine globale Variable isr_state immer 0 bleibt, obwohl ich
isr_state in der ISR explizit auf 1 setze. Zu erkennen ist dies durch
die Ausgabe von isr_state im Interrupt.
Hier ist mein Code. Er ist übernommen und ein wenig modifiziert von der
ATMEL Seite.
Vielleicht hat einer von Euch einen Tipp und kann mir weiterhelfen.
1 | #include <aic/aic.h>
|
2 | #include <tc/tc.h>
|
3 |
|
4 | volatile unsigned int isr_state = 0;
|
5 |
|
6 | //------------------------------------------------------------------------------
|
7 | /// Interrupt handler for TC0 interrupt.
|
8 | //------------------------------------------------------------------------------
|
9 | void ISR_TC0(void)
|
10 | {
|
11 | // Setze isr_state und gebe isr_state aus
|
12 | isr_state = 1;
|
13 | printf("iTick mit %i", isr_state);
|
14 |
|
15 | // Clear status bit to acknowledge interrupt
|
16 | AT91C_BASE_TC0->TC_SR;
|
17 | }
|
18 |
|
19 |
|
20 | //------------------------------------------------------------------------------
|
21 | /// Configure Timer Counter 0 to generate an with specific frequency
|
22 | //------------------------------------------------------------------------------
|
23 | void ConfigureTC(unsigned int freq)
|
24 | {
|
25 | unsigned int div;
|
26 | unsigned int tcclks;
|
27 |
|
28 | // Enable peripheral clock
|
29 | AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC0;
|
30 |
|
31 | // Configure TC for a 4Hz frequency and trigger on RC compare
|
32 | TC_FindMckDivisor(freq, BOARD_MCK, &div, &tcclks);
|
33 | TC_Configure(AT91C_BASE_TC0, tcclks | AT91C_TC_CPCTRG);
|
34 | AT91C_BASE_TC0->TC_RC = (BOARD_MCK / div) / freq; // timerFreq / desiredFreq
|
35 |
|
36 | // Configure and enable interrupt on RC compare
|
37 | AIC_ConfigureIT(AT91C_ID_TC0, AT91C_AIC_PRIOR_LOWEST, ISR_TC0);
|
38 | AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
|
39 | AIC_EnableIT(AT91C_ID_TC0);
|
40 | }
|
Und dann in der Funktion, wo ich den Timer benötige:
1 | void TimerFunction(unsigned int freq, unsigned int loops)
|
2 | {
|
3 | int i;
|
4 |
|
5 | // Inititalisierung des Timers
|
6 | ConfigureTC(freq);
|
7 |
|
8 | isr_state = 0;
|
9 | // Start des Timers
|
10 | TC_Start(AT91C_BASE_TC0);
|
11 |
|
12 |
|
13 | for(i=0;i<loops;i++)
|
14 | {
|
15 | while (isr_state == 0)
|
16 | {
|
17 | // Warten bis Interrupt ausgelöst wurde
|
18 | }
|
19 | isr_state = 0; // Rücksetzen des Status
|
20 | printf("Tick"); // Meldung
|
21 | }
|
22 |
|
23 | // Stopp des Timers
|
24 | TC_Stop(AT91C_BASE_TC0);
|
25 | }
|