Forum: Mikrocontroller und Digitale Elektronik Interrupt gesteuertes UART transmit


von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Hallo zusammen,
ich arbeite auf einem ATSAM4S gerade an der Optimierung der bandbreite 
und des timings meiner über UART an ein Bluetooth Modul zu übertragenden 
daten:

Ich habe zwei Ringbuffer, über die zu sendende und empfangene daten 
abgearbeitet werden.

Der Receive-Zweig klappt wunderbar: Über den UART0_Handler mit 
aktiviertem RXRDY Interrupt hole ich immer bei Eingang eines Bytes 
dieses aus dem Empfangsregister und schiebe es in den 
Empfangs-Ringbuffer für die weitere Verarbeitung.

Der Transmit-Zweig macht mir Probleme: Bislang hatte ich an einer Stelle 
der main-routine einfach den Transmit-Ringbuffer schritt für schritt 
abgearbeitet - also ganz ohne Interrupts.

Jetzt kann ich aber nur mit 115.2kBaud übertragen (und nutze diese 
Bandbreite ziemlich aus) - und das Erzeugt bei mir Timing Problemee, 
wenn ich jedes mal warten muss, bis die Übertragung beendet ist.

Am besten soll also regelmäßig der Transmit-Ringbuffer überprüft - und 
was darin ist stückweise übertragen werden.
Ich wollte das ganze in der selben UART0_Handler Interrupt routine wie 
oben abarbeiten, indem ich den TXRDY Interrupt (oder ENDTX) aktiviere 
und dann in der routine wenn einer Übertragung beendet wurde nur noch 
prüfe ob der Transmit-Ringbuffer leer ist - und wenn nicht ein Element 
herausnehme und versende - etc. etc.

Das funktioniert so nun nicht: Obwohl ständig daten in den ringbuffer 
geschickt werden, bekomme ich in der Konsole nur kurz daten - und dann 
ein stop. Auch, wenn ich am ende der mainroutine jedes mal noch einen 
transmit initiiere, um bei zwischenzeitlich leerem ringbuffer (und damit 
gestoppter übertragung) wieder neu zu beginnen.

Wie würdet ihr eine interrupt gesteuerte UART-Transmit-Übertragung 
lösen, die immer, wenn etwas im Ringbuffer ist, im "hintergrund" daten 
sendet, während in der mainroutine eben diese daten erzeugt werden?

: Bearbeitet durch User
von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Hier die grobe Übersicht der routinen unter Verwendung des Atmel 
Software Framework
1
/**
2
 *  Handler for UART interrupts - pushes received data in the RX fifobuffer/ pulls data to transmit from TX fifobuffer.
3
 */
4
void UART0_Handler (void){
5
  uint8_t temprx;
6
  // If data has been received, load into rxbuffer
7
  if (uart_is_rx_ready(CONSOLE_UART))  {
8
    uart_read(CONSOLE_UART, &temprx);
9
    fifo_push_uint8(&rxbuf_desc, temprx);  
10
  }
11
  
12
  // Send Data from TX Buffer
13
  if (!fifo_is_empty(&txbuf_desc) && (uart_is_tx_empty(CONSOLE_UART))) {
14
    fifo_pull_uint8(&txbuf_desc, &txchar);
15
    usart_serial_putchar(CONSOLE_UART, txchar);
16
  }
17
}
18
19
20
main(void{
21
22
// Initialize UART module
23
const usart_serial_options_t uart_serial_options = {
24
    .baudrate = CONF_UART_BAUDRATE,
25
    #ifdef CONF_UART_CHAR_LENGTH
26
    .charlength = CONF_UART_CHAR_LENGTH,
27
    #endif
28
    .paritytype = CONF_UART_PARITY,
29
    #ifdef CONF_UART_STOP_BITS
30
    .stopbits = CONF_UART_STOP_BITS,
31
    #endif
32
  };
33
34
  /* Configure console UART. */
35
  sysclk_enable_peripheral_clock(CONSOLE_UART_ID);
36
  stdio_serial_init((Usart *)CONF_UART, &uart_serial_options);
37
  // Enable UART End of Receive Transfer and End of Transmit interrupts
38
  NVIC_EnableIRQ(UART0_IRQn);
39
  NVIC_SetPriority(UART0_IRQn, IRQ_PRIOR_UART);
40
  uart_enable_interrupt(CONSOLE_UART, (UART_IER_RXRDY || UART_IER_TXRDY));
41
  // Reset console - initialize flags/counter
42
  console_reset(cstat);
43
  cstat->feedback=false;
44
45
while(1){
46
47
// Much data is generated here
48
49
// At the end: Start new transmission
50
  if (!fifo_is_empty(&txbuf_desc) && (uart_is_tx_empty(CONSOLE_UART))) {
51
    fifo_pull_uint8(&txbuf_desc, &txchar);
52
    usart_serial_putchar(CONSOLE_UART, txchar);
53
  }
54
55
}
56
}

: Bearbeitet durch User
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.