Forum: Mikrocontroller und Digitale Elektronik LPC2468 UART über Interrupt auslesen


von Eric S. (ottili86)


Lesenswert?

Hallo zusammen,

ich arbeite seit kurzem mit einem LPC2468 Mikrocontroller. Das ganze 
geschieht auf einem Eval-Board von Embedded Artists.
Unter anderem sollen dabei ankommenden Bytes in dem UART über einen 
Interrupt ausgelesen werden. Die Zeichen werden von Hyper Terminal aus 
gesendet. Hier mein Quellcode dazu:
Zunächst die UART-Initialisierung
1
  PCONP |= (1 << 4);
2
  
3
  U1FCR = 0x00;        //disables FIFO
4
  
5
  PCLKSEL0 &= 0xFFFFFDFF;  // PCLK1 = CCLK; 
6
  PINSEL7 |= 0x0000000F;  // P3.16 TXD1, P3.17 RXD1 
7
8
  U1LCR = 0x80;        // DLAB = 1
9
  U1DLM = baudrate / 256;              
10
  U1DLL = baudrate % 256;
11
  U1LCR = settings;
12
  U1FDR = scaler;
13
  
14
  install_irq(UART1_INT, (void *)UART1_Handler, 3);
15
16
  U1FCR = 0x07;
17
  U1IER = 0x03;

und die UART-ISR
1
void UART1_Handler (void)
2
{
3
  u8_t speicher, iirvalue;
4
5
//    Der folgende Abschnitt ist für meinen Lämpchen Debugger
6
  switch(loll)
7
  {
8
  case 0:
9
    loll = 1;
10
    FIO1SET  |= 0x00000800;
11
    break;
12
  
13
  case 1:
14
    loll = 0;
15
    FIO1CLR |= 0x00000800;
16
    break;
17
  }
18
19
//      Und das ist vorläufig die Datenbehandlung
20
  speicher = U1IIR;
21
  if ((speicher & 0x0E) == 4)
22
    speicher = 1;
23
  else
24
    speicher = 0;
25
  while(speicher)
26
  {
27
    iirvalue = U1RBR;
28
    speicher = U1IIR;
29
    if ((speicher & 0x0E) == 4)
30
      speicher = 1;
31
    else
32
      speicher = 0;
33
  }
34
  VICVectAddr = 0;
35
}

Jetzt mein Problem: Die ISR wird nur bei dem ersten ankommenden Zeichen 
aufgerufen. Danach springt das Programm wieder in main. Alle 
nachfolgenden ankommenden Zeichen im UART werden einfach ignoriert und 
die ISR nicht mehr aufgerufen.

Was mache ich falsch??? Habe schon einige Varianten ausprobiert, aber 
die hier funktioniert von den schlechten immer noch am besten. Wie 
gesagt ich bin auch noch relativ unerfahren auf diesem Gebiet.

Bin für jede Hilfe dankbar.

von ich (Gast)


Lesenswert?

Sind alle Stack-Pointer von allen User-Modes initialisiert? - Der ISR 
wird in einem anderen User Mode aufgerufen, wenn da der Stack nicht 
gesetzt ist, dann kommt er nie mehr zurück...

von Eric Schrön (Gast)


Lesenswert?

Er kommt ja wieder zurück und macht alles andere wunderbar was ich von 
ihm will. Aber er die ISR wird halt kein zweites mal aufgerufen, sondern 
nach dem ersten mal nie mehr.

von ich (Gast)


Lesenswert?

Im Code-Bundle für den LPC2368 gibt es ein gutes Demo für den externen 
Interrupt, im common Verzeichnis sind alle Dateien die es für eine 
Interrupt Ansteuerung braucht. (irq.c Startup.s swi_handler.s irq.h 
LPC23xx.h type.h ...)
Siehe www.standardics.nxp.com
Der UART ISR funktioniert identisch.

von Eric S. (ottili86)


Lesenswert?

Jep!!!

Das Code Bundle kenn ich und habe ich auch schon ausprobiert. Leider mit 
mäßigem Erfolg.

Hat es bei dir oder jemandem anders den schon funktioniert???

Gruß
Eric

