Hi, Habe ein Infineon-C515c. Kann mir einer sagen: 1. Wieso nach der Konfiguration der seriellen Schnittstelle, TI=1 gesetzt werden muss? TI wird doch automatisch gesetzt durch die CPU? 2. Wenn ich TI=1 setze, ist doch ein "serial Interrupt" ausgelöst. Wieso wird dann nicht zur "Interrupt Service Routine" gesprungen? Den Code habe ich angehangen. Hoffe auf Hilfe
Lens schrieb: > 1. Wieso nach der Konfiguration der seriellen Schnittstelle, TI=1 > gesetzt werden muss? TI wird doch automatisch gesetzt durch die CPU? > 2. Wenn ich TI=1 setze, ist doch ein "serial Interrupt" ausgelöst. Wieso > wird dann nicht zur "Interrupt Service Routine" gesprungen? Hast du mal ins Datenblatt zu dem Thema geguckt? Ich bin mit dem 515C nicht mehr ganz so vertraut, aber manche andere Controller (AVR) setzen gewisse Flags zurück, wenn man sie mit einer 1 beschreibt. Das wäre in diesem Zusammenhang meine Vermutung.
Mir ist klar, dass ich noch den "serial interrupt" im "IEN0"-Register aktivieren muss, doch ich versteh trotzdem nicht, wieso das "TI"-Flag am Anfang gesetzt werden muss.
Jetzt könnt ihr mir vielleicht helfen. Im Bild steht "TI" direkt neben "/SEND". Doch es steht nirgends explizit, dass TI dem "/SEND"-Pin entspricht. Was meint ihr?
Lens schrieb: > Doch es steht nirgends explizit, dass TI dem "/SEND"-Pin > entspricht. Tut es auch nicht; ebensowenig wie "Data" dem "Shift" entspricht.
Es heißt außerdem "TI = 1; /* TI: set TI to send first char of UART */ Was soll das denn heißen? Wie kann ich denn das erste Zeichen senden, obwohl ich noch garkeinen Sendebefehl abgesetzt hab?
Es geht wohl um interruptgesteuertes Senden. Die Interruptroutine, die aufgerufen wird, wenn die UART mit dem Senden des vorhergehenden Zeichens fertig ist, holt sich ein Zeichen aus dem (Software-)Sendepuffer und übergibt das der UART-Hardware. Die sendet das Zeichen, und löst wiederum einen Interrupt für das nächste Zeichen aus. Ist der Sendepuffer leer, wird kein weiteres Zeichen gesendet und also kein weiterer Interrupt ausgelöst. Um den ganzen Kram zu starten, genügt es nicht, Daten in den Softwaresendepuffer zu schreiben, sondern es muss die Sendeinterruptroutine gewissermaßen einmal angestupst werden -- und das geschieht durch manuelles Setzen des TI-Bits.
Das war mir schon klar :). Nur wie du in meinem Code vielleicht siehst, ist nirgendwo was von seriellem Interrupt, geschweigedenn von Interrupt Service Routinen was zu sehen. Das ganze basiert auf "polling", da ja printf() als "polling" programmiert ist. printf() überprüft ob TI=1 ist, wenn ja, dann schreibt es das Zeichen in "SBUF". Das versteh ich ehrlich gesagt nicht. Wieso muss es abprüfen, ob TI=1 ist? Ich mein wenn er "TI=0" abprüfen würde, dann fände ich das logischer?
Lens schrieb: > printf() überprüft ob TI=1 ist, > wenn ja, dann schreibt es das Zeichen in "SBUF". Das versteh ich ehrlich > gesagt nicht. Wieso muss es abprüfen, ob TI=1 ist? Ich mein wenn er > "TI=0" abprüfen würde, dann fände ich das logischer? Wie ist denn das Bit im Datenblatt beschrieben? Ich nutze den von Dir verwendeten µC nicht, deswegen kenne ich natürlich seine UART auch nicht.
Lens schrieb: > Das versteh ich ehrlich > gesagt nicht. Wieso muss es abprüfen, ob TI=1 ist? Ich mein wenn er > "TI=0" abprüfen würde, dann fände ich das logischer? TI=1 sagt doch, dass das Senderegister leer ist und ein neues Zeichen geschrieben werden darf. Wenn es =0 ist, wird noch gesendet und man darf nicht schreiben. TI könnte einen Interrupt auslösen, wenn das Bit "ES" im Register "IEN0" gesetzt ist. Aber man kann TI auch pollen. (Hinweis: Ich habe das jetzt mal schnell im Datenblatt nachgeschaut, es ist also nur meine Theorie ohne praktische Erfahrung und Garantie!) Gruß Dietrich
Dietrich L. schrieb: > TI=1 sagt doch, dass das Senderegister leer ist und ein neues Zeichen > geschrieben werden darf. Wenn es =0 ist, wird noch gesendet und man darf > nicht schreiben. > TI könnte einen Interrupt auslösen, wenn das Bit "ES" im Register > "IEN0" gesetzt ist. Aber man kann TI auch pollen. Genau so ist es. Auch bei polled-Betrieb, muss am Anfang explizit das Senderegister als "leer" deklariert werden. Senderoutine (polling): 1.) warte, bis das Senderegister leer ist 2.) lege das nächste Zeichen in das Senderegister 3.) fertig. Bei Interrupt Betrieb wird es etwas komplexer. Hier wird das neue Zeichen in den Sende-Ringbuffer gelegt - sofern gerade eine Übertragung läuft. Ansonsten wird es direkt in das Senderegister gepackt. Der Interrupt prüft dann, ob weitere Zeichen im Ringbuffer sind und lädt ggfs das nächste Zeichen in das Senderegister. Ist nichts mehr zu senden, wird "fertig" markiert, damit der nicht-Interrupt-Teil weiß, dass er die Übertragung neu anwerfen muss.
Georg G. schrieb: > 1.) warte, bis das Senderegister leer ist > 2.) lege das nächste Zeichen in das Senderegister > 3.) fertig. So wie ich das bei der Beschreibung von TI gelesen hab, muss TI noch gelöscht werden: TI=1 löst Interrupt aus, die ISR löscht TI wieder. Auch wenn das nur im Zusammenhang mit Interrupt genannt wurde, vermute ich doch, dass das auch ohne ISR gilt. Gruß Dietrich
Dann noch mal ganz ausführlich die nicht-Interrupt Variante:
1 | /*----------------------------------------------------------------------*/
|
2 | char get_key(void) { |
3 | /* */
|
4 | /* Zeichen von der seriellen Schnittstelle holen, ggfs warten */
|
5 | /* */
|
6 | /*----------------------------------------------------------------------*/
|
7 | while (!RI); |
8 | RI = 0; |
9 | return(SBUF); |
10 | }
|
11 | |
12 | |
13 | /*----------------------------------------------------------------------*/
|
14 | void put_char(char c) { |
15 | /* */
|
16 | /* Zeichen über die serielle Schnittstelle ausgeben */
|
17 | /* */
|
18 | /*----------------------------------------------------------------------*/
|
19 | while (!TI); |
20 | TI = 0; |
21 | SBUF = c; |
22 | }
|
Mein Datenblatt (Siemens, uralt) ist eigentlich recht eindeutig. Allerdings muss man wirklich jeden Satz lesen und ernst nehmen.
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.