Forum: Mikrocontroller und Digitale Elektronik ARM7_LPC2368: Timer Interrupt zurücksetzen


von D. S. (forack)


Lesenswert?

Hi!

Hab wie gesagt nen LPC2368 & nen Timer0_INT ausgelöst. In die ISR geht 
er, aber den Interrupt rücksetzen tut er nicht.

meine ISR:

void isr_TIMER0_INT (void) __irq {
T0IR = 1;

// code

VICVectAddr = 0;
}

Das T0IR=1 sollte den Interrupt doch so zurücksetzen, oda?

von mario (Gast)


Lesenswert?

Welchen Interrupt löst Du denn aus? Du hast 8 zur Auswahl:

0 MR0 Interrupt Interrupt flag for match channel 0.
1 MR1 Interrupt Interrupt flag for match channel 1.
2 MR2 Interrupt Interrupt flag for match channel 2.
3 MR3 Interrupt Interrupt flag for match channel 3.
4 CR0 Interrupt Interrupt flag for capture channel 0 event.
5 CR1 Interrupt Interrupt flag for capture channel 1 event.
6 CR2 Interrupt Interrupt flag for capture channel 2 event.
7 CR3 Interrupt Interrupt flag for capture channel 3 event.

Wenn Du timer-0-match-0 meinst dann müsste das eigentlich gehen.

von D. S. (forack)


Lesenswert?

mario wrote:
> Welchen Interrupt löst Du denn aus? Du hast 8 zur Auswahl:
>
> 0 MR0 Interrupt Interrupt flag for match channel 0.
>
> Wenn Du timer-0-match-0 meinst dann müsste das eigentlich gehen.

Stimmt, hätte man dazu scheiben können. Also genau den. Den 
Timer0_Match0.

Schreib das so rein wie oben beschrieben, aber der Interrupt wird im 
Debuggen beim passieren der Zeile T0IR = 1; nicht zurückgesetzt & neu 
reingehen tut er in die ISR auch net .....

Hab ich da was vergessen, oder was nicht berücksichtigt ???

edit:
bei T0IR = 0x01 << 0;
ist er genau so stur ....

von mario (Gast)


Lesenswert?

Die Interrupt-Routine wird es nicht sein. Ich vermute mal, dass der 
Interrupt immer wieder ausgelöst wird. Poste mal die Initialisierung.

von D. (Gast)


Lesenswert?

irq_channel = TIMER0 = 4
priority = 8 (aber hier unwichtig )
(*irq_handler) = isr_TIMER0_INT


