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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.