Hallo, obwohl ich jetzt schon ein bisschen Erfahrung mit Mikrokontroller habe (aber weit weg von einem Profi ;-) ), hätte ich eine Frage: Wie kann man eine Transmit Interrupt service routine sinnvoll nutzen? Man könnte doch die Daten auch ohne ISR senden. Könnte mir jemand ein kleines Anwendungsbeispiel erklären, damit ich mir etwas darunter vorstellen kann? Außerdem, wie wird eine soche ISR ausgelöst? Durch einen Timer? Vielen Dank!! Dominik
Ja, und einige Anwendungen benutzen auch nur für Receive eine ISR. Man kann, wenn man einzelne Bytes sendet, natürlich einfach auf TXC warten. Wenn man aber große Datenmengen sendet, kann man eine Interruptroutine schreiben, die automatisch immer das nächste Zeichen aus einer Puffervariable überträgt, wenn der UART gerade frei / fertig ist.
Ein Transmit-Interrupt zeigt an, dass ein Zeichen weggeschickt wurde und dass im Transmit-Hold-Register Platz ist für das nächste. Anwendungsbeispiel (Pseudocode):
1 | // ------------ serial-interface.c -----------------------------
|
2 | |
3 | static char * transmit_next; // next byte to transmit |
4 | static int transmit_remainder; // remaining bytes |
5 | volatile int transmission_complete; // flag controlling the main loop |
6 | |
7 | void send (const char * data, int length) |
8 | {
|
9 | // Datenspeicher festhalten
|
10 | transmit_next = data; |
11 | transmit_remainder = length; |
12 | |
13 | // Complete-Flagge löschen (Flagge für Main-Loop)
|
14 | transmission_complete = 0; |
15 | |
16 | // 1. Zeichen nach TransmitHold -> startet die Übertragung.
|
17 | THR = *transmit_next; |
18 | }
|
19 | |
20 | // ISR - wird automatisch aufgerufen nach jedem übertragenen Zeichen.
|
21 | void tx_isr (void) __interrupt |
22 | {
|
23 | transmit_remainder--; // Rest verringern |
24 | if (transmit_remainder > 0) // Noch Zeichen übrig? |
25 | {
|
26 | transmit_next++; // Puffer-Zeiger vorrücken |
27 | THR = *transmit_next; // Nächstes Zeichen ins Senderegister - Übertragung wird gestartet |
28 | }
|
29 | else // Ganzer Block übertragen |
30 | {
|
31 | transmission_complete = 1; // Signal zur Mainloop |
32 | }
|
33 | }
|
1 | // -------- main.c -------------------------------------------------
|
2 | |
3 | static char transmit_memory [256]; |
4 | |
5 | // transmit_memory füllen
|
6 | |
7 | // Sendung starten
|
8 | send (transmit_memory, 256); |
9 | |
10 | // Warten auf Sendung-Fertig
|
11 | while (!transmission_complete) |
12 | {
|
13 | // derweil was anderes machen
|
14 | }
|
Dominik schrieb: > Wie kann man eine Transmit Interrupt service routine sinnvoll nutzen? Eine Senden mittels ISR ist z.B. bei einer Multitasking Applikation sinnvoll. Wenn der Prozessor nichts anderes zu tun hat als darauf zu warten, dass der ganze String gesendet wurde, dann bracht es den ISR nicht. Bei einem Multitasking BS kann inzwischen ein anderer Task etwas sinnvolles tun und die ISR unterbricht diese Tätigkeit kurz um das Senderegister bei Bedarf neu zu laden.
Hallo, Danke für eure Antworten. Da ich ein RTOS verwende, kann ich mir jetzt ein Bild davon machen, wie ich die Tranmit ISR einsetzen könnte. Vielen Dank! Dominik
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.