von ich (Gast)


Lesenswert?

Ja. Ich musste nur erst durch die Makefile Scripte druchsteigen... Ich 
nutze Eclipse und GNU.

von Eric S. (ottili86)


Lesenswert?

Ich benutze die selben Tools. Wenn es bei dir geht, werde ich meine 
Bemühungen nochmal verstärken, den Bug zu finden. Ich nehme an, dass 
irgendwo noch ein Flag restet werden muss, dass den Interrupt anzeigt. 
Weist du in der Richtung irgendwas, wo eingehende Interrupts überall 
gespeichert werden???

von ich (Gast)


Lesenswert?

Auf den ersten Blick war Ihr Code in Ordnung. Daher denke ich es muss an 
den *.s Dateien, bzw Linker usw. liegen.

von mthomas (Gast)


Lesenswert?

Zumindest beim letzen Mal, als ich mir das NXP code-bundle angeschaut 
habe, war es für ARM Realview-Compiler/Tools (enthalten in halbwegs 
aktuellen Keil RV-MDK). Für GNU-tools sind Anpassungen erforderlich zum 
Interrupthandling. Gibt ein paar Möglichkeiten:

(1) direkter Spung im Core-IRQ-Vector auf die VIC-Vector-Addresse und 
ergänzen des IRQ Attributes zur ISR. Beispiele z.B. in eingen Codes von 
Analog Devices. Entspricht der Vorgehensweise bei KeilView und IAR nur 
wird __irq "ersetzt"). GNU IRQ-Attribute funktioniert aber 
möglicherweise nicht in allen Lebenslagen. daher:

(2) direkter Spung wie oben, allerdings ISR mit "naked" attribute und 
sich um den Offset von PC und Sicherung/Rücksicherung von Registers (und 
evtl. "nesting") selbst kümmern (per Macro). Beispiele dazu gibt es 
einige, z.B. das UART-Beispiel von Bill Knight im Dateibereich der 
LPC2000 Yahoo-Gruppe. Sieht nicht hübsch aus und ist auch schlecht 
portierbar, daher:

(3) Core-IRQ springt auf eine Assembler-"Wrapper", im Wrapper: einige 
Register sichern, evtl. nesting, ISR C-Funktion rufen 
(VIC-Vector-Addresse), Register rücksichern, Rücksprungaddresse 
anpassen, Rücksprung. Beispiel in vielen Codes von Atmel (für AT91 AIC, 
lässt sich an ARM/NXP VIC im LPC23xx/24xx anpassen) und leicht 
abgewandlert in Beispiel für STR7 von Anglia Designs.

Mglw. findet sich in meinem "Zeug" ein wenig Inspiration: 
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/

Hoffe, es hilf
Martin Thomas

von Eric Schrön (Gast)


Lesenswert?

vorläufig schonmal danke an alle!!!

@Martin
Danke für den Link. Ich werde mal in Ruhe die relevanten Beispiel 
durchgehen und schauen, was ich da so bei mir verbessern kann.

Eric

von NX (Gast)


Lesenswert?

Wenn ich das richtig verstehe blockiert der ARM doch Automatisch die 
Interrupts beim wechsel in den IRQ-Mode, vielleicht vergisst der 
GNU-Compiler diese wieder freizugeben...?

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

NX schrieb:
> Wenn ich das richtig verstehe blockiert der ARM doch Automatisch die
> Interrupts beim wechsel in den IRQ-Mode, vielleicht vergisst der
> GNU-Compiler diese wieder freizugeben...?

Thread gelesen? vgl. Beitrag 02.07.2008 09:56

"freigeben" ist allermeist Sache des Programmieres (z.B. gegf. 
auslösende Flags löschen, VIC Interrupt bestätigen), den Rest macht der 
Kern u.U. mit dem Interrupt-Controller. Hat wenig mit dem Compiler zu 
tun. Was der GNU ARM Compiler manchmal verbockt (evtl. inzwischen nicht 
mehr), ist die korrekte Sicherung und Wiederherstellung der 
Rücksprungaddresse aus dem Handler bei Verwendung des 
Funktionsattributes für IRQ.

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.