Hallo, ich habe da ein Problem. Ich nutze einen ATXmega 128A1 und sende damit im Interrupt via UARTC1. Wenn ich den TXC-Interrupt wähle funktiniert es einwandfrei. Ich möchte jedoch den DRE (DataRegisterEmpty) Interrupt nutzen, um die Kommunikation Schlupffrei zu machen. Jedoch funktioniert dies nur ein einziges mal nach einem Reset und danach werden keine Daten mehr gesendet. Gibt es da irgend welche Probleme bei den XMega's? Grüße Hans-Josef
Hallo, hier mal etwas Code. Zuerst die Version mit TXC-IRQ, welche einwandfrei funktioniert:
1 | #define COM_C1 USARTC1 // USART1 von PORTC wird als Interface Bus1
|
2 | |
3 | |
4 | mstr_send; // Receive OFF, Sender ON, Datenrichtung=Senden |
5 | uart_send_cnt = 6; // Anzahl zu sendender zeichen |
6 | uart_cnt = 0; // Zeichenzähler |
7 | |
8 | USART_PutChar(&COM_PB, uart_buffer[uart_cnt++]); // Sende 1.char |
9 | USART_TxdInterruptLevel_Set(&COM_C1, USART_TXCINTLVL_HI_gc); // Trans-IRO scharf machen |
10 | ...
|
11 | |
12 | ...
|
13 | ISR (USARTC1_TXC_vect) // Send IRQ |
14 | {
|
15 | if (uart_cnt < uart_send_cnt) // Alles gesendet? |
16 | USART_PutChar(&COM_C1, uart_buffer[uart_cnt++]); // TX Buffer fuellen |
17 | |
18 | else{ |
19 | PORTC.OUTCLR = PIN5_bm; // RS485 Datenrichtung Empfang |
20 | USART_Tx_Disable(&COM_C1); // TX_disable |
21 | }
|
22 | }
|
Jetzt mit DRE-IRQ, welches nur einmal funktioniert. Dabei sollte immer wenn das Datenregister leer ist was eingetragen werden und am Schluß wird dann der TXC-IRQ scharf gemacht, was die RS485-Datenrichtung umschaltet und den Sender abschaltet.
1 | #define COM_C1 USARTC1 // USART1 von PORTC wird als Interface Bus1
|
2 | |
3 | |
4 | mstr_send; // Receive OFF, Sender ON, Datenrichtung=Senden |
5 | uart_send_cnt = 6; // Anzahl zu sendender zeichen |
6 | uart_cnt = 0; // Zeichenzähler |
7 | |
8 | USART_DreInterruptLevel_Set(&COM_C1, USART_DREINTLVL_HI_gc); // Trans-IRO scharf machen |
9 | |
10 | ISR (USARTC1_DRE_vect) // Send IRQ |
11 | {
|
12 | if (uart_cnt < uart_send_cnt) // Alles gesendet? |
13 | USART_PutChar(&COM_C1, uart_buffer[uart_cnt++]); // TX Buffer fuellen |
14 | |
15 | else{ |
16 | USART_DreInterruptLevel_Set(&COM_C1, USART_DREINTLVL_OFF_gc); // DRE-IRQ sperren |
17 | USART_TxdInterruptLevel_Set(&COM_C1, USART_TXCINTLVL_HI_gc); // Trans-IRO scharf machen |
18 | }
|
19 | }
|
20 | |
21 | ISR (USARTC1_TXC_vect) // Ende des senden |
22 | {
|
23 | PORTC.OUTCLR = PIN5_bm; // RS485 Datenrichtung Empfang |
24 | USART_Tx_Disable(&COM_C1); // TX_disable |
25 | }
|
Also wie gesagt die erste Lösung arbeitet (bis auf die kleinen) Verzögerungnen durch andere IRQ-Bearbeitung. Die DRE-Lösung tut es nur bei erstenmal nach einem Reset, danach sendet der µC nichts mehr???? Ich habe spaßeshalber mal ein Senden im Pollbetrieb gemacht, mit dem gleichen Ergbnis. Grüße Hans-Josef
Hallo, Nach Reset ist das DRE-Bit gesetzt, die Routine wird also nach Freigabe der IRQ sofort aufgerufen. Du schaltest dann den DRE-IRQ in der ISR aus. Irgendwann sicher auch wieder ein? DRE ist nach Schreiben der Daten in der ISR gelöscht, das wird auch nie wieder gesetzt, es sei denn, Du schreibst das erste Byte zum erneuten Senden außerhalb der ISR in den UART, dann wird es gesetzt, wenn die Daten raus sind. Gruß aus Berlin Michael
Hallo, so ich habe den Fehler gefunden. Wenn man den Transmitter abschaltet wenn noch Zeichen im Schieberegister sind dann funktioniert der Tansmitter danach garnicht mehr. Hat jemand eine Ahnung, wie man den Transmitter wieder zurücksetzen kann? @amiga, Der DRE-IRQ wird immer ausgeführt, da das Flag nur gelöscht wird wenn man Daten schreibt. Löschen kann man das nicht. Wenn man den DRE-IRQ nicht sperrt dann kommt der immer. So steht's auch im Manual beschrieben. Grüße Hans-Josef
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.