Forum: Mikrocontroller und Digitale Elektronik lpc1768 uart0 rx interupt


von Pascal H. (_pascal_)


Lesenswert?

Hi,

ich bin gerade dabei meinen UART0 von meinem lpc1768 in betrieb zu 
nehmen.
Das Senden von Bytes funktioniert auch wunderbar.

Baudrate 115200 8N1

P0.2 u P0.3 sind auf UART gestellt.
FIFOS sind enabled.
NVIC_EnableIRQ(UART0_IRQn) ebenso.

Jetzt habe ich eine ISR implementiert doch leider passiert nicht viel.
Ich versuche ueber Minicom Bytes zu senden.

Ich lande leider nur in der ISR bei einem THRE aber nicht bei einem RBR 
wenn ich in minicom Bytes sende.
1
#include <lpc17xx.h>
2
#include <stdio.h>
3
4
void UART0_IRQHandler() {
5
6
  uint8_t irq_mode = LPC_UART0->IIR;
7
  irq_mode >>= 1;
8
  irq_mode &= 0x07;
9
10
  // Receive Data Avaliable
11
  if(irq_mode == 0x02) {
12
    printf("RBR\n");
13
  }
14
15
  // Receive Line Status
16
  if(irq_mode == 0x03) {
17
    printf("RLS\n");
18
  }
19
20
  // Character Time-out Indicator
21
  if(irq_mode == 0x05) {
22
    printf("CTI\n");
23
  }
24
25
  // Tranceive Register Empty
26
  if(irq_mode == 0x01) {
27
    //printf("THRE\n");
28
  }
29
30
}

Hier noch meine init function
1
void initSystem() {
2
3
  // set gpio function
4
  LPC_PINCON->PINSEL7 &= ~(0x3U << 18);
5
  LPC_PINCON->PINSEL7 &= ~(0x3U << 20);
6
7
  // set gpio pull-down
8
  LPC_PINCON->PINMODE7 |= (0x3U << 18);
9
  LPC_PINCON->PINMODE7 |= (0x3U << 20);
10
11
  // set gpio as output
12
  LPC_GPIO3->FIODIR |= (1U << 25);
13
  LPC_GPIO3->FIODIR |= (1U << 26);
14
15
  // setup uart0
16
  LPC_PINCON->PINSEL0 |= (1 << 4) | (1 << 6);
17
  LPC_UART0->LCR = 0x83;            // 8bit, no parity, 1 stop bit, DLAB=1
18
  LPC_UART0->DLL = 0x0D;            // divide by 13
19
  LPC_UART0->DLM = 0x00;
20
  LPC_UART0->LCR &= ~(0x01U << 7);      // disable DLAB
21
  LPC_UART0->FCR = 0x07;            // enable fifo's, interrupt if 1 char
22
23
  NVIC_EnableIRQ(UART0_IRQn);
24
25
  LPC_UART0->IER |= (0x07U << 0);        // enable interrupt if data received
26
27
}

Jemand eine idee?

Vielen Danke im voraus.

: Bearbeitet durch User
von Jim M. (turboj)


Lesenswert?

PINSEL Bits sollte man immer vorher löschen, falls da mal jemand anders
welche setzt:
1
 // setup uart0
2
  LPC_PINCON->PINSEL0 &= ~((3 << 4) | (3 << 6));
3
  LPC_PINCON->PINSEL0 |= (1 << 4) | (1 << 6);

Ansonsten müsste der Code oben eigentlich tun.
Next Step: Mit dem Oszi prüfen, ob sich am RX Pin was tut, wenn in 
Minicom gesendet wird. Nicht dass da irgendwo z.B. Flow Control genau 
das verhindert.

von Pascal H. (_pascal_)


Lesenswert?

Jup werd es mir merken :)

flow control ist definitiv ausgeschaltet in minicom.

Hab leider gerade kein oszi da. Habe dann einfach mal P0.2 und P0.3 
gebrueckt. Dann sollte ich ja das was ich sende gleich wieder in meiner 
ISR rein bekommen -> ohne erfolg.

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

printf in einer ISR, hab mal irgendwo gelesen das sei ein schlechter 
Stil...

von Pascal H. (_pascal_)


Lesenswert?

Ohhm joar kenn mich zwar nicht so gut aus aber ich weis dass printf nen 
haufen overhead aus der newlib hat.

Dennoch funktioniert printf hier ohne probleme da
1
  // Tranceive Register Empty
2
  if(irq_mode == 0x01) {
3
    //printf("THRE\n");
4
  }
wenn es einkommentiert ist das minicom terminal zuballert.

Kann das laufende RTOS was damit zu tun haben?

: Bearbeitet durch User
von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Wie prüfst Du ob Du in der ISR landest? Durch eine Ausgabe mit printf? 
Wenn ja würde ich das mal anderes überprüfen. Ich habe nämlich auch mal 
gelesen, das printf in einer ISR zu seltsamen Verhalten führen kann das 
sehr schwer zu analysieren sein kann.

von Pascal H. (_pascal_)


Lesenswert?

ok ich hab printf mal entfernt. Aber grundsaetzlich ueberpruefe ich das 
mit eclipse cdt debugger und breakpoint.

irq_mode ist immer 1 also THRE. Das passiert immer direkt nach dem 
Senden (alle 5sec) ... scheint mir nachvollziehbar :)
1
void xSendTask(void *pvParams) {
2
3
  const TickType_t xDelay = 5000 / portTICK_PERIOD_MS;
4
5
  while (1) {
6
7
    printf("%i\n", xTaskGetTickCount());
8
9
    vTaskDelay(xDelay);
10
11
  }
12
13
}

: Bearbeitet durch User
von Pascal H. (_pascal_)


Lesenswert?

So ich konnte das Problem mittlerweie loesen :D

Auf meinem dev board befindet sich ein USB-Seriel Wandler, welcher am 
UART0 haengt.

Da ich diesen nicht benutzt habe und direkt an die pins mit einem 
anderen usb-seriel converter gegangen konnte das nicht funktionieren da 
der verbaute converter die RX leitung vom UART0 festhaelt solange er 
keine nachrichten bekommt ^^

Leider kann man auch keine loetbruecke entfernen um diesen converter zu 
deaktivieren.

Ich benutze jetzt einfach den auf dem board verbauten.

Danke an Alle fuer Eure Hilfe.

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.