Forum: Mikrocontroller und Digitale Elektronik Nochmal SW UART


von TheMason (Gast)


Angehängte Dateien:

Lesenswert?

ich versuchs nochmal ....

ich möchte einen sw uart in meinem projekt verwenden.
habe dazu testhalber den uart auch auf einem mega8 implementiert.
(mega8 läuft mit 16MHz und 19200bd sw uart, verwendet werden die 8 bit 
timer, timer 0 für tx, timer 2 und int0 für rx, port-pin seitigt liegt 
rx auf int0 (pd2) und tx auf int1 (pd3) ).
gebe die auf rx empfangenen zeichen einfach wieder auf tx aus, bis auf 
das ich 0xd und 0xa immer zu 0xd und 0xa mache und aus 0x9 0x20 mache, 
um sourcen einfach auszugeben (um "große" datenmengen zu testen).

soweit so gut, funktioniert soweit, bis auf einige aussetzer.
die aussetzer äussern sich im stehenbleiben einer übertragung von 8kB 
ASCII-Code per copy&paste im PuTTY. Starte ich PuTTY neu so läuft alles 
wieder (bis zum nächsten stehenbleiben).

nehm ich hyperterminal dauert die übertragung einer 8kB "sende als 
text-datei" ewig ... kommt aber anscheinend alles korrekt an.