void IRQ_INIT ( int irqChanel, int priority, void (*irqHandler) (void) 
__irq )
{
  volatile unsigned long * irqVectorPtr = (unsigned long
(VIC_BASE_ADDR + 0x100);    /* Basisadresse der Interrupt Tabelle */
  volatile unsigned long * irqVectorCntPtr = (unsigned long*) 
(VIC_BASE_ADDR + 0x200);

  irqVectorPtr += irqChanel;
  *irqVectorPtr = (unsigned long) irqHandler;

  irqVectorCntPtr += irqChanel;
  *irqVectorCntPtr = priority;



}

von D. S. (forack)


Lesenswert?

mario wrote:
> Die Interrupt-Routine wird es nicht sein. Ich vermute mal, dass der
> Interrupt immer wieder ausgelöst wird. Poste mal die Initialisierung.

uups... war gar net eingeloggt ....
aber ebarbeiten kann man die textform ja leider trotzdem nicht ... :(

irqChanel = Timer0 = 4
priority = 8
(*irqHandler) = isr_TIMER0_INT
1
void IRQ_INIT ( int irqChanel, int priority, void (*irqHandler) (void) __irq )
2
{
3
  volatile unsigned long * irqVectorPtr = (unsigned long*) (VIC_BASE_ADDR + 0x100);    /* Basisadresse der Interrupt Tabelle */
4
  volatile unsigned long * irqVectorCntPtr = (unsigned long*) (VIC_BASE_ADDR + 0x200);
5
6
  irqVectorPtr += irqChanel;
7
  *irqVectorPtr = (unsigned long) irqHandler;
8
9
  irqVectorCntPtr += irqChanel;
10
  *irqVectorCntPtr = priority;    
11
  
12
}

oder meintest die vom Timer ???

die ist:
1
case TIMER_0 :
2
          TIMER0_PERIPHER_ON; //#define  TIMER0_PERIPHER_ON      PCONP |= 0x2
3
          T0PR = prescale_value;                  /* PRESCALE-Wert in PR-Register schreiben */      
4
5
          /* ---------------------------------------------------------------------*/
6
          /*             T I M E R _ 0  ---  M O D E - S E L E C T                */
7
          /*             wählt zwischen Timer oder Capture - Mode          */
8
          /*                           A N F A N G                                */
9
          /*----------------------------------------------------------------------*/
10
          switch ( mode_select ) {
11
            
12
              case TIMER_MODE :                
13
                  T0CTCR =  0 << 0 ;                
14
              break;
15
switch ( match_register ) {
16
              
17
              // MATCH - Register - 0
18
              case MR0 :                         
19
                  T0MR0 = match_value;            // Timer-Wert wird in Match-Register schreiben
20
                  
21
                    if ( interrupt == TRUE )        // Interrupt wird ausgelöst, falls TC == MR 
22
                      T0MCR |= 0x1 ;
23
                  
24
                    else               
25
                      T0MCR |= ( T0MCR & 0xFFFFFFFE );
26
                    
27
                    
28
                    if ( TC_Reset == TRUE )          //   TC - Reset, wenn TC == MR 
29
                      T0MCR |= 0x2 ;
30
                    
31
                    else
32
                      T0MCR |= ( T0MCR & 0xFFFFFFFD ); 
33
                      
34
                    
35
                    if ( stop == TRUE )            // Timer STOP, wenn TC == MR
36
                      T0MCR |= 0x3;
37
                    
38
                    else
39
                      T0MCR |= ( T0MCR & 0xFFFFFFFB );                
40
                  
41
              break;

von mario (Gast)


Lesenswert?

Da finde ich keinen Fehler, aber das ist ja nicht die gesamte 
Initialisierung von Timer0.
Mach mal folgendes:

void isr_TIMER0_INT (void) __irq {
T0IR = 1;

// code
T0MCR = 0; // Interrupt-Auslösung löschen !!!

VICVectAddr = 0;
}

und schau mal, ob das T0IR(0)-Bit nun gelöscht wurde.

von D. S. (forack)


Lesenswert?

mario wrote:
> Da finde ich keinen Fehler, aber das ist ja nicht die gesamte
> Initialisierung von Timer0.
> Mach mal folgendes:
>
> void isr_TIMER0_INT (void) __irq {
> T0IR = 1;
>
> // code
> T0MCR = 0; // Interrupt-Auslösung löschen !!!
>
> VICVectAddr = 0;
> }
>
> und schau mal, ob das T0IR(0)-Bit nun gelöscht wurde.

Was fehlt deiner Meinung nach bei der Ini zum Timer noch ??? Hoff' nix 
vergessen zu haben.

Das T0MCR = 0 macht den Interrupt auch net rückgängig. Habs getestet.
Sagt dem ja auch nur, dass das feature enabled ist & nicht, das es 
wirklich eingetreten ist.
Macht das ganze T0MCR Register 0 ... :D

so ne' sch..... habs auch beim MR1 ausprobiert .... setzt er auch net 
zurück ... ich probiers mal noch mit nem anderen Timer ....

von mario (Gast)


Lesenswert?

> Macht das ganze T0MCR Register 0 ... :D
Das war Absicht.

bei mir sieht das so aus:
void Timer0Handler(void)
{
  T0IR = 1;      // clear interrupt flag

//bla

  VICVectAddr = 0x00000000;  // clear this interrupt from the VIC
}

void init_timer0 ( uint32_t TimerInterval_Hz )
{
  T0TCR = TxTCR_Counter_Reset;        // reset & disable timer 0
  T0MR0 = (PCLK/TimerInterval_Hz)-1;
  T0MCR = TxMCR_MR0I|TxMCR_MR0R;  // Interrupt and Reset on MR0

  VICIntSelect &= ~(VIC_CHAN_TO_MASK(VIC_CHAN_NUM_Timer0));
  VICIntEnClr  = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_Timer0);
  VICVectAddr4 = (uint32_t)Timer0Handler;
  VICVectPriority4 = INT_PRIORITY_TIMER0;
  VICIntEnable = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_Timer0);
  T0IR  = TxIR_MR0_Interrupt;     // clear match0 interrupt
  T0TCR = TxTCR_Counter_Enable;       // enable timer 0

}

Vielleicht ist auch das IC defekt!? :O(

von D. S. (forack)


Lesenswert?

mario wrote:
>> Macht das ganze T0MCR Register 0 ... :D
> Das war Absicht.
Jo. Dacht ich mir schon ... :)



>   VICIntEnClr  = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_Timer0);
Da sollte doch dann VICIntEnClr = 0x10; stehen, ne?
Also das die Software den 0x10 (bit4 Timer0) zurücksetzen darf.
Das hab ich jetzt mal (hoffnungsvoll) vor das T0IR = 1 geschrieben, aber 
das wars nicht.


> Vielleicht ist auch das IC defekt!? :O(
Genau! :D ...
Wäre ja mal schon krazz ... Aber dann kann man's wenigstens wieder auf 
die Holländer schieben ... ;)

Schätz, ich werd dann morgen mal bei Keil anrufen u. schauen was die 
dazu sagen ....

Dank dir !

von D. S. (forack)


Lesenswert?

Also es geht.

Nur T0IR = 1 MUSS ganz am Ende der isr stehen.
Warum auch immer ....

Wer zufällig ne Erklärung dazu ??

Weil in einer ISR setzt man doch zu allererst den Interrupt zurück & 
dann geht's weiter. So hab ichs zumindest gelernt & auch immer so 
angewendet .....

Ergo:

Funktioniert NICHT:
1
 void isr_TIMER0_INT (void) __irq {
2
 T0IR = 1;
3
 // code
4
 VICVectAddr = 0;
5
 }

------------------------------------
Funktioniert:
1
 void isr_TIMER0_INT (void) __irq { 
2
 // code
3
 VICVectAddr = 0;
4
 T0IR = 1;
5
 }

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.