Hallo! Ich habe folgendes Problem. Ich sende eine Zahl (4 stellig) als string mit vorangestellten "g" (falls weniger als 4 stellen wird mit Nullen voran aufgefüllt) an einem anderen mc (Beides Atmega8) Der 2.MC nimmt dann das was er empfängt und hängt das einer vorhandenen String Variable an. In der Hauptschleife wird dann gewartet bis die Anzahl der Zeichen im "empfangen String" auf über 10 angewachsen ist. Dann sucht er mit der instr- Funktion nach "g" und weiß, aha ab hier muss ich 4 stellen abschneiden und hab dann meine Zahl. Das Problem ist, das er durch das ganze abfragen und hantieren mit Stringvariablen sehr viel ressourcen braucht, was dazu führt, dass er nach unbestimmter Zeitdauer sich aufhängt) Habt ihr eine Idee, wie ich das Verfahren optimieren könnte? Wenn ich zb ein 4 stellige zahl sende, wird dann beim empfänger IC nur einmal der Interrupt ausgelöst, oder etwa pro empfangendes Byte? Dann könnte ich nähmlich gleich in der onrxd interrupt schleife die zahl in einer variablen abspeichen ohne in der hauptschleife ständig zu pollen. viele Grüße Axel
Wenn du sicherstellen kannst, dass z.B. ein CR nicht in deinem zu übertragenden String vorkommt, würde ich so ein Zeichen als Abschluss des Telegramms schicken, noch hinter einer Checksum, wenn du so etwas brauchst. Wenn du dann noch einen Hardware UART benutzt, kannst du in Bascom den Bytematch Interrupt verwenden. Du brauchst dann gar nicht zu pollen sondern liest die Zeichen alle zusammen aus dem Buffer ein. Das behindert den Rest deines Programms fast gar nicht. Gruß Rolf
sorry, aber das hört sich doch recht suboptimal / konzeptlos an. das läßt sich alles sauber und ohne jegliche ressourcenprobleme über interrupts lösen. in der bascom hilfe stehen schon komplette lösungen drin. sehr elegant auch das, sollte sofort so funktionieren : '0011.BAS: Optimierter String-Empfang $Regfile = "2313def.dat" $Crystal = 3686400 $Baud = 9600 Dim s As String*4 At &H60 Dim b(5) As Byte At &H60 Overlay Dim n As Byte On URXC OnRxD Enable URXC Enable Interrupts Main: If n > 4 Then Print s n = 0 End If Goto Main OnRxD: Incr n b(n) = UDR Return
Hallo! Dietmar, ich verwende ja bereits einen Interrupt dafür. Aber beide Beiträge waren dennch hilfreich - wenn ich abfrage IF n größer 4, kann ich ja nicht ausschließen, das irgendwas falsch übertragen wurde etc. Also muss ich schon noch son Abschlusszeichen nehmen. Ich probiere das mal mit dem Bytematch, den kannte ich noch garnicht)) Dann spare ich mir ständig das mit der Stringlänge. Kann man einfach Bytematch und dann den "buchstaben" (Abschluss vom telegramm) oder muss der Buchstabe als Asci stehen? Danke Danke!
Schau dir mal die Hilfe zu "Config Serialin" an. Unter Bytematch steht, dass dort der ASCII Wert angegeben werden muss, der den Interrupt auslöst. Gruß Rolf
@ axel, du kannst doch in der isr einfach abfragen ob das endezeichen angekommen ist, oder dein startzeichen, oder in kombination. Wenn du auch noch überprüfen willst ob auch alles richtig übertragen wurde dann musst du eh noch mit crs 's arbeiten, was aber auch nicht 100 % ig sicher ist und auch codeanpassungen auf der senderseite durchführen, falls das überhaupt möglich ist.. Bleib bei dem aufbau wie in meinem beispiel, damit hst du alles unter kontrolle und nutzt die controllermöglichkeiten und ressourcen optimal aus !
Dietmar S. wrote: > sorry, aber das hört sich doch recht suboptimal / konzeptlos an. > > das läßt sich alles sauber und ohne jegliche ressourcenprobleme über > interrupts lösen. > > in der bascom hilfe stehen schon komplette lösungen drin. > sehr elegant auch das, sollte sofort so funktionieren : > > > '0011.BAS: Optimierter String-Empfang > $Regfile = "2313def.dat" > $Crystal = 3686400 > $Baud = 9600 > > Dim s As String*4 At &H60 > Dim b(5) As Byte At &H60 Overlay > Dim n As Byte > > On URXC OnRxD > Enable URXC > Enable Interrupts > > Main: > If n > 4 Then > Print s > n = 0 > End If > Goto Main > > OnRxD: > Incr n > b(n) = UDR > Return So ich habe jetzt ewig hin und her probiert. Wenn ich s und b() so deklariere, dann bekomme ich eine Fehlermeldung - hab ich nicht mehr genau im kopf, aber irgendwas mit besetzt. Woran könnte das liegen? Aber mit dem Overlay, das sieht in der Tat ziemlich ressourcensparend aus. Das ist ja ziemlich raffiniert mit dem byte ins Stringformat - sonst kannte ich das nur mit dem befehl chr(). Das Ding ist, ich gebe die werte mit dem IC per Multiplexing auf 7 segment anzeigen aus - und wenn der Codeteil zu lang wird, dann leuchten sekundlich mal segmente, die garnicht leuchten sollen. Müsste ich nicht zwingend die 2 ms waitms einlegen nach jedem bitmuster, hätte ich das problem vielleicht garnicht(( Es lief ja schon, nur ich musste eine einzige If-Anweisung in der Hauptschleife hinzufügen und das war schon zuviel des guten..
ah ok mit dem overlay das klappt jetzt ich meld mich mal übermorgen wie es aussieht gruss axel
Hallo Axel, Overlays sind eine gute Art, die aufwändigen String Operationen zu vermeiden. Aber nicht so: Dim s As String*4 At &H60 Dim b(5) As Byte At &H60 Overlay Du hast ein Problem schon gesehen: Bascom geht die Dim Befehle der Reihe nach durch und setzt die Variablen beginnend am Anfang in den Speicher. Wo das ist, hängt von dem µC Typ ab. beim 2313 ist es tatsächlich die Adresse Hex60. Bei anderen Controllern ist der Start woanders. Daher nimmt man nie feste Werte. Es geht auch so: Dim s As String*4 Dim b(5) As Byte At s Overlay und schon hast du keine Probleme mehr mit der Reihenfolge der Variablen im Speicher. Und du kannst dein Programm jederzeit für andere Hardware ohne Fehler compilieren lassen. Wenn du Dietmars Anweisung folgst, wird der Interrupt bei jedem eintreffenden Zeichen auf RxD ausgelöst und du musst jedesmal überprüfen, ob schon alle Zeichen eingetroffen sind. Nimmst du Bytematch, wird nur ein Interrupt ausgelöst und du weißt, dass sie alle da sein müssen. Aber mach es so, wie du es willst. Gruß Rolf
Guten Abend) Ich habe schon Überlegungen zu dem Bytematch-Befehl angestellt und etwas herumprobiert. Wie können die Daten bei dem Gebrauch der bytematch Funktion am effektivsten aus dem Puffer geholt und gespeichert werden? Kann man eine Variable auch in diesem Fall via overlay zb auf die Specherstellen des UART Puffers legen? Aber selbst dann entfällt zwar das Polling, aber ich müsste den string ja trotzdem mit instr() durchsuchen um die position zu erfahren um dann mit dem mid() Befehl die 3 Zeichen davor einzeln herauszutrennen. Man könnte vielleicht auch alles aus dem empfangspuffer löschen und beim Bytematch dann einfach die ersten 3 Zeichen entsprechend abspeichern. Theoretisch , wozu es jedoch überaus sperrliche Informationen gibt, gibt es ja eben diesen Ringpuffer beim Uart und auch dafür schon festgelegte Variablen. _wpointer soll angeblich die Zahl enthalten, an welcher Stelle die letzte Ziffer gespeichert wurde. Dabei zeigt er aber einen syntax Fehler an...die Auskunft in der Hilfe bzw. sogar über google ist sehr dürftig. Dann müsste es doch gehen, wenn man bei Bytematch des Abschlusszeichens einfach in der Interrupt Routine die letzten 3 Speicherzellen davor ausliest und sofort in die dafür vorgesehenen variblen speichert, wobei das ja dem ähnlich wäre mit dem empfangspuffer löschen und beim Bytematch die ersten 3 Zeichen abspeichern. gruss Axel
so wie es aussieht funzt die variante - zumindesten kann ich das anzeigeflackern noch nicht feststellen Der ankommende string sieht so aus: "018g" Das array k steht für die einzelnen Ziffern der segmentanzeige. Config Serialin = Buffered , Size = 20 , Bytematch = 103 Dim X4 As String * 20 At _rs232inbuf0 Overlay Dim K(3) As String * 1 Serial0charmatch: K(1) = Mid(x4 , 1 , 1) K(2) = Mid(x4 , 2 , 1) K(3) = Mid(x4 , 3 , 1) Clear Serialin Return Danke für die Unterstützung!! gruß Axel
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.