Heute ist mir aufgefallen, sobald die eingegebenen Zeichen über den UART
die Zahl bei Size (hier 30) übersteigen und dann mit CR bestätigt wird,
hängt sich der Controller bei "Input Incoming_data Noecho" auf.
Aber warum eigentlich? Der Puffer sollte doch laut Bascom Hilfe ein
Ringpuffer sein, also sollte es keine Probleme geben.
Hat jemand ne Ahnung warum das passiert? Wenn ja evtl. was man dagegen
tun kann?
Gruß Andreas
Hm versteh ich jetzt nicht so ganz. Sobald CR empfangen wurde, wird
Serial0charmatch() aufgerufen und versucht den Buffer zu lesen.
Nur genau da bleibt der Controller hängen
Andreas schrieb:> Sub Serial0charmatch()> Local Incoming_data As String * 35>> 'Daten vom Buffer auslesen> Input Incoming_data Noecho> 'Ausgelesene Daten zurück schicken> Print Incoming_data> End Sub> [/code]
liegt es vielleicht daran, das du den Quelltext nicht 100% übernommen
hast?
Wäre nett wenns mal jemand schnell mit ner neueren Version simulieren
könnte.
Ich arbeite noch mit 11.9.8.
Vielleicht taucht ja das Verhalten da nicht auf.
AAAlllsoooo,
ich weis zwar nicht warum bei dir was nicht funktioniert, kann aber
mitteilen was bei mir seit vielen jahren perfekt funktioniert.
Hier also die abgewandelte Version deines Programmes:
1
$regfile = "m8def.dat"
2
$crystal = 8000000
3
$hwstack = 100
4
$swstack = 100
5
$framesize = 100
6
$baud = 38400
7
8
----> das muss weg : Declare Sub Serial0charmatch()
dorian schrieb:> ?>> wie soll da jemals die ISR "Serial0charmatch:"> angesprungen werden ?
genauso wie in dem Ursprungsquelltext die Sub Serial0charmatch()
angesprungen wurde.
Das ist in Bascom intern so declariert und steht in der
Bedienungsanleitung.
Gruss Klaus de Lisson
Ok vielen Dank für die Hilfe.
Auch bei Klaus´ Code hängt der Simulator bei mir, sobald meine Eingabe
länger als die 30 Zeichen ist. Wieder bei Input Incoming_data Noecho.
Ich werde später mal eine neuere Version ausprobieren.
Andreas schrieb:> Code hängt der Simulator
Hallo,
zu Simulator kann ich nix sagen, da ich den in all den Jahren noch nie
benutzt habe. In Hardware funktioniert es aber.
gruss
> Heute ist mir aufgefallen, sobald die eingegebenen Zeichen über den UART die
Zahl bei Size (hier 30) übersteigen
Ist halt immer die Frage, was die Implementierung des Ringbuffers in so
einem Fall dann macht.
Wird das Zeichen dann nicht mehr im Ringbuffer gespeichert, weil der
voll ist UND sucht INPUT auf jeden Fall nach dem Abschlusszeichen, dann
hängt das natürlich.
Ist aber reine Spekulation. Dokumentiert ist in dieser Richtung nichts.
Klaus De lisson schrieb:> zu Simulator kann ich nix sagen, da ich den in all den Jahren noch nie> benutzt habe. In Hardware funktioniert es aber.
Hm ok nun Version 2.0.7.5 probiert. Immer noch das selbe Problem im
Simulator. Na ja werds mal mit der Hardware versuchen.
Karl Heinz schrieb:> Wird das Zeichen dann nicht mehr im Ringbuffer gespeichert, weil der> voll ist UND sucht INPUT auf jeden Fall nach dem Abschlusszeichen, dann> hängt das natürlich.
Ja glaub auch, dass es daran liegt
Ja habs jetzt nochmal genauer angeschaut.
Anscheinend handelt es sich doch nicht um einen Ringpuffer. Der Puffer
wird einfach komplett vollgeschrieben. Kommt das Bytematch Zeichen, wird
Serial0charmatch aufgerufen, das Zeichen selbst wird jedoch nicht mehr
in den Puffer geschrieben, da dieser bereits voll ist.
Input versucht jetzt den Puffer bis zum Bytematch Zeichen einzulesen.
Das steht natürlich nicht drin -> Endlosschleife.
Da sich mein Programm beim Input Aufruf in der ISR Routine befindet,
bleibt der Controller für immer hängen.
Das Programm von Klaus ruft Input allerdings nicht in der ISR Routine.
Da Input den Puffer anscheinend zum Teil gelöscht hat, kann dieser
wieder Zeichen aufnehmen. Kommt jetzt wieder ein Bytematch Zeichen, wird
dies von Input ausgelesen und bleibt nicht mehr hängen.
Ja trotzdem irgendwie nicht zufriedenstellend.
Muss ich mir was anderes überlegen.
hier noch ne modifizierte MAIN zum testen:
'Hauptschleife
Do
if cr_received = 1 then
Input Incoming_data Noecho
print Incoming_data
Clear Serialin
cr_received = 0
end if
Loop
End
Klaus De lisson schrieb:> hier noch ne modifizierte MAIN zum testen:
Hilft leider auch nix, er bleibt ja schon bei "Input Incoming_data
Noecho"
hängen. Erst wenn wieder ein Bytematch Zeichen empfangen wurde, gehts
weiter.
Dann wird der Puffer durch Clear gelöscht, da is er aber schon leer, da
ihn bereits Input gelöscht hat ;-).
Andreas schrieb:> Erst wenn wieder ein Bytematch Zeichen empfangen wurde, gehts> weiter.
Heeeee ?,
was denkst du denn wofür die Routine entwickelt wurde ?
genau zu diesem Zweck.
Gruss Klaus
Klaus De lisson schrieb:> Heeeee ?,
Simuliers doch einfach mal, dann wirst dus feststellen.
Oder lies dir mal meinen Beitrag 06.12.2013 um 22:53 Uhr mal genauer
durch.
Dim B(uart_input_max_inc) As Byte At &H600 Overlay
15
Dim char_counter As Byte
16
Dim Message_received As Byte
17
18
19
On URXC OnRxD
20
Enable URXC
21
Enable Interrupts
22
23
Do
24
If Message_received = 1 Then
25
Message_received = 0
26
Print Input_data
27
End If
28
Loop
29
30
Onrxd:
31
If Message_received = 0 Then
32
If Udr = Char_match Or Char_counter >= Uart_input_max Then
33
B(char_counter) = Udr
34
B(char_counter + 1) = 0
35
Char_counter = 0
36
Message_received = 1
37
Else
38
B(char_counter) = Udr
39
Incr Char_counter
40
End If
41
End If
42
Return
Zur Erklärung:
Es wird solange eingelesen, bis das char_match Zeichen empfangen wurde
oder input_data voll ist. Ist input_data voll und noch nicht ausgelesen,
werden weiterhin empfangene Zeichen einfach verworfen.
Die Adresse der Variablen muss eventuell angepasst werden.
Das freut mich,
das Beispiel von Roland Walter ist sehr strukturiert und die Nutzung von
Overlays ist elegant.
Serielle Kommunikation ist so aufgebaut immer stabil.
Oh hab was vergessen:
Zeile "Dim Input_data As String * 10 At &H600"
muss durch "Dim Input_data As String * Uart_input_max At &H600"
ersetzt werden.
fertiger Code im Anhang
Gruß Andreas
Du solltest möglichst jede Verarbeitung aus der ISR rausnehmen und mit
Flags arbeiten.
Den Verarbeitungsteil machst du dann im Hauptprogramm, soweit das geht.
Isr schrieb:> Du solltest möglichst jede Verarbeitung aus der ISR rausnehmen und mit> Flags arbeiten.
Ja stimmt hab ich schon öfter gehört.
Habs jetzt in die ISR Routine, weils im AVR-GCC Tutorial auch so gemacht
wird. In der Arduino Bibliothek siehts genauso aus.
Außerdem gehts bei meinem Projekt nicht so zeitkritisch zur Sache.
Ich finds so einfach übersichtlicher ;-)
Wer will kann ja in der ISR nur ein Flag für den Empfang eines Zeichens
setzen und den String dann in der Main zusammenfügen.
Andreas schrieb:> Isr schrieb:>> Du solltest möglichst jede Verarbeitung aus der ISR rausnehmen und mit>> Flags arbeiten.>> Ja stimmt hab ich schon öfter gehört.
Warum wohl;-)
>> Habs jetzt in die ISR Routine, weils im AVR-GCC Tutorial auch so gemacht> wird. In der Arduino Bibliothek siehts genauso aus.
Das bedeutet nicht, dass es nicht auch besser geht.
>> Außerdem gehts bei meinem Projekt nicht so zeitkritisch zur Sache.> Ich finds so einfach übersichtlicher ;-)
Kleiner Denkfehler;-):
auf die Geschwindigkeit der eingehenden Zeichen hast Du keinen Einfluss,
außer über die Baudrate.
Deine Mainroutine wird eh vom Interrupt zum Schweigen gebracht.
Wenn nun aber die Zeichen so schnell eintrudeln, dass die ISR beim
nächsten Zeichen noch gar nicht fertig ist, dann funktioniert das nicht
mehr.
Dreh die Baudrate hoch und irgendwann läuft Dein , nicht vorhandener
(hardwareabhängig), Puffer über.
Vielleicht geht das trotzdem noch bei max. Baudrate ( rechne das mal
nach, schöne kleine Übung).
Du wirst erkennen, dass Du den Kollegen Zufall zu sehr strapazierst.
Machs sauber und professionell, so wie es sich für den Ingenieur auch
gehört.
>> Wer will kann ja in der ISR nur ein Flag für den Empfang eines Zeichens> setzen und den String dann in der Main zusammenfügen.
Mit " Wollen" hat das nichts zu tun, sondern mit funktionierendem
Code;-).
Mach fertig und zeigs uns, dafür haben wir Dich schließlich auf die Spur
gebracht.
Isr schrieb:> Mach fertig und zeigs uns, dafür haben wir Dich schließlich auf die Spur> gebracht.
da ist doch mal ein gutes Wort zum Sonntag, wie es sich gehört.
Daumen hoch!
Gruss Klaus de Lisson
Isr schrieb:> Kleiner Denkfehler;-):
Eigentlich dachte ich an was anderes mit Zeitkritisch:
In den Interrupts sollte man ja nur Flags setzen, da ein längerer
Aufenthalt in der ISR andere Interrupts blockiert.
Auch wenn sich der Controller bei mir länger in der ISR Onrxd befindet
macht das nix, da es keine anderen wichtigen Interrupts gibt.
> auf die Geschwindigkeit der eingehenden Zeichen hast Du keinen Einfluss,> außer über die Baudrate.
Stimmt allerdings.
> Deine Mainroutine wird eh vom Interrupt zum Schweigen gebracht.> Wenn nun aber die Zeichen so schnell eintrudeln, dass die ISR beim> nächsten Zeichen noch gar nicht fertig ist, dann funktioniert das nicht> mehr.> Dreh die Baudrate hoch und irgendwann läuft Dein , nicht vorhandener> (hardwareabhängig), Puffer über.> Vielleicht geht das trotzdem noch bei max. Baudrate ( rechne das mal> nach, schöne kleine Übung).
Ja kann gut passieren.
Wenn der Controller zu langsam ist um die eingehenden Zeichen zu
verarbeiten, dann hilfts aber auch nix, wenn sich der Code zum Auswerten
in der Main befindet. Es werden in der ISR zwar die Flags für ein neues
Zeichen gesetzt aber die Auswertung ist zu langsam um diese zu
verarbeiten.
Andreas schrieb:> Ja kann gut passieren.> Wenn der Controller zu langsam ist um die eingehenden Zeichen zu> verarbeiten, dann hilfts aber auch nix, wenn sich der Code zum Auswerten> in der Main befindet. Es werden in der ISR zwar die Flags für ein neues> Zeichen gesetzt aber die Auswertung ist zu langsam um diese zu> verarbeiten.
Du hast das noch nicht so ganz verstanden:
Es hat niemand gesagt in der ISR NUR Flags zu setzen.
Die muss halt so knackig kurz sein, dass dein Ziel immer erreicht wird.
Du musst es so bauen, das deine eingehenden Zeichen nicht verloren gehen
können, also auf alle Fälle in einem Puffer landen (Array/String)...
In der ISR kannst Du durchaus nach dem Motto alter string = alter string
+ neues Zeichen vorgehen.
Damit hast du doch alles erreicht.
In der Hauptschleife kannst Du in Ruhe all das tun was getan werden soll
du verlierst keine Zeichen.
Denk da nochmal gaanz in Ruhe und logisch drüber nach ;-)
sokrates schrieb:> Es hat niemand gesagt in der ISR NUR Flags zu setzen.
Na ja aber "möglichst nur" hieß es.
> Die muss halt so knackig kurz sein, dass dein Ziel immer erreicht wird.> Du musst es so bauen, das deine eingehenden Zeichen nicht verloren gehen> können, also auf alle Fälle in einem Puffer landen (Array/String)...
Meine Interruptroutine aus dem ersten Beispiel ist für mich kurz und
knackig genug, damit bei 9600 Baud keine Zeichen verloren gehen. Mehr
wollt ich eigentlich nicht. Amen.
Wers besser kann, der soll doch bitte einfach den Code posten.
Trotzdem Danke
Andreas schrieb:> Aber ich hab doch noch was.>> Ich hoffe jetzt ist jeder Glücklich :-)>> Gruß Andreas
ANDREAS..
.. es geht doch garnicht darum das wir glücklich sind.
... wir waren es doch zuvor schon
.... du warst der, der unglücklich war weil deine Software nicht funzte
. nun scheinst du glücklich zu sein und alles ist gut.
isr2
Was von dem, das C normalerweise von seinen Fans angekreidet wird, hat
BASCOM hier eigentlich nicht gezeigt? Overlay vs. union; AT &H123, huch
das ist ja ASM; dazu passt auch $hwstack, $swstack, $framesize, darum
kümmert sich bei mir GCC und ld; simpler Array-Überflauf a la C führt
zum Crash; Bibliothek von Funktionen, die man im Zweifel besser nicht
nutzt;
Für mich ist das nicht einfacher als C und wenn's nicht reicht, ich sag
nur:
1
Messwert=((a&0xfc)/2)*BASE_RATIO;
Wie schreibt man das nochmal in BASCOM?
Ja Timm Thaler, das ist in BASCOM nicht unüblich, sondern unmöglich.
Ja ja der einzige Vorteil von Bascom sind die vorhandenen Bibliotheken
und der Zugriff auf einzelne Pins ohne Bitmanipulation.
Die Leistungsfähigkeit des Compilers lässt teilweise doch zu wünschen
übrig. Fehlermeldungen sind oft nichtssagend.
?
Wo ist denn hier ein Problem aufgetreten welches sprachabhängig ist?
Bleib mal bei dem Beispiel ohne in Allgemeingeschwafel zu verfallen.
Das ist doch ein schönes Beispiel welches zeigt, das die Probleme oft im
fehlenden Verständnis genereller Dinge liegt.
Eigentlich hatte ich an einigen Beispielen aufgezeigt, daß dieser
COMPILER, ich hatte nichts zur Sprache geschrieben, einiges an Klippen
liefert, die seine Anhänger normalerweise C zuschreiben. Aber das ist
dann ja böses BASCOM Bashing, weil nicht sein kann, was nicht sein darf.