mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ARM7 LPC2148 und UART Interrupt


Autor: Arne (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Moin zusammen,

ich quäl mich gerade mit einem LPC2148 rum.
Compiler ist IAR EWARM 5.4 mit Segger J-Link.

Und zwar bin ich momentan am UART. Senden (gepollt) funktioniert, nun 
will
ich den Empfang per IRQ lösen. Vermutlich habe ich die Interruptstruktur 
des ARM7
noch nicht so ganz geschnallt, daher hier mal ein Auszug aus dem 
cstartup.s von IAR:
; The module in this file are included in the libraries, and may be
; replaced by any user-defined modules that define the PUBLIC symbol
; __iar_program_start or a user defined start symbol.
;
; To override the cstartup defined in the library, simply add your
; modified version to the workbench project.

        SECTION .intvec:CODE:NOROOT(2)

        PUBLIC  __vector
        PUBLIC  __vector_0x14
        PUBLIC  __iar_program_start
        EXTERN irq_handler,fiq_handler

        ARM
__vector:
        ;;
        ldr   pc,[pc,#+24]              ;; Reset
        B   .                           ;; Undefined instructions
        B   .                           ;; Software interrupt (SWI/SVC)
        B   .                           ;; Prefetch abort
        B   .                           ;; Data abort
__vector_0x14:
        DC32  0                         ;; RESERVED
        ldr   pc,[pc,#+24]              ;; IRQ
        ldr   pc,[pc,#+24]              ;; FIQ

        DC32  __iar_program_start       ;; Reset
        DC32  0                         ;; Undefined instructions
        DC32  0                         ;; Software interrupt (SWI/SVC)
        DC32  0                         ;; Prefetch abort
        DC32  0                         ;; Data abort
        DC32  0                         ;; RESERVED
        DC32  irq_handler               ;; IRQ
        DC32  fiq_handler               ;; FIQ
Das sollte der interessante Teil in cstartup.s sein (sonst wird es zu 
lang.
__iar_program_start ist weiter unten definiert (MAM-Init usw.)

In main habe ich:
/*************************************************************************
 * Function Name: irq_handler
 * Parameters: void
 * Return: void
 *
 * Description: IRQ subroutine
 *
 *************************************************************************/
__irq __arm extern void irq_handler (void)
{
  void (*interrupt_function)();
  uint32 vector;

  vector = VICVectAddr;    /* Get interrupt vector.        */
  interrupt_function = (void(*)())vector;
  (*interrupt_function)();  /* Call vectored interrupt function.  */
  VICVectAddr = 0;
}

/*************************************************************************
 * Function Name: fiq_handler
 * Parameters: void
 * Return: void
 *
 * Description: FIQ subroutine
 *
 *************************************************************************/
__fiq __arm extern void fiq_handler (void)
{
  void (*interrupt_function)();
  uint32 vector;

  vector = VICVectAddr;    /* Get interrupt vector.        */
  interrupt_function = (void(*)())vector;
  (*interrupt_function)();  /* Call vectored interrupt function.  */
  VICVectAddr = 0;
}

Damit ich nicht zuviel wirres Zeug schreibe, mal die beiden Screenshots 
der Register für VIC und UART anbei. Die ISR für UART 0 liegt bei 
0x000008c8 (lt Mapfile). In CPSR sind I-Bit und F-Bit 0.

Habe in irq_handler() einen Breakpoint gestellt und er läuft nicht 
drauf, wenn ich über TeraTerm Zeichen sende (9600 8N1).

Any idea?

thanx, Arne

Autor: Arne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keiner 'ne Idee? Rettet meinen Sonntag! ;-)

Autor: Wilhelm F. (ferkes-willem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Hardware scheint ja schon zu funktionieren, wenn du damit, 
allerdings ohne Interrupt, schon gearbeitet hast.

Wo der VIC-Controller initialisiert wird, sehe ich so direkt nicht...

Hattest du schon mal einen anderen Interrupt als den UART zum laufen 
bekommen?

Autor: Arne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wo der VIC-Controller initialisiert wird, sehe ich so direkt nicht...
Vector #6 in cstartup.s verweist auf irq_handler, in irq_handler zieht 
er sich den ausgelösten INT über
vector = VICVectAddr;
und springt dann mittels Funktionspointer
(*interrupt_function)();
 in die eigentlich Behandlungsroutine.

Was müsste ich sonst noch initialisieren?
Enabled ist der IRQ (s. Screenshot VIC.gif) sowohl in VICIntEnable, als 
auch in VICVectCntl6.
Globale INTs in CPSR sind auch enabled (I/F-Bit beide auf 0).

> Hattest du schon mal einen anderen Interrupt als den UART zum laufen
bekommen?
Nein, habe eben ein Testprg hochgezogen, das auf Buttondruck den EINT1 
auslöst - kein Erfolg. :-(
PINSEL0 ist auch entsprechend gesetzt (0x8000 für EINT1).

Autor: Wilhelm F. (ferkes-willem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der IAR-Code ist für mich etwas ungewohnt, da ich mit Keil arbeitete. Es 
ist manches auf andere Art gelöst. Aber das sollte letztendlich doch 
gehen.

Das sieht aber ansonsten alles vernünftig aus. Ich schau aber nochmals 
drüber.

Geht das Programm jetzt gar nicht mehr, macht es nur die Interrupts 
nicht, oder was macht es noch?

Autor: Arne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der IAR Debugger hat mich wohl in die Irre geführt - die Demo zum 
Auslösen des EINT1 per Button funktioniert jetzt.
In meinem Init-code habe ich jetzt ein VICVectAddr = 0 eingefügt. Damit 
klappt der EINT-Test. Der UART weigert sich weiterhin. Am Prg.anfang 
springt er ab und an in den Handler für meinen UART, aber U0IIR.IP ist 
'1'?!?!

Die Handler für die Interrupts in meinem API muss ich ja nicht mit 
"__irq __arm" markieren? Das passiert ja schon über irq_handler - 
richtig?

Autor: Arne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wilhelm Ferkes schrieb:
> Geht das Programm jetzt gar nicht mehr, macht es nur die Interrupts
> nicht, oder was macht es noch?

Also ich sende am Anfang 10 Char - die kommen in TeraTerm auch an. Nur 
Empfang per INT funktioniert nicht. Sonst baue ich erstmal was ein, dass 
Empfang per Polling macht...

Autor: Wilhelm F. (ferkes-willem)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arne schrieb:

>Sonst baue ich erstmal was ein, dass
>Empfang per Polling macht...

Schnell genug wäre der ARM ja meist auch für Polling. Das ist aber keine 
ernsthaft saubere Lösung.

>Damit klappt der EINT-Test. Der UART weigert sich weiterhin.

Na prima. Dann funktioniert die Interruptsache schon mal generell.

>Am Prg.anfang springt er ab und an in den Handler für meinen UART,
>aber U0IIR.IP ist '1'?!?!

Ich schau nochmal nach, wie das in meinem Sourcecode war, hatte den UART 
auch schon am laufen, allerdings im LPC2129. Die µC sind aber da 
prinzipiell gleich.

Zum Debuggen sollte auch die Codeoptimierung des Compilers auf Null bzw. 
deaktiviert sein. Nur als Randbemerkung. Da hab ich auch schon seltsame 
Dinge erlebt.

Autor: Arne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wilhelm Ferkes schrieb:
> Zum Debuggen sollte auch die Codeoptimierung des Compilers auf Null bzw.
> deaktiviert sein.

Ist meine erste 'Amtshandlung' bei IAR Projekten, da der die 
Debug-Projekte per default auf Optimierungsstufe 'Low' stellt :-/

UART Empfang funktioniert jetzt zumindest soweit, dass die ISR 
aufgerufen wird. Ich hatte als INT-Quelle U0IER.RXLSIE gesetzt statt 
U0IER.RDAIE.
Jetzt rennt er zwar auf den Breakpoint in der ISR, aber U0LSR.DR ist 
'0'!
Wie passt das zusammen? Er empfängt was, meint in der ISR aber (bevor 
ich U0RBR anfasse), dass er eigentlich nix empfangen hat.

Autor: Arne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Scheint jetzt zu funktionieren!

Der Debugger verar***t mich. Wenn ich einen Breakpoint in die ISR setze, 
dann verhält sich das ganze System anders, als wenn ich den Breakpoint 
rausnehme! Ich krieg die Krätze!
Aber Danke für Deine Hilfe. Schönen Sonntag noch.

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.