HAllo zusammen, Zwar habe ich eine Frage Betreff der RS232. Habe ein problem mit dem Empfangen von Daten. Senden an den PC kann ich zeichen via rs232, jedoch empfangen über rs232 geht irgenwie nicht. Zwar funtioniert nicht mal der Interrupt richtig, dehalb vermute ich da das problem. Hat jemand eine idee was ich in der Initalisierung oder sonst vergessen habe? Mein Code: #include <avr/interrupt.h> void init_RS232(void); //Interrupt für RX von USART SIGNAL (SIG_UART0_RECV) { //Daten empfangen, aufruf für LED um zu togglen. Leds.led2Toggle(); } //Main Programm int main(void) { /* Set baud rate */ UBRR0H = (unsigned char)(ubrr>>8); UBRR0L = (unsigned char)ubrr; /* Enable receiver and transmitter */ UCSR0B = (1<<RXEN)|(1<<TXEN); /* Set frame format: 8data, 2stop bit */ UCSR0C = (1<<USBS)|(3<<UCSZ0); sei(); // test WriteChar('s') return 0; } //Write Data over RS232 void WriteChar(unsigned char c) { while(!(UCSR0A & (1 << UDRE0))) ; /* warte, bis UDR bereit */ UDR0 = c; /* sende Zeichen */ } /*void ReceiveData( void ) { while(! (UCSR0A & (1<<RXC))); rx_ = UDR0; } */ Besten dank für eure Hilfe. lg
Du musst das UDR im Interrupt Handler lesen, sonst wird das Flag nicht gelöscht und der Interrupt immer wieder ausgelöst! Abgesehen davon sind SIGNAL und die Vektornamen à la SIG_XXXX veraltet und sollten nicht mehr verwendet werden...
Der Interrupt muss noch auf enable gesetzt werden. UCSR0B = (1<<RXEN)|(1<<TXEN)|(1 << RXCIE);
Und in der main Funktion fehlt noch eine Endlosschleife. //Main Programm int main(void) { /* Set baud rate */ UBRR0H = (unsigned char)(ubrr>>8); UBRR0L = (unsigned char)ubrr; /* Enable receiver and transmitter */ UCSR0B = (1<<RXEN)|(1<<TXEN); /* Set frame format: 8data, 2stop bit */ UCSR0C = (1<<USBS)|(3<<UCSZ0); sei(); // test WriteChar('s') while(1); return 0; }
Und was soll der Blödsinn mit Interrupt und Polling gleichzeitig? Du musst Dich schon entscheiden, ob Du einen Interrupt auslösen oder das Flag in einer Schleife abfragen willst! Beides gleichzeitig geht nicht.
Wenn du uns jetzt auch noch verraten würdest, wo du eine Schleife siehst in der was empfangen wird? Ansonsten war nämlich leider dein Post Blödsinn.
Okay habe gsehen das der Interrupt doch aufgerufen wird. Um jedoch die Daten zu speichern ist so zu machen: SIGNAL(SIG_UART0_RECV) { while(! (UCSR0A & (1<<RXC))); rx_ = UDR0; } Gruss
Dabei besteht allerdings die Gefahr, dass du beim Empfang mehrerer Zeichen die Daten in rx_ überschreibst bevor du sie im Hauptprogramm verarbeitet hast. Je nach dem was du eigentlich vorhast, kann es sinnvoller sein, das lesen direkt im Hauptprogramm ohne Interrupt zu machen. Dann hast du nämlich die Möglichkeit anhand des Flags DOR (data over run) zu überprüfen, ob ein Zeichen verloren gegangen ist. Wenn du es optimal lösen willst, dann solltest du in der Interrupt Routine fürs Empfangen die Daten in einen FIFO Puffer schreiben. Dabei solltest du dann Prüfen, ob der Puffer voll ist, und wenn ja selber eine globale Variable als Buffer Overrun Flag setzen.
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.