PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RS232 Serielle Kommunikation und Probleme mit Strings



Mindchanger
01.12.2006, 05:48
Hallo.

Ich habe momentan ein kleines Problem mit meinem rnbfra und dem Mega32 bezüglich der Kommunikation über UART.
Der Controller soll Strings empfangen und Rückgabewerte ausgeben.
Die Gegenseite (PC) mache ich mit C#.
Die C# Form besteht aus einem Button und 2 Textfeldern.
In das eine Textfeld kommt der String, der per button an die Com geschickt wird und dann an den Controller versendet wird.
Leider kommt der Controller dabei nicht mit.
Ich habe bascomseitig folgendes verwendet:
Ich benutze ischarwaiting und anschließendes inkey().
Das inkey Char wird dann in einen string gepackt --> so wird der Befehl den ich übertragen will aufgebaut.
Das klappt per Hyperterm prima, da ich jedes Zeichen einzeln eingebe und mit einem "?" den Befehl abschließe. Der Controller gibt ihn dann per "print" aus und er landet in C# im zweiten Textfeld.

Wenn ich aber nun per C# den String übergebe (nicht per Hyperterm), nimmt der Controller natürlich nur den ersten Char des Strings an, da er vermutlich nicht hinterherkommt.
Also habe ich den String in C# in ein Chararray konvertiert und lasse nun die Zeichen einzeln übertragen. Dabei muss ich aber zwischen jedem Zeichen soviel Timout einfügen, dass er für einen Befehl wie "#led_an,1100" fast 3 Sekunden brauch.

Hat jemand eine Idee, wie ich in Bascom, bzw. im Controller, Strings annehmen kann, die z.B. in einem Eingangspuffer landen und dann zusammengesetzt werden?
Oder hat jemand generell eine gute Musterlösung, wie man am sinnvollsten die Kommunikation mir RS232 verwirklicht, bzw. was sich allgemein am meisten bewährt hat?




Dim A As Byte
Dim Temp As String * 1
Dim Befehl As String * 15
Dim Stringlänge As Integer
Dim Parameter As Integer
Dim B As Integer

Print "Waitkey- Abbruch mit Escape"
Do
Start:
A = Ischarwaiting()
A = Inkey()

If A = 35 Then ' hat eine # bekommen --> Befehlt folgt

Print Chr(a) ; " Befehlscommando empfangen " ; A
Temp = Chr(a)
Befehl = Befehl + Temp
Stringlänge = Len(befehl)
Print "Stringlänge : " ; Stringlänge
Goto Weiter

Elseif A <> 35 Then

Goto Start

End If

Weiter:
Do
A = Ischarwaiting()
A = Inkey()

If A <> 63 And Stringlänge > 0 And A <> 0 And A <> 44 Then ' 63 = ? = Ende des Befehls

Print Chr(a) ; "Char eines Befehls erkannt " ; A
Temp = Chr(a)
Befehl = Befehl + Temp
Print "Der Befehl lautet bisher: " ; Befehl
Print "der letzte Char war: " ; A

Elseif A = 44 Then ' 44 steht für , Komma - ab hier Parameter

Inputbin Parameter , B
Printbin Parameter ; B

End If

Loop Until A = 63 'Abschlusszeichen des Befehls 63 = ?

Print " Abschlusszeichen erkannt, Befehl lautet: " ; Befehl ; Parameter



Mfg

Marius

albundy
01.12.2006, 14:29
Hallo Marius,

ich habe etwas ähnliches auch schon gemacht.
Dazu musst du aber Hardware UART benutzen.
Mit einem geeigneten Quarz, kannst du die Baudrate
dann auch auf 115200 setzen.


$regfile = "m8def.dat"
$crystal = 8000000
$baud = 38400 '0,16% Fehlerrate bei 8 MHz

On Urxc Empfang 'ISR Empfangsroutine
Enable Urxc
Enable Interrupts

Dim Befehl As String * 15 , Para As String * 4 , Parameter As Integer
Dim E_byte As Byte , E_flag As Byte

Do
If E_flag = 3 Then 'Empfangsstring komplett
Parameter = Val(para) 'aus String Integer machen
Print "Befehl: " ; Befehl ; " - " ; "Parameter: " ; Parameter
Befehl = "" 'Befehl löschen
Para = "" 'Parameter löschen
E_flag = 0 'Empfang neu setzen
End If
Loop

End

Empfang:
E_byte = Udr
Select Case E_byte
Case 35 : E_flag = 1 '"#" = Befehl kommt
Case 44 : E_flag = 2 '"," = Parameter kommt
Case 13 : E_flag = 3 '"ENTER" = Empfang komplett
Case Else:If E_flag = 1 Then Befehl = Befehl + Chr(e_byte)
If E_flag = 2 Then Para = Para + Chr(e_byte)
End Select
Return

Damit kannst du den kompletten String vom PC an den Controller schicken, ohne das etwas verloren geht.

Vitis
01.12.2006, 21:10
korrekt, hardware interrupt verwenden hilft oft weiter,
oder in der mainloop anstatt ischarwaiting und inkey
einfach waitkey verwenden, da kannste dir n großteil
der highlevelbefehle von bascom schenken.
per goto aus ner if-bedingung raus springen ist auch nicht gerade
perfekter code, würd ich lassen.
die geschcihte mit dem String ist auch so ne Sache.
eleganter gehts mit Overlayvariablen.
Dann kanste einfach die empfangenen bytes hintereinander
reinschreiben ala Ringpuffer.

Mindchanger
06.12.2006, 05:20
Hallo.

Vielen Dank schonmal für die Hilfe. Bin leider erst gestern zum Testen gekommen.
Alles läuft soweit prima.
Habe meinen Code jetzt etwas verfeinert und es klappt.

Leider muss ich jetzt erstmal meine Zeit weiter in c# investieren, da ich dort einige Probleme mit threading bezüglich Zugriffe auf Objekte der Form habe. Bringt mich noch zum Wahnsinn :-)

Ich meld mich wieder.

Dankeschön

Marius