Hallo zusammen,
der Titel sagt eigentlich schon ziemlich viel.
Ich habe einen AT89C51ID2 und möchte ihn von einem Rechner aus per
serieller Schnittstelle ansteuern - und natürlich soll er auch was
zurücksenden.
Den Receive des Controllers habe ich soweit verstanden (glaube ich).
Aber wie sage ich dem Controller, dass er Daten schicken soll? Es gibt
ja (laut Datenblatt) nur ein UART-Buffer-Register namens SBUF. Dann habe
ich noch ein Bit, mit dem ich den Empfang aktivieren und deaktivieren
kann.
Muss ich jetzt also, um Daten vom Controller zum PC zu übertragen, den
Empfang deaktivieren, meinen Buffer mit dem zu schreibenden Wert füllen
und dann auf den Transmit-Interrupt warten? Oder bin ich da total auf
dem Holzweg?
Danke schonmal im voraus für Eure Antworten und viele Grüße
P.S.: Ach ja, Pegelwandlung usw. ist klar, da nehm ich nen ADM232AAN
(hab ich Muster von bekommen und sollte funktionieren).
Also, mov a,sbuf ließt dein Zeichen, mov sbuf,a sendet es.
RI zeigt einen Receive an, TI einen Transmit.
So, was willst du machen ??
Beispiel: Daten senden:
send_byte: jnb ti,send_byte
mov sbuf,a
clr ti
Nun sende was du willst, oder wie ist die Frage zu verstehen ?
Hallo Joe,
ja, hast die Frage schon richtig verstanden.
Auch wenn ich in C programmiere, so viel Assembler versteh ich sogar
noch :-)
Das heißt also, ich muss REN nicht rücksetzen, oder? Was macht er denn,
wenn er gleichzeitig Daten empfängt, während er sendet? Okay, sollte
normalerweise (bei mir) nicht passieren, aber wenns doch so ist?
Viele Grüße und danke für die schnelle Antwort!
REN ist das Interrupt freigabe Flag für die UART.
In C gehts auch ... ;-))
void putchar_uart (char c)
{
while (!TI); // Transmitter busy ?
TI = 0; // TI Flag löschen
SBUF = c; // Ausgabe an UART
}
Im Interrupt Betrieb setzt du also REN + EA. Wenn dann ein Interrupt
auftritt dann weißt du erstmal nicht war es RI oder TI. Also mußt du
schon ein bischen mehr programmieren.
Ein ISR gleicher priorität kann sich nicht selbst unterbrechen, also im
worst case verlierst du ein Zeichen. Derartige Fälle mußt du sowieso im
Protokoll berücksichtigen. Eine genaue Aussage kann man aber erst machen
wenn man alle Fakten kennt, beschreibe was du machen willst !!
Hallo Joe,
okay, hier etwas ausführlicher, was ich machen möchte:
Der PC schickt per serieller Schnittstelle verschiedene Telegramme raus.
Diese unterscheiden sich in ihrer Länge.
Es gibt vier verschiedene Telegrammtypen, die durch zwei Bit im ersten
Byte gekennzeichnet werden.
Wenn also der erste Receive-Interrupt kommt schaut der Controller nach,
was für ein Telegrammtyp es ist, setzt eine Variable maxAnzahl auf die
maximale Anzahl an Bytes des jeweiligen Telegrammtyps und speichert den
Wert des 1. Bytes in einem Buffer.
Jetzt kommt das nächste Byte (also der nächste Interrupt), er speichert
den Wert im Buffer und überprüft, ob die maximale Anzahl an Bytes für
den entsprechenden Telegrammtyp schon erreicht ist.
Wenn ja schickt er eine Antwort an den Rechner. Wenn nicht gehts halt
mit dem Empfang des nächsten Bytes weiter.
Zum Senden hatte ich mir überlegt, dass ich vier verschiedene Funktionen
schreibe, die die jeweils gewünschte Antwort (hängt natürlich vom
empfangenen Telegramm ab) an den Rechner schicken (auch diese
unterscheiden sich in ihrer Länge).
Dafür hätte ich dann das ES-Bit rückgesetzt (das ist laut meinem
Datenblatt das Interrupt-Enable bit für die UART) und ziemlich genau die
Routine von dir übernommen.
Wenn der Transmit fertig ist wird der Interrupt wieder freigegeben,
damit weitere Nachrichten vom PC empfangen werden können.
Dass der Prozessor während dem Senden nicht unterbrochen werden kann
sollte eigentlich nicht weiter stören, da der PC, nachdem er ein
Telegramm weggeschickt hat, sowieso auf eine Antwort warten muss.
Laut meinem Datenblatt ist das REN-Bit das "Reception Enable Bit" und
dient dazu, den Empfang an- oder abzuschalten...
Hoffe mal, es ist einigermaßen klar, was ich machen möchte.?
Viele Grüße
Die Frage ist, ob ich REN während dem Senden rücksetzen muss, oder ob
ich es auf 1 lassen kann.
Was würde denn passieren, wenn (was nicht passieren sollte, aber nehmen
wir mal an es passiert doch) der Controller Daten empfängt, während er
sendet und REN auf 1 wäre.
Dann würde er doch den Transmit-Buffer überschreiben (denn RI wird ja
erst gesetzt, wenn er 9 Bits (1 Byte + Stopbit) empfangen hat), oder? Je
nachdem ob ich gerade durch Zufall das letzte Byte sende kann ich dann
also auf den Interrupt noch reagieren, oder das Zeichen ist verloren und
ich laufe anschließend in den Wald, weil ich mein zuletzt geschriebenes
Byte wieder einlese, was aber nicht einem gültigen Telegramm vom
Computer entspricht, sehe ich das richtig?
In diesem Fall würde ich eben REN rücksetzen, dann kriege ich zwar nicht
mit, dass der Rechner sendet, aber besser so als anschließend total in
den Wald zu laufen!
Wollte damit nur sicher gehen, dass ich mir das richtig überlegt habe,
da ich noch nicht besonders viel Erfahrung mit Mikrocontrollern habe.
Viele Grüße
In deinem Fall ist alles eine "bewußte" Aktion. Wenn ich ehrlich bin
würde ich die UART im polling mode ganz ohne Interrupt betreiben. Den
brauchst du eigentlich gar nicht.
Statt REN kannst du auch EA abschalten, wäre eine weitere Möglichkeit.
Wie dem auch sei, bei deiner Routine läuft alles nacheinander:
Erst Kommando.. Telegramm vom PC... Dann antwortet der Controller mit
dem zurücksenden von Daten. Dann.... gehts weiter, warum also Interrupt
?
Warum Interrupt?
Nun, dann kann ich zumindest auf den Receive warten ohne dass ich
ständig das Request-Bit des Empfängers pollen muss.
Finds persönlich fast sympatischer, wenn in main irgendwo while(1);
steht als die CPU ständig damit zu beschäftigen ein bestimmtes Bit zu
pollen.
Aber das ist reine Geschmackssache :-)
Viele Grüße und danke für die Hilfe
Ja, einen Interrupt und ab diesem Zeitpunkt pollen, man muß es nur
sinnvoll kombinieren.
Wie gesagt, ansonsten wäre dein Workflow ohne Interrupt abzubilden.
1.) ISR, MC wird empfangsbereit Interrupt
2.) Empfang der Kommandosequenzen non Interrupt
3.) Zurücksenden der MC Daten an den Host non Interrupt
Wählst du jetzt ein entsprechendes Protokoll (echo, handshake etc..)
dann geht nichts mehr Verloren.
Ich habe in den seltensten Fällen 100% Kommunikation über ISR's
realisiert da es überhaubt nicht notwendig ist, und glaub mir, ich habe
schon einige geschrieben.