habe meinen source mit denen von peter danneggers sw uart und mit denen 
von atmels half duplex interrupt driven application note 304 verglichen 
und stelle wenig unterschiede fest. sowenig das es eigentlich 
funktionieren müsste (was es ja auch prinzipiell tut).
lediglich verwende ich beide 8 bit timer im overflow modus.
wahlweise auch 16 bit mt 2 ccr (per #define). aber noch nicht weiter 
getestet.

meine frage(n) :
 - kann es sein das putty bei einem möglicherweise fehlerhaft 
empfangenen zeichen völlig aussetzt und bei hyperterminal einfach 
nochmal versucht ?
 - was könnte grundsätzlich an meinem ansatz falsch sein ? (in der app 
not e ist sogar noch zeit für ein switch-case) ?
   - fang ich mir eine akkumulation des phasen jitters ein, sodass bei 
4800 bd oder auch 19200 ein zu großer fehler enstehen kann ?
   - irgendwelche flags falsch (oder zum falschen zeitpunkt) gesetzt ?
   - grundsätzliche denkpannen / umsetzungsfehler ?
 - laufen die bitzeiten auseinander ?
   - überlagern sich die paar us ausführungzeit beim voll-duplex 
übertragen derart das gar nichts mehr läuft (es sind doch noch nichtmal 
1us bei 16 MHz)

meine bitte(n) :
 - schaut doch bitte mal eben (ich weiß das sacht man nicht) nach.
 - probiert es bitte jemand mal aus (ist hoffentlich nicht zuviel 
verlangt) und sagt mir ob eine text-datei mit xx kB größe einigermassen 
sauber ankommt (lediglich das erste zeichen einer neuen zeile kann 
fehlen)
 - kann mir jemand verraten warum sowas einfaches solche probleme 
verursacht ?
 - kann mir jemand sagen ob es an putty liegen kann ?

weitergehende fragen :
 - ist es soviel voodoo einen sw uart zu programmieren, wohl kaum, oder 
?

verdammich, das kann doch nicht sein, das ich bald wochen brauche um 
einen sw uart zu implementieren. das haben doch 500k andere leute schon 
gemacht.
warum klappt der mist nicht ?

bitte hilf mir mal jemand. bin echt entnervt das sowas simples
nicht sauber funzt und vorallem warum es nicht funzt, wo der ansatz doch 
so einfach ist ....

gruß
rene

von TheMason (Gast)


Lesenswert?

warum kann mir denn keiner was dazu sagen ?
fehlen infos ?
zu kompliziert ? zu trivial ?
leute, was ist los ?

von ghu (Gast)


Lesenswert?

Ganz einfach. Du hast hier schon einen anderen Beitrag erstellt, der 
einen drängeligen Eindruck macht.
Reduziere Dein Programm auf die SW UART und teste die Routinen 
gründlich. Erst dann packe Deine sonstigen Routinen dazu.

von TheMason (Gast)


Lesenswert?

habe ich doch gemacht ...

der beitrag vom 10.5. um 3uhr nochwas sagt doch das ich den sw uart 
standalone getestet habe. auch die quellsourcen zu dem stand-alone sw 
uart sind drin (allerdings erst einen beitrag später). ergebnis : nicht 
ein einziger hat sich das angeschaut.

ok was macht man dann ? man macht einen neuen beitrag auf damit nicht 
jeder erst den ganzen kladarradatsch komplett lesen muß und das problem 
nochmal ganz exakt und mit all meinen interpretationsmöglichkeiten der 
fehlerursache darstellt, die konfiguration (uC, quarz, pins, usw) und 
sourcen, und was ich versucht habe usw ...

ergebnis : auch nichts. (da kann dann schon etwas frust aufkommen)

warum es drängelt ?

weil mich dieser sch... sw uart ordentlich nerven kostet weil er eben 
prinzipiell funktioniert aber eben nicht 100% oder vielleicht doch zu 
100% aber eben meine terminal-sw einen bug hat (was möglich aber 
unwahrscheinlich ist).
ich möchte diesen uart in meinem projekt (es geht dabei um das 
audio-projekt, das auch so schon wenig resonanz findet [sorry für die 
meckerei]) einsetzen möchte und er da auch prinzipiell funktioniert 
(aber eben auch nicht 100%) wende ich mich eben an ein solches forum.

und es nervt einfach ein wenig wenn man bei einem (relativ) einfachen 
problem das man selbst schon fast gelöst hat, keinerlei antwort bekommt, 
bzw niemand drübergucken kann oder will.
wenn ich wüsste woran es liegt würde ich hier nicht schreiben, und das 
ein sw uart kein hexenwerk ist wissen denke ich auch die meisten.

drängeln ist nicht schön, ok, aber wenn bei weitaus einfacheren 
problemen innerhalb von minuten geantwortet wird, und ich bei meinem 
problem nur einige denksantösse brauche warum es nicht klappen kann (ich 
verlange ja kein funktionierenden sw uart auf nem silbertablett oder ?!, 
vielmehr habe ich ja mehrere ansätze selbst versucht und hoffe darauf 
das mir jemand sagen kann was genau falsch ist bzw. sein kann)

sorry wenn ich ein wenig pampig bin, aber ich bin einfach nur genervt 
das das teil fast komplett funktioniert, aber eben nur fast. und das mir 
keiner helfen kann, bzw. noch nichtmal in den code geschaut wird (wo 
doch sonst immer bemängelt wird das man zuwenig infos zu einem problem 
gibt)
ich sitze nun ja auch schon eine weile vor dem problem.

genug gemeckert. ich hoffe nun das jemand mir mal seine erfahrungen zum 
thema sw uart schildert.

gruß und einen schönen pfingstsonntag
rene

von TheMason (Gast)


Lesenswert?

hoffe es war nicht zuviel gemeckert ...

nochmals die bitte :

bitte hilf mir doch jemand mal. verzweifel echt daran.
es kann doch nicht sein das die empfangsfolge abreisst (und danach gar 
nichts mehr kommt kein int0 mehr).
es kann doch nur noch was mit den flags sein die ich in der INT0-ISR und 
in der T2-ISR setze.
laut datenblatt (und auch der app note) mache ich (scheinbar) alles 
richtig, oder ?
trotzdem reisst der empfang ab (in dem ziel-projekt schneller als auf 
dem reinen mega8-aufbau auf dem nur der sw uart läuft).

bitte helft mir doch.
macht echt kein spaß, wenn man an sowas trivialem kleben bleibt. vor 
allem habe ich schon x varianten durchgespielt. ergebnis ist immer 
dasselbe ...

gruß
rene

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Hast du den die anderen SW Uarts mal getestet? bzw warum nuzt du die 
nicht einfach?
Ansosnten bei Flags: eine 1 schreiben LÖSCHT das flag, sachen wie:

FLAGREGISTER = FLAGREGISTER | (1<<FLAG)

sind böse, weil damit alle anderen Falgs auch gelöscht werden!

#define RX_INT_FLAG      GIFR |=  (1 << RX_GIFR);

keine Ahnung ob das damit zusammenhängen kann, ich kenn mich mit 
SoftUART und C nicht genug aus.

von TheMason (Gast)


Lesenswert?

>warum nuzt du die nicht einfach?

weil ich evtl. nen zweiten sw uart brauche und bei peter danneggers 
lösung nur einer über icp angeschlossen werden kann. mit den externen 
interrupts ist man dann etwas flexibler (kann int0 oder int1 nutzen).
und in der app note wirds ja auch mit INT0 gemacht.
mich wurmt eben nur das es ja größtenteils funktioniert.

vllt. werde ich wirklich mal die app note oder peters lösung probieren.

>sind böse, weil damit alle anderen Falgs auch gelöscht werden!

#define RX_INT_FLAG      GIFR |=  (1 << RX_GIFR);

hast recht.
aber selbst mit GIFR = (1 << _GIFR) (und bei den timern) bringts keine 
änderung.
da schmiert die kommunikation dann noch eher ab ...
ich verstehs einfacht nicht ....

von holger (Gast)


Lesenswert?

>aber selbst mit GIFR = (1 << _GIFR) (und bei den timern) bringts keine
>änderung.
>da schmiert die kommunikation dann noch eher ab ...

Wie viele Interrupts hast du denn noch so am laufen ?
Der Software UART lebt davon das der Timer Interrupt immer
pünktlich kommt. Tut er das nicht, weil ein anderer
Interrupt ihn aufgehalten hat, dann kracht es logischerweise.
Baudrate stimmt nicht mehr.

Vollduplex solltest du besser auch komplett streichen.
Denk mal drüber nach: RX und TX laufen mit den gleichen Zeiten.
Du sendest im Beispiel alles was du empfängst als Echo zurück.
Und dann kommst du auf die grandiose Idee für z.B. 0x0D
ZWEI Zeichen zurückzusenden. Da wird ja wohl ein Zeichen
beim empfangen flöten gehen müssen.

Teste Empfang und Senden getrennt. Also kein Echo machen,
oder nur soviele Zeichen als Echo wie du auch empfängst.
Bleib bei Halfduplex beim Software UART. Und verwende nach
Möglichkeit keine weiteren Interrupts oder verbiete sie
je nach Sende/Empfangslage.

von TheMason (Gast)


Lesenswert?

@holger

>Wie viele Interrupts hast du denn noch so am laufen ?

beim versuchsaufbau keinen. (wie gesagt beschränke mich erstmal nur auf 
den SW UART). in der anwendung laufen noch ein timer und ein uart. der 
timer bedient nur ein paar (4-5) SW Timer. der uart-interrupt (nur rx) 
speichert seinen input, bzw. durchläuft eine kleine midi-statemachine.

>Der Software UART lebt davon das der Timer Interrupt immer
>pünktlich kommt.

ist klar soweit. je mehr verzögerung ich durch andere interrupts habe, 
desto mehr komme ich aus der bitmitte raus. also andere interrupts schön 
kurz halten.

>Denk mal drüber nach: RX und TX laufen mit den gleichen Zeiten.

auch klar. wobei tx denke ich kein thema ist. der interrupt ist sehr 
kurz.
rx braucht wegen der int umschaltung etwas länger und macht auch etwas 
mehr. das durch die quasi gleichzeitigkeit ein jitter ensteht ist auch 
klar, aber wie groß darf dieser werden bis es kritisch wird ?
ich habe bei 19200bd und 16mhz 833 takte pro bit-schritt. komme da 
später noch drauf zurück.

>Und dann kommst du auf die grandiose Idee für z.B. 0x0D
>ZWEI Zeichen zurückzusenden. Da wird ja wohl ein Zeichen
>beim empfangen flöten gehen müssen.

richtig, aaber :

das nehme ich an der stelle in kauf, das einzelne zeichen beim empfang 
nach einem zeilenumbruch flöten gehen. die gehen auch nur flöten weil 
ich keinen rx-fifo eingebaut habe.
ich habe das gemacht um putty einen crlf zu senden wenn ich nur ein cr 
bekomme.
mache das deswegen um einen stress-test zu machen. schicke dazu 8kb 
ascii-quellcode per putty raus und es muß alles (bis auf eben das erste 
zeichen am anfang einer neuen zeile) wieder ankommen.

>Bleib bei Halfduplex beim Software UART

warum ist vollduplex so kritisch ?
je höher meine uC frequenz, und je niedriger die baudrate desto 
unkritischer ist doch der sw-jitter auf der tx/rx leitung.
bei 19200bd und 16mhz habe ich von bit-mitte zu bit-mitte 833 takte.
selbst wenn ich 400 takte (das sind 25!!us, eine ewigkeit) "rumsauen" 
würde , hätte ich immer noch eine chance das bit rechtzeitig zu 
erwischen.

ich will meinen sw uart ja auch nicht mit 57.6k oder so laufen lassen.
er soll in der zielanwedung (in der ich um weitere interrupts nicht drum 
herum komme) mit max 9600 (schön wären eben 19200), aber von mir aus 
auch mit 4800 bd laufen. also habe ich noch mehr reserven bzw. der 
jitter wird unkritischer.

sehe ich das jetzt falsch ?!

>oder verbiete sie je nach Sende/Empfangslage.

selbst dann reisst der empfang ab. (habe cli/sei in der INT0 und in der 
RX-Timer ISR drin)

von holger (Gast)


Lesenswert?

>#define RX_INT_FLAG      GIFR |=  (1 << RX_GIFR);

Das solltest du wie oben schon gesagt wurde nicht machen.
Das zersägt dir dein Interruptsystem. Es muss mit der korrekten
Methode funktionieren oder du handelst dir Ärger an anderen Stellen ein.

#define RX_INT_FLAG      GIFR =  (1 << RX_GIFR);

>warum ist vollduplex so kritisch ?

Weil RX und TX sich die verfügbare Zeit teilen müssen ?

>>oder verbiete sie je nach Sende/Empfangslage.
>selbst dann reisst der empfang ab. (habe cli/sei in der INT0 und in der
>RX-Timer ISR drin)

Genau da bringen sie gar nichts. Wenn ein Interrupt beim AVR aufgerufen
wird sind andere Interrupts bis zum RETI verboten.

von TheMason (Gast)


Lesenswert?

>#define RX_INT_FLAG      GIFR |=  (1 << RX_GIFR);

>Das solltest du wie oben schon gesagt wurde nicht machen.

habs eingesehen, das es kritisch ist wenn gleichzeitig andere interrupts 
laufen und man sich u.u. andere flags plättet. wundert mich nur das die 
in ihrer app note das auch so machen.

#define RX_INT_FLAG      GIFR =  (1 << RX_GIFR);

ist schon etwas richtiger :-))

