Ich habe ein Problem mit dem UART.
Auf die Gegenseite habe ich keinen Einfluss, ich muss also benutzen was
da ist. Das Frameformat ist 7 bit, 1 stopbit und parity even. Das
"blöde" ist, dass den Uart-Receiver die Einstellung beim Stopbit nicht
interessiert (Datasheet Page 197: Bit 3 – USBSn: Stop Bit Select
This bit selects the number of stop bits to be inserted by the
Transmitter. The Receiver ignores this setting.). Ich empfange immer nur
richtig Daten wenn ich am PC auf 2 Stopbits umstelle, bei einem Stopbit
werden die Zeichen schlicht falsch empfangen. Dazu die Bilder im Anhang:
1. Bild (von 13:30:59 Uhr): "Test"+CR+LF gesendet (bei den gezeigten
Einstellungen)
2. Bild (von 13:31:33 Uhr): "Test"+CR+LF gesendet (bei den gezeigten
Einstellungen)
3. Bild (von 13:31:54 Uhr): CR+LF gesendet (bei den gezeigten
Einstellungen)
Ich muss eigentlich nur hinbekommen, dass der Receiver bei 1 Stopbit die
Daten richtig empfängt. Muss ich da noch irgendwo was schubbsen wenn
mein Frameformat nur 7 bit + 1 stop ist? Ich sehs grade nicht.
Mein Testcode:
main
1 | #define ubbrFuer4800BD 185 //Bei 14,318 MHz Quarz fuer 4800 Bd
|
2 | #define uart_str_length 19
|
3 |
|
4 |
|
5 | #include <avr/io.h>
|
6 | #include <avr/interrupt.h>
|
7 |
|
8 | #include "uart.h"
|
9 | #include "main.h"
|
10 |
|
11 | volatile char uartString[uart_str_length] = "050.00\r\n";
|
12 | volatile uint8_t uart_str_count = 0;
|
13 | volatile uint8_t uartGetMessage = 0;
|
14 |
|
15 | int main(void)
|
16 | {
|
17 | /* insert your hardware initialization here */
|
18 | setup();
|
19 | sei();
|
20 | for(;;){
|
21 | /* insert your main loop code here */
|
22 | while (uartGetMessage == 0);
|
23 | uartGetMessage = 0;
|
24 | sendString(uartString);
|
25 | }
|
26 | return 0; /* never reached */
|
27 | }
|
28 |
|
29 | void setup(void) {
|
30 | //setup uart/rs232
|
31 | uartSetup(ubbrFuer4800BD);
|
32 | }
|
33 | ISR(USART_RX_vect){
|
34 | unsigned char nextChar;
|
35 | // Daten aus dem Puffer lesen
|
36 | nextChar = UDR0;
|
37 | if ( uartGetMessage == 0) {
|
38 | // Daten werden erst in uart_string geschrieben, wenn nicht String-Ende bzw. maximale Zeichenlaenge erreicht ist
|
39 | if( (nextChar != '\n') &&
|
40 | (nextChar != '\r') &&
|
41 | (uart_str_count < uart_str_length) ) {
|
42 | // Zeichen abspeichern
|
43 | uartString[uart_str_count] = nextChar;
|
44 | // und String-Count um 1 erhoehen
|
45 | uart_str_count++;
|
46 | }
|
47 | else {
|
48 | // Stringende definieren
|
49 | uartString[uart_str_count] = '\0';
|
50 | // Zeichenempfangszaehler zuruecksetzen
|
51 | uart_str_count = 0;
|
52 | // und Flag setzen für Datenempfang Abgeschlossen
|
53 | uartGetMessage = 1;
|
54 | }
|
55 |
|
56 | }
|
57 | }
|
uart.c
1 | #include "uart.h"
|
2 |
|
3 |
|
4 | void uartSetup(uint16_t baudrate){
|
5 | //set Baudrate
|
6 | UBRR0H = baudrate >> 8;
|
7 | UBRR0L = baudrate & 0xFF;
|
8 | //set other UART Settings
|
9 | UCSR0B |= (1<<TXEN0)|(1 << RXEN0)|(1<<RXCIE0); // UART TX/RX einschalten, RXIE einschalten
|
10 | UCSR0C |= (1 << UPM01)|(1<<UCSZ01); // Asynchron 7N1 und Parity even
|
11 | }
|
12 | void sendChar(unsigned char zeichen){
|
13 | {
|
14 | /* Wait for empty transmit buffer */
|
15 | while ( !( UCSR0A & (1<<UDRE0)) );
|
16 | /* Put data into buffer, sends the data */
|
17 | UDR0 = zeichen;
|
18 | }
|
19 | }
|
20 | void sendString(const char* charOfString){
|
21 | //send string from ram
|
22 | /* while *charOfString != '\0 */
|
23 | while (*charOfString) {
|
24 | sendChar(*charOfString);
|
25 | charOfString++;
|
26 | }
|
27 | }
|
28 | void sendString_p(const char* charOfString){
|
29 | //send string from flash
|
30 | register char c;
|
31 | /* while *charOfString != '\0 */
|
32 | while ( (c = pgm_read_byte(charOfString++)) ) {
|
33 | sendChar(c);
|
34 | }
|
35 | }
|