Archiv verlassen und diese Seite im Standarddesign anzeigen : Mit RS232 gleichzeitig senden und empfangen
Hallo,
mein ASURO soll dauernd und zeilenweise Messwerte (int) ausgeben die durch Hyperterminal angezeigt werden sollen. Hyperterminal empfängt also nur die Ziffern "0" bis "9", "-", CR und LF.
Soweit ist das ja kein Problem.
Aber:
Wenn ich spontan(!), und das soll jederzeit möglich sein, via Hyperterminal "q" (wie quit) eingebe soll ASURO die Übertragung der Messwerte beenden.
Weiß einer ob das überhaupt geht (mit dem ATMEGA)? Mit der LIB 2.7.1?
Wie warte ich auf ein Zeichen (hier konkret das "q") WÄHREND zufällig gerade die Ausgabe läuft, ich also mitten im PrintInt(..) stecke?
Helfen da Interrupts überhaupt weiter?
damaltor
09.01.2008, 01:20
gehen tut alles mit der richtigen programmierung.
wie du bereits gemerkt hast, GLEICHZEITIG kann der prozessor immer nur eine sache. möglich wäre aber immer nur ein zeichen zu senden, und dann kurz zu warten ob nicht ein q gekommen ist..
linux_80
09.01.2008, 20:10
Hallo,
beim Asuro ist aber auch das Problem, das die Daten per IR übertragen werden, und dabei die jeweils andre Richtung deaktiviert wird.
Wenn gesendet wird, kann nix empfangen werden, denn der Asuro würde nur seine eigenen Daten wieder reinbekommen !
Deswegen funktioniert auch der Test des IR-Adapters gegen weisse Wand o.ä., was man schreibt kommt wieder zurück.
Es ist in der Lib festgelegt, das entweder nur gesendet oder nur empfangen werden kann.
radbruch
09.01.2008, 21:06
Hallo
Das Problem mit dem Echo hätte ich auch genannt, allerdings wußte ich das mit dem UCSRB-Register nicht:
void SerWrite(unsigned char *data,unsigned char length)
{
unsigned char i = 0;
UCSRB = 0x08; // enable transmitter
while (length > 0) {
if (UCSRA & 0x20) { // wait for empty transmit buffer
UDR = data[i++];
length --;
}
}
while (!(UCSRA & 0x40));
for (i = 0; i < 0xFE; i++)
for(length = 0; length < 0xFE; length++);
}
void SerRead(unsigned char *data, unsigned char length,unsigned int timeout)
{
unsigned char i = 0;
unsigned int time = 0;
UCSRB = 0x10; // enable receiver
/* non blocking */
if (timeout != 0) {
while (i < length && time++ < timeout) {
if (UCSRA & 0x80) {
data[i++] = UDR;
time = 0;
}
}
if (time > timeout) data[0] = 'T';
}
/* blocking */
else {
while (i < length) {
if (UCSRA & 0x80)
data[i++] = UDR;
}
}
}
(aus asuro.c V2.3)
Die Beschreibung der UCSRB-Bits aus dem Datenblatt:
• Bit 4 – RXEN: Receiver Enable
Writing this bit to one enables the USART Receiver. The Receiver will override normal
port operation for the RxD pin when enabled. Disabling the Receiver will flush the
receive buffer invalidating the FE, DOR and PE Flags.
• Bit 3 – TXEN: Transmitter Enable
Writing this bit to one enables the USART Transmitter. The Transmitter will override normal
port operation for the TxD pin when enabled. The disabling of the Transmitter
(writing TXEN to zero) will not become effective until ongoing and pending transmissions
are completed (i.e., when the Transmit Shift Register and Transmit Buffer Register
do not contain data to be transmitted). When disabled, the Transmitter will no longer
override the TxD port.
•
Zuerst Bit3: Wenn gesetzt werden die normalen Porteinstellungen (Eingabe/Ausgabe) überschrieben. Wenn nicht gesetzt, werden schon gestartete Ausgaben nicht beeinflußt und nach dem Senden wird der Port nicht mehr überschrieben(, falls er von anderen Anwendung verwendet wird)
Bit4: Der Empfänger überschreibt die normalen Porteinstellungen, wenn er enabled ist.
Ich habe mit Absicht die Stellen mit "enables/disables the USART Transmitter" weggelassen, weil ich mich frage, ob der UART nicht trotzdem aktiv ist solange die Anwendung nicht an den Ports "rumfummelt". Dann könnte man nämlich doch beides gleichzeitig machen und z.B. den Receiver-Interrupt abfangen. Das könnte man mal testen, muss man aber nicht:
Ich würde selbstständige Sende- und Empfangsfunktionen schreiben (auf Basis der Lib-Funktionen) und das mögliche eigene Echo wegprüfen (if receive==send) . Nur ein Ansatz, noch nicht versucht oder geprüft.
Gruß
mic
@dalmator
Ich muss widersprechen. Im konkreten Fall sollte der Prozessor (die Hardware) zwei Dinge, hier receive und transmit GLEICHZEITIG machen können. Denn alle Beschreibungen lesen sich so, als könne man dies erreichen indem man gleichzeitig RXEN und TXEN gesetzt hält.
@linux_80
Ist schon klar, das mit dem Echo. Deshalb habe ich ja extra ein Zeichen gewählt (hier das "q") was nicht gesendet wird. "q" kann also nicht als Echo kommen! Oder, wie hast Du dabei gedacht?
Apropos "Test des IR-Adapters": Pc-seitig scheint mein Wunsch "gleichzeitig senden und empfangen" ja schon erfüllt zu sein.
@radbruch
Ja, in der Lib wird das UCSRB Register so verwendet, dass sich receive und transmit wechselseitig ausschließen. Laut Datenblatt scheint mir, dass nichts zu diesem Vorgehen zwingt. Ausser, vielleicht ein Energiesparwunsch?
Apropos Energiesparen: Laut Datenblatt sollte auch die Warteschleife am Ende von SerWrite(..) nicht nötig sein.
linux_80
09.01.2008, 22:27
Wie radbruch schon meinte wirst Du ums probieren nicht herumkommen wenn Du es so machen willst. Kann funktionieren, muss aber nicht immer, vor allem in kleineren Räumen wirds besser reflektieren als im Freien zB.
Aber auch mal mit andren Zeichen proberen, ob sich die gesendeten IR-Signale nicht überschneiden, und etwas ganz anderes draus machen :-k
Beim PC macht es weniger aus, wenn etwas falsches angezeigt wird, solange es im Terminal läuft, und nur zB. Du das liest. Die Fehlererkennung beim Menschen ist doch noch etwas besser ausgelegt, als man das in Software für den AVR auf die schnelle proggen könnte :-k
radbruch
09.01.2008, 22:28
Laut Datenblatt sollte auch die Warteschleife am Ende von SerWrite(..) nicht nötig sein.
Die Warteschleife sollte vor dem Senden sein und dient nur dazu einen Überlauf zu verhindern.
mic
damaltor
10.01.2008, 01:51
rossir: ich meinte dass der prozessor immer nur einen befehl zur zeit abarbeiten kann. es ist also nicht möglich, zwei befehle im gleichen systemtakt zu verarbeiten.
jodoch sollte es durchaus möglich sein, mit enabled tX und RX senden und empfangen zu können. für eine "normale" uart schnittstelle habe ich zB für meine projekte eine interruptgesteuerte lösung gefunden; diese speichert zu sendende daten in einem puffer und sendet immer bei einem UART_TX_READY ein weiteres zeichen. tritt ein UART_RX_READY auf, wird das zeichen aus dem register abgeholt und zur späteren weiterverarbeitung ebenfalls in einem puffer gesichert.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.