Guten Morgen zusammen! Mein Aufbau sieht wie folgt aus: Ich habe einen Atmega324 an dem ein Max232 hängt. Verbunden sind Rx, Tx (beide gekreuzt) und GND. Der Atmega hat einen externen Quarz mit 10Mhz und die UART Einstellungen habe ich aus dem Tutorial und Datenblatt übernommen (Baud 9600 8N2). Aktiviert ist ferner, dass beim Empfang von Zeichen ein Interrupt ausgelöst wird. Am PC verwende ich HTerm. Wenn ich Zeichen vom µC zum PC sende, klappt das einwandfrei. Das Senden vom PC zum µC hingegen klappt nicht - es wird kein Interrupt ausgelöst. Ich habe dann einmal eine Brücke zwischen Tx und Rx vom Max232 gesetzt. Dann habe ich im HTerm die gesendeten Zeichen gesehen. Als nächstes habe ich Tx und Rx vom µC gebrückt und daraufhin wurde der Interrupt ausgelöst. Prinzipiell scheint das Empfangen vom µC also zu funktionieren. Aber wenn ich über HTerm sende, kommt einfach nichts im µC an. Die Kabel habe ich natürlich auch schon mal gewechselt. Gibts vielleicht irgendwelche Ideen, woran das liegen könnte?
Der Fehler ist in Zeile 42 deines geheimen Quellcodes.
Troll A. schrieb: > Gibts vielleicht irgendwelche Ideen, woran das liegen könnte? Weil du das ja alles sicher schon mit dem Oszilloskop kontrolliert und dort auch die beiden Timings (Baudrate) verglichen hast (das sollte man bei seriellen Schnittstellen generell), liegt es mit höchster mit höchster Wahrscheinlichkeit am Programm. > es wird kein Interrupt ausgelöst. Wie sieht es mit Polling aus, wenn schon der Interrupt nicht kommt?
:
Bearbeitet durch Moderator
Rahul D. schrieb: > Der Fehler ist in Zeile 42 deines geheimen Quellcodes. Ich habe alles in mehreren Dateien gesplittet, aber hier mal die wichtigsten Funktionen: Init
1 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
|
2 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
|
3 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
|
4 | |
5 | #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
|
6 | #error BAUD not valid
|
7 | #endif
|
8 | |
9 | void uart_init() |
10 | {
|
11 | UBRR0H = UBRR_VAL >> 8;; |
12 | UBRR0L = UBRR_VAL & 0xFF; |
13 | |
14 | UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0); |
15 | |
16 | //8data 2stop bit
|
17 | UCSR0C = (1<<USBS0)|(3<<UCSZ00); |
18 | }
|
Interrupt
1 | volatile uint8_t uart_string_complete = 0; |
2 | volatile uint8_t uart_string_count = 0; |
3 | volatile char uart_string[UART_MAX_STRING_LENGTH + 1] = ""; |
4 | |
5 | ISR(USART0_RX_vect) |
6 | {
|
7 | unsigned char nextChar; |
8 | |
9 | nextChar = UDR0; |
10 | |
11 | //Append new char only if string is not complete, else the main loop has to process the string first
|
12 | if(uart_string_complete == 0) |
13 | {
|
14 | uint8_t finishString = 0; |
15 | |
16 | if(nextChar == '\n' || nextChar == '\r' || uart_string_count == UART_MAX_STRING_LENGTH) |
17 | {
|
18 | finishString = 1; |
19 | }
|
20 | else
|
21 | {
|
22 | uart_string[uart_string_count] = nextChar; |
23 | uart_string_count++; |
24 | |
25 | if(nextChar == ';') |
26 | finishString = 1; |
27 | }
|
28 | |
29 | if(finishString == 1) |
30 | {
|
31 | uart_string[uart_string_count] = '\0'; |
32 | uart_string_count = 0; |
33 | uart_string_complete = 1; |
34 | }
|
35 | }
|
36 | }
|
Selbst wenn ich bei jedem Interrupt uart_string_complete auf 1 setzte, erhalte ich nichts. Lothar M. schrieb: > Weil du das ja alles sicher schon mit dem Oszilloskop kontrolliert Habe ich leider nicht zur Verfügung... Lothar M. schrieb: > Wie sieht es mit Polling aus, wenn schon der Interrupt nicht kommt? Schlecht. Mit
1 | if ( UCSR0A & (1<<RXC0) ) |
2 | {
|
3 | // Zeichen wurde empfangen, jetzt abholen
|
4 | uint8_t c; |
5 | |
6 | while (!(UCSR0A & (1<<RXC0))); |
7 | c = UDR0; |
8 | |
9 | lcd_gotoxy(0,1); |
10 | lcd_putc(c); |
11 | }
|
in der Main Loop bekomme ich leider auch keine Ausgabe. Ich verstehe es irgendwie nicht, da ja das Senden vom µC zum PC einwandfrei klappt...
Troll A. schrieb: > Ich habe einen Atmega324 an dem ein Max232 hängt. Dann musst du dessen Funktion wenigstens mal statisch kontrolliert? 9V-Batterie am RS232-RX-Eingang mal so und mal andersrum gepolt und dann am RX-Ausgang des MAX gemessen, welche Pegel rauskommen? > Ich habe dann einmal eine Brücke zwischen Tx und Rx vom Max232 gesetzt. Auf welcher Seite? Auf der RS232 Seite oder der TTL-Seite? > Als nächstes habe ich Tx und Rx vom µC gebrückt und daraufhin wurde der > Interrupt ausgelöst. Von wo aus wurde da gesendet? Der MAX war dabei noch angeschlossen? Troll A. schrieb: > Lothar M. schrieb: >> Weil du das ja alles sicher schon mit dem Oszilloskop kontrolliert > Habe ich leider nicht zur Verfügung... Würde ich ändern. Serielle Schnittstellen bekommt man nur mit einem "Deserializer" wie einem Oszi oder einem Logicanalyzer sicher in den Griff. Ein Oszi ist besser, weil man damit auch die Signalqualität (Pegel, Flanken) bewerten kann. Denn das Debuggen von seriellen Schnittstellen ohne Oszi ist wie Autofahren nach Gehör: man merkt Probleme immer erst dann, wenn es schiefgegangen ist.
:
Bearbeitet durch Moderator
Lothar M. schrieb: > oder einem Logicanalyzer Für kleines Geld gibt es die "Salae-Kompatiblen", als SW empfehle ich sigrok, das erlaubt intensives Analysieren serieller Kommunikation. Verfügbar auch für Windows. https://sigrok.org
Troll A. schrieb: > Das Senden > vom PC zum µC hingegen klappt nicht - es wird kein Interrupt ausgelöst. Du bist Dir sicher, dass der PC sendet? Brücke doch mal versuchsweise am PC TxD und RxD, dann sollte das Terminalprogramm ein Echo empfangen. Auch schadet es nichts, die Handshakeleitungen am PC zu brücken. RTS mit CTS verbinden sowie DCD mit DSR und DTR verbinden. Grüßle, Volker
Troll A. schrieb: > UBRR0H = UBRR_VAL >> 8;; > UBRR0L = UBRR_VAL & 0xFF; Hat zwar nichts mit deinem eigentlichen Problem zu tun, daher nur so als Hinweis: die Verwaltung der 8-Bit-Register bei einem 16-Bit-Register macht der Compiler für dich.
1 | UBRR0 = UBRR_VAL; |
Oliver
Volker B. schrieb: > Du bist Dir sicher, dass der PC sendet? Brücke doch mal versuchsweise am > PC TxD und RxD, dann sollte das Terminalprogramm ein Echo empfangen. Hat er wohl gemacht: Troll A. schrieb: > Ich habe dann einmal eine Brücke zwischen Tx und Rx vom Max232 gesetzt. > Dann habe ich im HTerm die gesendeten Zeichen gesehen.
Harald K. schrieb: > Volker B. schrieb: >> Du bist Dir sicher, dass der PC sendet? Brücke doch mal versuchsweise am >> PC TxD und RxD, dann sollte das Terminalprogramm ein Echo empfangen. > > Hat er wohl gemacht: > > Troll A. schrieb: >> Ich habe dann einmal eine Brücke zwischen Tx und Rx vom Max232 gesetzt. >> Dann habe ich im HTerm die gesendeten Zeichen gesehen. Sorry, das hab' ich überlesen. Dann hilft wohl nur noch ein Oszilloskop. Nachtrag: Die Berechnung der Baudrate ist korrekt? Nicht dass der Compiler dafür 16-Bit-Zahlen verwendet. Grüßle, Volker
:
Bearbeitet durch User
Beitrag #7583183 wurde vom Autor gelöscht.
> Ich habe dann einmal eine Brücke zwischen Tx und Rx > vom Max232 gesetzt. Dann habe ich im HTerm die gesendeten > Zeichen gesehen. Als nächstes habe ich Tx und Rx vom µC > gebrückt und daraufhin wurde der Interrupt ausgelöst. Also für mich folgt daraus, dass die Verbindung vom MAX232 zum ATmega324.PD0 nicht in Ordnung ist.
S. L. schrieb: > Also für mich folgt daraus, dass die Verbindung vom MAX232 zum > ATmega324.PD0 nicht in Ordnung ist. Das ließe sich ja auch einfach prüfen: An der MCU RxD und TxD brücken und die MCU im Reset halten. Dann sollte der PC sein Echo empfangen. Grüßle, Volker
:
Bearbeitet durch User
Bau mal ein sei(); als letzte Zeile in deine Uart-Init.
Wie sind die Schnittstelleneinstellungen von HTerm? Arbeitet HTerm mit 2 Stoppbits (Baud 9600 8N2)?
:
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.