Wie ihr sehen könnt lasse ich mir den String dabei immer zurückgeben und
mir ist aufgefallen, dass immer mal wieder das 3.Zeichen fehlt.
Also hab ich mal IsCharWaiting() rausgeschmissen und siehe da, es
funktioniert. Jetzt ist aber mein Programmablauf zu lang, also habe ich
nach Alternativen für IsCharWaiting() gesucht. (Inkey hat das gleiche
Problem)
und bin auf UART Interrupts gestoßen, die wohl genau diesem fehlen von
Zeichen vorbeugen soll.
Aber ich konnte niergends einen erklärten Befehlssatz finden, maximal
ein paar Beispielprogramme, aber anhand derer verstehe ich leider nicht,
was genau ich jetzt für mein Programm wo an Befehlen brauche.
Ich nutze einen ArduinoNano mit einem Bascom Programm.
Ich wäre euch für Befehle, mitsamt Erklärung echt dankbar.
Also schon mal Danke im Vorraus
Myster_Levoltie
Von Rowalt.de.
Perfekt!
'0011.BAS: Optimierter String-Empfang
$Regfile = "2313def.dat"
$Crystal = 3686400
$Baud = 9600
Dim s As String*10 At &H60
Dim b(11) As Byte At &H60 Overlay
Dim n As Byte
On URXC OnRxD
Enable URXC
Enable Interrupts
Main:
If n > 9 Then
Print s
n = 0
End If
Goto Main
OnRxD:
Incr n
b(n) = UDR
Return
Thx Adam P.
Der 1.Link war zwar nur Taster und Timer interrupts, aber im 2. Hab ich
was gefunden.
Keine Ahnung, wieso ich diese seiten bei meiner eigenen Recherce nicht
gefunden hab, ist saß da schon ne weile Dran, vermutlich bin ich blind,
blöd, oder beides xD.
Auf jeden Fall danke für die Hilfe
Uart overlay schrieb:> Dim s As String*10 At &H60
Sicher, daß man Strings händisch plazieren muß, bzw. überhaupt darf?
Das sollte ja der Compiler besser machen können. Z.B. beim ATmega328 ist
an &H60 noch gar kein RAM. Händisches Plazieren kann also schnell mal in
die Hose gehen.
Eine feste Zeichenzahl ist recht unflexibel. Typisch liest man Strings
bis zum CR/LF ein.
Natürlich muß man auch auf Pufferende testen, damit nicht der RAM
überschrieben wird.
Adam P. schrieb:> - http://staff.ltam.lu/feljc/electronics/bascom/BASCOM_Tutorial_2.pdf
Also ich hab es jetzt mit dem von diesem Link gemacht und das klappt
auch soweit, aber wenn ich das 1.Mal nach dem Starten des Programms/µC
einen Befehl hinsende fehlt immernoch das 3. Zeichen, bei jeglichen
danach, funktioniert es jetzt einwandfrei.
Irgendwelche Ideen Adam?
Myster L. schrieb:> Irgendwelche Ideen Adam?
Sorry, ich programmier in C.
Grundsätzlich:
Wird ein Interrupt für den Empfang benutzt,
dann sollten eigentlich keine Zeichen verloren gehen.
Ich hab leider keine Wahl als Bascom zu nehmen. :/ (Azubi eben)
Also ich mach es wie im code oben auch, ich setzt mir in der URXC
einfach wieder das Merker-Bit und werte es im Hauptprogramm aus, weil
sonst später zu viel Zeit verloren geht, wenn ich das in der ISR machen
würde.
(Ganz nebenbei, dass ich denke, dass es gar nicht geht, die Zeichen alle
auf einmal in der ISR auszulesen, weil für Input-Befehl URXC disabled
sein muss)
Naja, wenn ich eindeutig sagen kann, dass es nur beim 1. Befehl ist,
dass lässt sich ja durch nen Dummy-Befehl, der beim Starten des Systems
1. Hingesendet wird lösen. Hauptsache der Nutzer später hat kein Problem
mehr.
Nochmal danke dir.
Falls du in dem Interrupt nur das Zeichen empfängst und dieses dann aber
erst in der Hauptschleife einem String zuweist...dann kann es schon
passieren.
Myster L. schrieb:> ich setzt mir in der URXC> einfach wieder das Merker-Bit und werte es im Hauptprogramm aus
Das ist dann zu spät.
Du musst im Interrupt das Zeichen nehmen und dem String anhängen.
Adam P. schrieb:> Das ist dann zu spät.> Du musst im Interrupt das Zeichen nehmen und dem String anhängen.
Ich kann den String nicht im Interrupt auslesen, das würde zu viel Zeit
kosten, das Programm hat später sehr viele Interrupts, da es einen
Schrittmotor mit bis zu 4000U/min steuern muss und der darf halt echt
nicht ruckeln.
Myster L. schrieb:> da es einen> Schrittmotor mit bis zu 4000U/min steuern muss
Dann würde ich es erst recht nicht mit Bascom machen...sag das mal
deinem schlauen Ausbilder :-D
Myster L. schrieb:> Adam P. schrieb:>> Das bezweifel ich...wer sagt das?>> Dein Link:> http://staff.ltam.lu/feljc/electronics/bascom/BASCOM_Tutorial_2.pdf> Seite 5, steht auch extra Rot dran...
Ah ok, interessant...aber bzgl. Zeit.
Ob du nun im Interrupt eine Variable auf 1 oder 0 setzt oder ob du einer
Variable ein Zeichen zuweist...das sollte aufs gleiche hinauslaufen.
Adam P. schrieb:> Dann würde ich es erst recht nicht mit Bascom machen...sag das mal> deinem schlauen Ausbilder :-D
Ich hab wie gesagt leider keine Wahl. Er ist auf Bascom spezialisiert,
gelernt hab ich zwar auch C, aber hier muss ich leider Bascom verwenden.
:/
Adam P. schrieb:> Ob du nun im Interrupt eine Variable auf 1 oder 0 setzt oder ob du einer> Variable ein Zeichen zuweist...das sollte aufs gleiche hinauslaufen.
Auch bei einem String mit bis zu 12 Zeichen?
Myster L. schrieb:> Auch bei einem String mit bis zu 12 Zeichen?
Ja weil im Empfangsregister nur 1 zeichen Platz hat.
Ein Interrupt Aufruf = 1 Zeichen.
Schau ins Datenblatt vom µC.
Da gibts kein Platz für nen String, nur 1 Zeichen.
Myster L. schrieb:> Dazugehörige ISR:> Serialinterrupt:> NeueDaten = 1> Return
Das ist Quatsch mit Soße.
Du mußt das Zeichen in einem Puffer ablegen und den Puffer weiterzählen.
Üblich nennt sich sowas FIFO.
Also wie gesagt: in Kombination mit dem Hauptprogramm teil funktioniert
es aktuell einwandfrei. Hab über 100 Befehle hingesendet, kein Zeichen
hat gefehlt.
Myster L. schrieb:> Also wie gesagt: in Kombination mit dem Hauptprogramm teil funktioniert> es aktuell einwandfrei. Hab über 100 Befehle hingesendet, kein Zeichen> hat gefehlt.
Ja wie nun...was hast jetz geändert?
Dachte es funktioniert nicht beim ersten mal...
Myster L. schrieb:> Teil im Hauptprogramm:if NeueDaten = 1 then> NeueDaten = 0> Disable URXC> Input , Datain> Enable URXC>> Dazugehörige ISR:> Serialinterrupt:> NeueDaten = 1> Return
Da hatte ich doch den Code gepostet
Adam P. schrieb:> Dachte es funktioniert nicht beim ersten mal...
Früher hat regelmäßig das 3. Zeichen gefehlt, jetzt fehlt es nur beim
allerersten Befehl
Myster L. schrieb:> Da hatte ich doch den Code gepostet
Ja und hast gesagt:
Myster L. schrieb:> Also ich hab es jetzt mit dem von diesem Link gemacht und das klappt> auch soweit, aber wenn ich das 1.Mal nach dem Starten des Programms/µC> einen Befehl hinsende fehlt immernoch das 3. ZeichenMyster L. schrieb:> Früher hat regelmäßig das 3. Zeichen gefehlt, jetzt fehlt es nur beim> allerersten Befehl
Also funktioniert es noch nicht!
Myster L. schrieb:> Früher hat regelmäßig das 3. Zeichen gefehlt, jetzt fehlt es nur beim> allerersten Befehl
Hi,
dann ist es aber immer noch nicht sauber.
Peter D. schrieb:> Du mußt das Zeichen in einem Puffer ablegen und den Puffer weiterzählen.> Üblich nennt sich sowas FIFO.
Oder Ringpuffer.
ciao
gustav
Jo, das Korrekt.
Ausgangssituation bevor ich mich ans Vorum gewendet habe:
REGELMÄßIG fehlte bei hingesendeten Datenstring das 3. Zeichen
Jetzt, nachdem ich es mit deinem Link gemacht habe:
NUR beim 1. mal hinsenden, nach starten des Programmes/µC fehlt das 3.
Zeichen.
Jeder Befehl danach ist sauber!
Karl B. schrieb:> Hi,> dann ist es aber immer noch nicht sauber.
Das stimmt schon.
Aber es ist schon mal deutlich besser als vorher. ;)
Solange es nur der allererste Befehl ist, kann ich da mogeln und einfach
einen Dummy-Befehl automatisch hinsenden lassen, sodass alle Befehle vom
Benutzer dann funktionieren.
Nicht elegant, aber funktionsfähig. Mir geht halt leider die Zeit aus...
Myster L. schrieb:> Jeder Befehl danach ist sauber!
Das ist trotzdem falsch...Kannst ja auch net sagen:
"Beim ersten Flugzeugstart an einem Tag fallen alle Instrumente aus,
ABER danach läufts" :-D
Ich hab grad mein Sozialen...
Wie heißt die Entwicklungsumgebung bzw. Compiler?
Dann versuch ich das eben selbst und messe die Zeiten mit nem
LogicAnalyser.
Adam P. schrieb:> "Beim ersten Flugzeugstart an einem Tag fallen alle Instrumente aus,> ABER danach läufts" :-D
Naja, fliegen wird es dann vermutlich nicht mehr. :-D
Aber etwas Sport schadet ja nicht. xD
Myster L. schrieb:> Aber es ist schon mal deutlich besser als vorher. ;)
Du hast aber das Problem nicht gelöst. Es wird Dir daher wieder auf die
Füße fallen, sobald das Programm etwas mehr zu tun hat.
So ist der Interrupt vollkommen sinnlos. Du kannst auch im Main das
RXC0-Flag direkt testen.
Peter D. schrieb:> Du hast aber das Problem nicht gelöst. Es wird Dir daher wieder auf die> Füße fallen, sobald das Programm etwas mehr zu tun hat.
Wie meinst du das, also von welcher Situation sprichst du genau?
Myster L. schrieb:> also von welcher Situation sprichst du genau?
Von der die immer dann Eintrifft, wenn man am wenigstens damit
rechnet...
und dann geht der ganze Spaß erst richtig los, weil man erstmal gar
nicht weiß woran es liegt.
Myster L. schrieb:> Dazugehörige ISR:> Serialinterrupt:> NeueDaten = 1> Return
Der Interrupt ist nicht nur vollkommen nutzlos, er feuert auch
ununterbrochen, bis die Mainloop das RXD ausliest. Das Main läuft dabei
mit etwa 1% CPU Takt, also bei 8MHz Quarz effektiv mit 80kHz.
Daß da überhaupt noch irgendwas funktioniert, halte ich für ein Gerücht.
Ich vertrau euch ehrlich gesagt mehr als mir selbst, was das hier
angeht, daher bin ich grad am umschreiben mit
1
Serialinterrupt:
2
incr nDataina(n) = UDR
3
Return
damit sollte ich die Zeichen dann ja schon mal alle in dem Array haben.
Meine Verarbeitung basiert aber darauf, dass es ein String ist. Da
direkt einen String zu verwenden ging nicht so einfach, also brauche ich
ja theoretisch nur noch ne möglichkeit das Array jetzt in nen String zu
konvertieren, richtig?
Adam P. schrieb:> Wie wäre es damit?
Hab es grad eben angepasst einprogrammiert und bisher läuft es gut, aber
ich habe 2 Fragen:
1. Wie lange braucht diese Interrupt Routiene?
2. Wie ist die Priorität dieser ISR? Ich habe eine Tabelle angehängt, du
weißt nicht zuällig welche dieser Interrupts es ist, oder?
(Mir geht´s darum, ob höher, oder niedriger priorisiert als timer1
compare)
aber bisher sieht es ganz gut aus.
(Nicht, dass ich besonders viel ahnung hätte. Ich bin zwar unter
meinesgleichen ganz gut was Programmieren angeht, aber in 3Jahren und
nur nebenbei, lernt man halt nur begrenzt viel :) )
Pandur S. schrieb:> Allenfalls kann man den Strin auch verarbeiten wehrend er reinkommt,> dann erspart man sich das Abspeichern.
Nope, dafür ist die verarbeitung viel zu groß. Ich habe alle
Informationen auf geringe Zeichenmenge komprimiert, dass ist gut für die
Übertragung, aber die Auswertung braucht halt länger.
Peter D. schrieb:> Uart overlay schrieb:>> Dim s As String*10 At &H60>> Sicher, daß man Strings händisch plazieren muß, bzw. überhaupt darf?
Ja, Bascom Overlays sind eine feine Sache.
> Das sollte ja der Compiler besser machen können. Z.B. beim ATmega328 ist> an &H60 noch gar kein RAM. Händisches Plazieren kann also schnell mal in> die Hose gehen.
Wozu dient wohl diese Zeile?;-)
$Regfile = "2313def.dat"
Natürlich soll das im RAM liegen, also DABLA wälzen.
Basom wird da aber schon meckern!
>> Eine feste Zeichenzahl ist recht unflexibel. Typisch liest man Strings> bis zum CR/LF ein.> Natürlich muß man auch auf Pufferende testen, damit nicht der RAM> überschrieben wird.
Ja, kommt immer darauf an was man will;-)
AF schrieb:> Natürlich soll das im RAM liegen, also DABLA wälzen.
Oder den Compiler sich automatisch drum kümmern lassen, denn dazu ist er
ja da. Warum ihm also ins Handwerk pfuschen, das ergibt doch keinen
Sinn.
Laß das "At &H60" ganz einfach weg.
AF schrieb:>> Eine feste Zeichenzahl ist recht unflexibel. Typisch liest man Strings
Naja, ich weiß ja genau, welche Befehle gesendet/empfangen werden, d.h.
kein Grund mehr Speicherplatz zu verschwenden, als nötig. ;)
Myster L. schrieb:> Naja, ich weiß ja genau, welche Befehle gesendet/empfangen werden, d.h.> kein Grund mehr Speicherplatz zu verschwenden, als nötig. ;)
Das ist nicht der Punkt.
Eine feste Länge bietet keine Möglichkeit der Paketsynchronisation.
Schaltet man nicht beide Seiten gleichzeitig ein oder treten Störungen
auf, bleibt man für alle Zeit asynchron und empfängt immer nur Mumpitz.
Ein Endezeichen ist quasi das minimalste Protokoll mit Fehlerbehebung.
Gerne fügt man vor dem Endezeichen auch noch 2 Hex-Digits als CRC ein.
Peter D. schrieb:> Das ist nicht der Punkt.> Eine feste Länge bietet keine Möglichkeit der Paketsynchronisation.> Schaltet man nicht beide Seiten gleichzeitig ein oder treten Störungen> auf, bleibt man für alle Zeit asynchron und empfängt immer nur Mumpitz.> Ein Endezeichen ist quasi das minimalste Protokoll mit Fehlerbehebung.> Gerne fügt man vor dem Endezeichen auch noch 2 Hex-Digits als CRC ein.
Absolut korrekt, dafür hat man auch mal ASCII Zeichen wie STX und ETX
definiert.
Auf irgendwas muss man sich "synchronisieren".
Natürlich ist eine Synchronisation sinnvoll. Aber dafür braucht man, so
viel ich den vorligenden Fall verstanden habe, keine variable Länge.
Wenn das Schlusszeichen nicht mit dem Ende des Speichers zusammenfallt,
hat man den Anfang verpasst. Wenn die Messagelänge immer gleich ist,
dann heisst doch, dass pro "Burst" diese maximale Anzahl zeichen kommen,
wenn nicht synchron, dann weniger.