mikrocontroller.net

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


Autor: D. S. (forack)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: D. S. (forack)
Datum:

Bewertung
0 lesenswert
nicht 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 ....

Autor: mario (Gast)
Datum:

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

Autor: D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;



}

Autor: D. S. (forack)
Datum:

Bewertung
0 lesenswert
nicht 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
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;    
  
}

oder meintest die vom Timer ???

die ist:
case TIMER_0 :
          TIMER0_PERIPHER_ON; //#define  TIMER0_PERIPHER_ON      PCONP |= 0x2
          T0PR = prescale_value;                  /* PRESCALE-Wert in PR-Register schreiben */      

          /* ---------------------------------------------------------------------*/
          /*             T I M E R _ 0  ---  M O D E - S E L E C T                */
          /*             wählt zwischen Timer oder Capture - Mode          */
          /*                           A N F A N G                                */
          /*----------------------------------------------------------------------*/
          switch ( mode_select ) {
            
              case TIMER_MODE :                
                  T0CTCR =  0 << 0 ;                
              break;
switch ( match_register ) {
              
              // MATCH - Register - 0
              case MR0 :                         
                  T0MR0 = match_value;            // Timer-Wert wird in Match-Register schreiben
                  
                    if ( interrupt == TRUE )        // Interrupt wird ausgelöst, falls TC == MR 
                      T0MCR |= 0x1 ;
                  
                    else               
                      T0MCR |= ( T0MCR & 0xFFFFFFFE );
                    
                    
                    if ( TC_Reset == TRUE )          //   TC - Reset, wenn TC == MR 
                      T0MCR |= 0x2 ;
                    
                    else
                      T0MCR |= ( T0MCR & 0xFFFFFFFD ); 
                      
                    
                    if ( stop == TRUE )            // Timer STOP, wenn TC == MR
                      T0MCR |= 0x3;
                    
                    else
                      T0MCR |= ( T0MCR & 0xFFFFFFFB );                
                  
              break;




Autor: mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: D. S. (forack)
Datum:

Bewertung
0 lesenswert
nicht 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 ....

Autor: mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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(

Autor: D. S. (forack)
Datum:

Bewertung
0 lesenswert
nicht 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 !

Autor: D. S. (forack)
Datum:

Bewertung
0 lesenswert
nicht 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:
 void isr_TIMER0_INT (void) __irq {
 T0IR = 1;
 // code
 VICVectAddr = 0;
 }

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.