Hi,
bastel gerade ein wenig mit RS232 herum. Ich habe eine bidirektionale
Verbindung zwischen PC und µc.
Der PC sendet bspl. eine "10"
Die "10" wird in der Variablen "c" gespeichert und an den PC zurück
gegeben.
Soweit so gut.
In einer ISR habe ich die Variable "tempo"
Wie kann ich die "10" aus "c" nun an "tempo" übergeben ?
Gruß
odin
Er erhält "10" und das ist ein string. Daher:
strcpy(tempo,c);
:D
Du musst darauf achten, dass c eine globale Variable ist, da du
ansonsten aus der ISR keinen Zugriff darauf hast.
EDIT: In der Annahme, dass du C verwendest...
Vorsicht bissiger Hund!
Werden über die serielle Schnittstelle die Zeichen "1" und "0"
übertragen, so kann der Zugriff via. strcpy () Probleme bereiten.
strcpy steht auf das Abschließende "\0" - so war‘s wenigstens früher
mal.
Also ich verwende die lib von Peter Fleury.
Mit c = uart_getc(); --> weise ich den Inhalt der variablen c zu.
C wird außerhalb der Funktion mit unsigned int c; --> global
ebso die variable tempo mit unsigned int
odin schrieb:> volatile uint8_t zaehler;> unsigned int tempo;> unsigned int c;
Mach erstmal aus tempo und c auch ein volatile uint8_t, sonst gibts
casting Probleme. c muss allerdings nicht volatile sein.
Ausserdem musst du entweder ein einzelnes Byte übertragen (also z.B. ein
grosses 'A' hätte dann 0x41 als Wert), oder du brauchst eine
Empfangsroutine, die dir eine Zahl, gefolgt von einem 'Ende' Zeichen
umwandelt in ein Byte.
odin schrieb:> Mit c = uart_getc(); --> weise ich den Inhalt der variablen c zu.
Quatsch.
Damit steht in c nur das letzte empfangene Zeichen, z.B. '0' = 48.
Du willst aber eine Zeichenkette empfangen und dann in eine Zahl
umwandeln.
Dazu mußt Du Dir erstmal ein Protokoll überlegen, wie der Anfang und das
Ende der Zeichenkette markiert und erkannt werden kann.
Vielleicht kann "Odin" ja mal aus seinem Götterhimmel herauskrabbeln und
seinen Anhängern erklären ob er so etwas simples wie ein binäres Zeichen
z.B. 0xA=10=ein Zeichen, oder eine ASCII-Zeichenkette wie z.B. "1" + "0"
= zwei Zeichen, durch die Lande schaukelt.
Hey amatuer, keine Spässe über meinen Name, ich heisse wirkich so !
Also ich wollte einfach nur den ordinären Wert 10 vom PC übertragen, der
die Blinkgeschwindigkeit änder soll
... was nichts daran ändert, das eine Klarstellung nötig war.
Also nix mit strcpy () sondern einfach warten bis ein Zeichen im Puffer
vorhanden ist und dieses dann holen/kopieren (=).
odin schrieb:> for(;;)> {> c = uart_getc();>> tempo = c;>> if ( c & UART_NO_DATA )> {> }
So so.
Du verwendest also das c bereits, noch ehe klar ist, ob uart_getc()
überhaupt ein Zeichen für dich hatte, oder ob es mangels Daten
UART_NO_DATA geliefert hat, um anzuzeigen, dass vom Sender nichts
gekommen ist.
Liest heute eigentlich noch irgendwer Democode und überlegt sich, was er
da gelesen hat oder wird heutzutage in Demos nur noch gedankenlos und
dämlich das reingeschrieben, was man sich irgendwie denkt?
Mann ihr wärt aber sowas von aufgeschmissen gewesen, wenn ihr in einer
Zeit angefangen hättet, in der es kaum Demos gab und man sich aus 500
Seiten Manuals alles zusammensuchen musste und dann stundenlang das
Gelesene versucht hat, in Code zu giessen.
odin schrieb:> Ja was sol ich da sagen , Gnade der späten Geburt !>> Ich nehme aber einmal an, du wolltest mir auch damit weiter helfen.
Ich will dich aufrütteln, dass du Democode auch STUDIEREN musst.
Das was du in einer Demo siehst, das steht da nicht von ungefähr! P.
Fleury het den nicht geschrieben, weil ihm fad war, sondern weil er
damit etwas demonstrieren will. Nämlich: wie verwendet man die Funktion
korrekt und wie wertet man den Returncode korrekt aus.
Und wenn ich seinen Code studiere, dann sehe ich dass er von der
Funktion einen Wert bekommt, den er in c speichert. Und dann gehts
weiter! Was macht er mit diesem c? Wie wertet er die Variable aus.
Bereits in der nächsten Zeile steht
if( c & UART_NO_DATA )
UART NO DATA?
Da muss es doch sofort zum Klingeln anfangen. NO DATA - keine Daten. Was
macht seine Demo in diesem Fall? Nichts - sie macht buchstäblich nichts.
Wie denn auch, wenn die Funktion liefert "Ich hab nichts", dann ist da
auch nichts, mit dem man etwas tun könnte (etwa ausgeben).
Ok, die Funktion hahe ich ja auch soweit verstanden. Mein "tempo = c;"
steht da nur aus lauter Verzweifelung.
Aus meiner bescheidenen Sicht müsste der Code hier stehen :
for(;;)
{
c = uart_getc();
if ( c & UART_NO_DATA )
{
}
else
{
if ( c & UART_FRAME_ERROR )
{
uart_puts_P("UART Frame Error: ");
}
if ( c & UART_OVERRUN_ERROR )
{
uart_puts_P("UART Overrun Error: ");
}
if ( c & UART_BUFFER_OVERFLOW )
{
uart_puts_P("Buffer overflow error: ");
}
uart_putc( (unsigned char)c );
tempo = c;
}
}
Denn nur wenn alle DANN Möglichkeiten NICHT zutreffen, ist erfolgreich
etwas übertragen worden.
Es klappt aber leider auch so nicht
Ich habe nie mit der Bibliothek von Peter Fleury gearbeitet, aber
vielleicht wäre es hilfreich statt mit:
tempo = c;
mit
tempo = c & 0xff;
zu arbeiten.
Irgendwie sieht euer Code so aus als ob da mehr als char zurückgeliefert
wird, euer Interesse aber auf char beschränkt ist.
amateur schrieb:> tempo = c;>> mit>> tempo = c & 0xff;>> zu arbeiten.
Das passt schon.
Wenn alle Fehler ausgeschlossen sind, dann bleibt in c nur mehr das
LowByte übrig. Das High-Byte ist definitiv 0.
"Funktioniert nicht"
ist nun mal keine ordentliche Fehlerbeschreibung.
Der COde sendet ja das Byte, welches dann an temp zugewiesen wird über
die UART zurück. D.h. da hat man ja die Bestätigung beim Sender, was der
AVR eigentlich erhalten hat, und welche Werte dann auch tatsächlich an
tempo zugewiesen werden.
Aber noch bin ich mir nicht sicher, ob er überhaupt den UNterschied
zwischen einer ASCII Übertragung und einer binären Übertragung versteht.
Mal genauer nachfragen.
> Also ich wollte einfach nur den ordinären Wert 10 vom PC übertragen,> der die Blinkgeschwindigkeit änder soll
Und wie machst du das auf PC-Seite?
Und wurde die UART eigentlich schon mal prinzipiell getestet?
Wenn du vom AVR was zum PC schickst (zb indem dort ein Terminalprogramm
läuft), erscheint dann dort das Gesendete korrekt?
Ich weis nicht wie Fehlerträchtig (hängt wohl vom Quarz ab) die
Übertragung ist, aber bei einem UART_FRAME_ERROR, UART_OVERRUN_ERROR
oder UART_BUFFER_OVERFLOW erfolgt trotzdem ein:
tempo = c;
amateur schrieb:> Ich weis nicht wie Fehlerträchtig (hängt wohl vom Quarz ab) die> Übertragung ist, aber bei einem UART_FRAME_ERROR, UART_OVERRUN_ERROR> oder UART_BUFFER_OVERFLOW erfolgt trotzdem ein:> tempo = c;
Yep,
Das ist nicht schön. Aber wenn die UART prinzipiell korrekt funktioniert
(was man erst mal testen müsste), dann kommen diese Fehler praktisch
nicht vor. In einem Profiprogramm werden sie selbstverständlich
behandelt, aber für die ersten Schritte ist es schon ok.
Die ganze Problematik wird ja auch im Tutorial komplett ignoriert. Ein
1
uint8_tuart_getc(void)
2
{
3
while(!(UCSRA&(1<<RXC)))// warten bis Zeichen verfuegbar
4
;
5
returnUDR;// Zeichen aus UDR an Aufrufer zurueckgeben
6
}
ist ja so gesehen auch nur die halbe Miete, weil ja die ganze
Fehlerbehandlung komplett ignoriert wird. Irgendwo muss man nun mal
anfangen und Fehlerbehandlung hat die Tendenz, die Dinge mal schnell
kompliziert und unübersichtlich zu machen.
Aber wie gesagt: Wenn die UART prinzipiell funktioniert, dann treten
diese Fehler nicht auf und können so gesehen fürs erste ignoriert
werden.
So vielen Dank für die Unterstützung ! Es funktioniert !!
Natürlich muss ich auch binär etwas senden, wenn ich binär etwas erwarte
:-)
Und ich habe sogar verstanden warum
tempo = c & 0xff;
zum Ziel führte !
Danke an alle !