mikrocontroller.net

Forum: Compiler & IDEs Interrupts bei LPC2294 ARM Mikrocontroller


Autor: Hammoud (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
Meine Versuche einen Timer des LPC2294 als Intervall -Timer zu
programmieren schlugen bislang fehl. Der Timer wird richtig
initialisiert und nach der vorgegebenen Zeit wird auch ein Interrupt
ausgelöst. Problem ist nur, dass die ISR des Timers nie ausgeführt
wird.
In der ISR wird lediglich die Systemuhr aktualisiert und das
Interrupt-Flag gelöscht. Die von mir definierte ISR sieht
folgendermaßen aus:

// this function is to be called when a timer interrupt is generated
void __attribute__((interrupt("IRQ"))) timerIntHandler(void);

void timerIntHandler(void)
{
     timeNow+= ####;  // #### is the time between 2 timer interrupts
     T0IR = (1<<0);   // Clear interrupt flag by writing 1 to Bit 0
     VICVectAddr = 0; // Acknowledge Interrupt
}

Die Adresse dieser Funktion wird auch in den entsprechenden
Interrupt-Vektor geschrieben:

VICVectAddr0 = (unsigned long)timerIntHandler;

Ich habe mehrmals gecheckt, ob irgend etwas bei der Initialisierung
vergessen wurde und meiner Meinung nach müsste alles richtig sein.

Ich würde mich freuen, wenn der eine oder andere einen Tipp parat hat.

PS: ARM-gcc-Toolchain

Vielen Dank
Hammoud

Autor: Jens Altenburg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

interessant wäre nicht nur die ISR Routine sondern die Initialisierung
selbst. Der VIC braucht noch die dazugehörige Interruptfreigabe.
Beim LPC2138 sieht das in etwa so aus:

   VICIntSelect &= ~0x10;
   VICIntEnable  =  0x10;
   VICVectCntl0  =  0x24;  /* vectored interrupt control reg */
   VICVectAddr0  =  (unsigned long)timerIntHandler;
   TOTCR = 0;              /* stop timer */
   T0PR  = 0;              /* prescaler */
   T0MR0 = wert;           /* set match register */
   T0MCR = 1;              /* interrupt bei match */
   T0TCR = 1;              /* start timer */
   ... global interrupt enable nicht vergessen

Beim LPC2294 vorher mal im Datenblatt nachschauen.

MfG

Jens

Autor: Zoltan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint32_t timetick; // globale Variable

// Timer Counter 0 Interrupt initialisieren
void init_timer (void)
{
T0MR0 = 14999; // 1mSec = 15.000-1 counts
T0MCR = 3; // Interrupt and Reset on MR0
T0TCR = 1; // Timer0 Enable
VICVectCntl0 = 0x20 | 4; // IRQ Slot0 für Timer 0 (VIC-Channel 4)
VICVectAddr0 = (uint32_t)tc0; // IRQ Slot0 auf Funktion tc0 setzen
VICIntEnable = 0x00000010; // Enable Timer0 Interrupt (Bit4=1)
}

// Timer Counter 0 Interrupt executes each 1ms @ 60 MHz CPU Clock
void tc0 (void) __irq
{
++timetick; // Interrupt-Aktion: Zeitvariable erhöhen
T0IR = 1; // Clear interrupt flag
VICVectAddr = 0; // Acknowledge Interrupt
}

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht ziemlich richtig aus.
Verwendest du den Keil?
Ich habe hier eine Initialisierungsroutine für einen LPC2138. Versuch
die mal. Die Routinen sehen ziemlich kompatibel aus. Es kann sein, dass
der Prozessor bei irgendeiner Reihenfolge ein Problem hat.

Diese Routine hat bei mir funktioniert:

  VICVectAddr1 = (unsigned long)timercomp_irq;          // set
interrupt vector in 1
  VICVectCntl1 = 0x20 | 4;   // Vic UART0
  VICIntEnable = 0x0000010;                  // Enable Timer Interrupt

  T0TCR=0x2; // Timer Reset
  T0CTCR=0x0; // Timermode
  T0MR0=119; // Vergleichsregister    // Überlauf bei 2µs
  T0MCR=3;   // IRQ-Vergleich 0, Timer=0 im Vergleichsregister 0
  T0TCR=0x1; // Timer startet





void timercomp_irq(void) __irq
{
  T0IR=0x01;
  if(flag==1)
  {
  IOCLR0=x;
  flag=2;
  }
  else
  {
  IOSET0=x;
  flag=1;
  }
VICVectAddr = 0; // Acknowledge Interrupt
}



Schreib uns, ob du es geschafft hast.

Tschüss
Martin

Autor: Axel Stab (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wir haben mit dem Timer-Demo unter dem folgenden Link schnell einen
brauchbaren Timer-Interrupt hinbekommen:

http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/

Allerdings haben wir jetzt mit mehrkanaligem Match-IRQ Betrieb Probleme
(Rücksetzen der IRQ-Bits), scheint am Chip zu liegen, in den Erratas
steht auch eine ganze Menge...

Viel Erfolg!


Hier Auszüge aus unserem Code:

/* Setup the Timer Counter 0 Interrupt */
void init_timer0 (void) {
  T0PR = 5;//T0 prescaler: clk/(1+prescaler) => 1 tick = 0,1 us
  T0MR0 = 10000;                           // 1mSec = 10000 counts
  T0MR1 = 10000000;                           // 1Sec = 10 mio counts
  T0MR2 = 10000000;
  T0MCR = ( 0x01 | 0x08 | 0x40 );        // Interrupt on MR0 + MR1 +
MR2
  T0TCR = 1;                                  // Timer0 Enable
  VICVectAddr0 = (unsigned long)tc0;          // set interrupt vector
in 0
  VICVectCntl0 = 0x20 | 4;                    // use it for Timer 0
Interrupt
  VICIntEnable = 0x00000010;                  // Enable Timer0
Interrupt
  timerticks = 0;
}


void _attribute_ ((interrupt("IRQ"))) tc0 (void) {

  if ( T0IR & 0x01 ) {
    //Match Register 0: 1ms-Interrupt

    i_timerticks |= 0x04;

  T0MR0 += 10000;
    T0IR     = 0x01;                          // Clear interrupt flag
    VICVectAddr = 0;                            // Acknowledge
Interrupt
  }


}

Autor: Joachim Klein (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

die Zeile:

    VICVectAddr = 0;

muss ausserhalb des if body stehen, sonst wird der Interrupt Controller
nicht zurück gesetzt, außer die if Bedingung ist erfüllt.

Gruß, Joachim

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.