aber ich glaube ich verabschiede mich auch von dem gedanken das teil so 
in der anwendung laufen zu lassen. wäre halt ne schöne debugmöglichkeit 
gewesen.
muß ichs halt anders realisieren.

trotzdem danke an alle (die mein gemecker ausgehalten haben :-))

gruß
rene

von Peter D. (peda)


Lesenswert?

TheMason wrote:
>>warum nuzt du die nicht einfach?
>
> weil ich evtl. nen zweiten sw uart brauche und bei peter danneggers
> lösung nur einer über icp angeschlossen werden kann. mit den externen
> interrupts ist man dann etwas flexibler (kann int0 oder int1 nutzen).

Macht im Code doch keinen Unterschied, ob Du nun das ICR1 oder TCNT1 
ausliest.
Bei TCNT1 ist nur der Fehler größer durch die Interrupteintrittszeit, 
eventuell da einige Zyklen (20..50) abziehen.

Mit den 8Bit-Timern dürfte der Bitfehler meistens zu hoch sein, wenn der 
Prescaler nur in 8-er Potenzen einstellbar ist.
Der 8Bit-Timer für die UART ist also nur bei den ATtiny25..85 sinnvoll.

Wenn der Fehler so ist, daß der PC schneller sendet und Du keinen Puffer 
einrichtest, muß es bei größeren Datenpaketen unweigerlich krachen.

SW-UART mit Puffer z.B. hier:

Beitrag "LCD über nur einen IO-Pin ansteuern"


Peter

von TheMason (Gast)


Lesenswert?

>Macht im Code doch keinen Unterschied, ob Du nun das ICR1 oder TCNT1
>ausliest.

es ging sich darum das ich evtl. einen 2. sw uart (der noch langsamer 
laufen soll) mit implementiere. und das geht bei nur einem icp eben 
nicht :-)

aber das ganze hat sich erledigt.
ich machs per i2c. da kann ich dann entweder nen 2. avr als uart laufen 
lassen, bzw. den von meinem 2. board.
da verwende ich dann auch die app notes und es scheint zu funktionieren 
...

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
Noch kein Account? Hier anmelden.