Hallo,
ich kann erfolgreich DAten versenden mit dem USART, nur mit dem
Empfangen klappt es noch nicht :( Im folgenden Code wird irgendwie nie
die Interrupt Routine angesprungen, obwohl der andere µC was schickt,
ebenfalls mit 2400 Baud.
Muss mich korrigieren, es geht nachdem ich eine gemeinsame Masse
zwischen den beiden COntrollern hergestellt habe... Mein Ziel ist aber
eine Datenübertragung per Infrarot, da habe ich ja auch keine gemeinsame
MAsse???
@ Fragender
Dein Signal vom TX-Pin hat einen Masse-Bezug!
Also der Strom fließt vom TX-Pin nach Masse.
Wenn du den + Pol deiner Autobatterie anfasst bekommst du doch auch
keine gewischt, es sei denn du hast deine Hand an der Karosserie
(Masse).
Die (woanders abgeschaute)Idee dabei ist,dass die empfangenen Daten in
einen Ringpuffer geschrieben werden, und sobald Lese- und Schreibzeiger
verschieden sind, ausgegeben werden sollen. Leider kommt gar nichts am
Pc an, gesendet wird definitiv und der der Interupt wird auch ausgelöst.
1)
send_string(datenbyte);
->
send_char(datenbyte);
2)
Du schreibst in den Puffer, ohne zu überprüfen, ob darin überhaupt noch
Platz ist.
3)
Du schaltest die Interrupts ein, bevor schreibzeiger initialisiert
ist.
4)
In main muss der Zugriff auf schreibzeiger vor der Unterbrechung durch
den Interrupt geschützt werden. Und wenn du den Sourcecode bezüglich 2)
änderst, auch die Zugriffe auf lesezeiger.
Kann es sein, dass Schreibzeiger immer auf den Anfang vom Array zeigt?
wenn ich in der ISR direkt send_string(*schreibzeiger) einfüge,bekomme
ich hallo, dann hallohallo, dann hallohallohallo etc. ??
Die Deklaration von schreibzeiger ist falsch. Der Zeiger selber muss
volatile sein, nicht das Ziel.
volatile char *schreibzeiger;
->
char * volatile schreibzeiger;
(die beiden anderen volatiles sind im aktuellen Code übrigens
überflüssig)
> wenn ich in der ISR direkt send_string(*schreibzeiger) einfüge
"send_string(*schreibzeiger)" ist schlicht Unsinn, genau wie das
"send_string(datenbyte)" im vorigen Code.
Arg,noch eine letzte Frage: Leider scheint der Zeiger nicht zum ANfang
zurückzuspringen, nachdem der Puffer voll ist... D.h. wird hallo\0
gesendet, kommt es bei puffer_groesse 50 9mal richtig an und beim 10.
mal nur ein teil und dann nicht mehr richtig. muss ich da auch was
anders deklarieren?
Das liegt daran, dass du in main lesezeiger nicht richtig verwaltest.
Spiel mal durch, was passiert, wenn bei Eintritt in den if-Block
lesezeiger auf ein '\0' zeigt.
Wieso finde ich die Arbeitsweise mit Pointern bei einem Ringpuffer nur
so umständlich?
Mit ein paar Variablen, die einfach die Indizes hochzählen, finde ich es
wesentlich leichter. Zumindest funktionieren meine Ringpuffer-Routinen
einwandfrei ohne Pointer-Operationen.
Natürlich ginge es mit einem Index einfacher, insbesondere wenn er als
Puffergröße auch noch eine 2er-Potenz wählen würde. Er wollte ja aber
wissen, warum sein Ansatz nicht geht, und die Antwort darauf lautet ja
nicht "mit Zeigern geht es gar nicht, nimm einen Index".
>und die Antwort darauf lautet ja nicht "mit Zeigern geht es gar nicht, nimm >einen Index".
Wohl wahr.
Klar geht es mit Zeigern. Nur sollte man schon etwas sicherer beim
Umgang damit sein...
STK500-Besitzer wrote:
> Wieso finde ich die Arbeitsweise mit Pointern bei einem Ringpuffer nur> so umständlich?
Weil sie es ist.
> Mit ein paar Variablen, die einfach die Indizes hochzählen, finde ich es> wesentlich leichter.
Und wenn ein Byte (0..255) als Index reicht, ist das sogar effizienter
(weniger Code, schneller):
Beitrag "AVR-GCC: UART mit FIFO"
Peter
Stefan Ernst wrote:
> insbesondere wenn er als> Puffergröße auch noch eine 2er-Potenz wählen würde.
Das spart gerade mal einen Befehl ein, lohnt also nicht.
Peter