Forum: Mikrocontroller und Digitale Elektronik Bascom und ATMega 8, String zerlegen, auf kommandos reagieren


von Matthias B. (matthias_b14)


Angehängte Dateien:

Lesenswert?

Ich weiß grad nicht mehr weiter. Wollte wie oben angegeben einen ATMega8 
dazu bewegen Strings, welche er per RS232 erhält, zu zerhacken und die 
Schnipsel entsprechend zu verarbeitet. Ein String über RS232 soll dabei 
folgende Form haben: <Startbyte><Adresse><kommando><Optionale 
Parameter><CR>. Bisher habe ich das ganze mit #001adr" getestet. Das 
Zerhacken ist mir auch ganz gut gelungen, nur macht der µC danach was er 
will. Später soll das Programm die Befehle über RS232 empfangen und über 
eine Software UART passende kommandos über RS485 versenden (bin erst am 
anfang;)). Hier erstmal der Code:
1
'##########################################################################
2
 $regfile = "m8def.dat"
3
 $crystal = 8000000
4
 $hwstack = 100
5
 $swstack = 100
6
 $framesize = 100
7
 $baud = 9600
8
9
 Declare Sub Serial0charmatch()
10
11
'########[ Variables ]#####################################################
12
  Dim New_command As String * 10 , A As String * 3 , Command As String * 3
13
14
'########[ Constants ]#####################################################
15
Const Adresse = "001"
16
17
'########[ Hardware Configuration ]########################################
18
 Config Portc.5 = Output
19
 Config Serialin = Buffered , Size = 10 , Bytematch = 13
20
21
 Config Lcdpin = Pin , Db4 = Portb.5 , Db5 = Portb.4 , Db6 = Portb.3 ,_
22
   Db7 = Portb.2 , E = Portb.1 , Rs = Portb.0
23
 Config Lcd = 20 * 2
24
25
'########[ Initialisation ]################################################
26
 Open "comd.6:9600,8,N,1" For Output As #1                  'TXD
27
 Open "comd.7:9600,8,N,1" For Output As #2                  'RXD
28
 Enable Interrupts
29
30
'########[ Main Code ]#####################################################
31
Do
32
33
      If A = Adresse Then                         'Adressprüfung
34
      Select Case Command                         'Selektion nach kommando
35
         Case "ADR"
36
         Print "Funktioniert 1"
37
         Case "SBY"
38
         Print "Funktioniert 2"
39
         Case "RPM"
40
         Print "Funktioniert 3"
41
         Case Else
42
         Print "Case Else"
43
      End Select
44
      End If
45
46
      A = "" : Command = ""
47
48
Loop
49
End
50
51
'########[ Subroutines ]###################################################
52
 Sub Serial0charmatch()
53
   Input New_command Noecho
54
   Clear Serialin
55
   If Instr(new_command , "#") = 1 Then       'Suchen nach Startzeichen (#)
56
   A = Mid(new_command , 2 , 3)                'Abtrennen der Adresse
57
   Command = Mid(new_command , 5 , 3)          'Abtrennen des Befehls
58
   Command = Ucase(command)                    'Umwandeln in Großbuchstaben
59
60
   Toggle Portc.5
61
62
   Print A ; " und " ; Command        'Ausgabe der Teilstrings zur Prüfung
63
64
   Else
65
   New_command = ""
66
67
   End If
68
End Sub

Wie im Bild zu sehen zerlegt der AtMega den String scheinbar korrekt, 
verarbeitet den dann aber nicht richtig weiter. Je nach lust und Laune 
des Controllers tritt ein anderes Ereigniss für ein und den selben 
Befehl ein. Erwartet habe ich eigentlich immer ein "Funktioniert 1".

Ich weiß grad keinen Rat mehr und hoffe das mir hier einer einen Tipp 
geben kann was ich falsch gemacht habe/ anders machen sollte.

von Matthias B. (matthias_b14)


Angehängte Dateien:

Lesenswert?

Hab das Bild ohne die Dezimalwerte vergessen. Es wurde immer nur 
"#001adr" gesendet.

von Matthias B. (matthias_b14)


Lesenswert?

Juhu, ich hab rausgefunden woran das lag, war gestern wahrscheinlich 
doch etwas zu müde:P. Falls mal jemand auch das Problem haben sollte:

In meinem Programmcode puffer ich ankommende Zeichen solange bis das 
Zeichen <CR> empfangen wird. Ab da hüpfe ich mit interrupt in die Sub 
Serial0charmatch(). Dort wird alles fein ausgeführt. Allerdings kehre 
ich danach an genau die Stelle zurück, an der das Hauptprogramm vorher 
unterbrochen wurde. Wenn das nun mitten im Code war erfolgt die 
Auswertung der Variablen a und command nicht oder nicht korekt. Daher 
erhielt ich nur äußerst selten eine korrekte Antwort.

Eine einfache Änderung am Code hilft jedoch damit das ganze wie 
vorgesehen funktioniert:
1
Do
2
3
      If A <> "" Then
4
      If A = Adresse Then                                   'Adressprüfung
5
      Select Case Command                                   'Selektion nach kommando
6
         Case "ADR"
7
         Print "Funktioniert 1"
8
         Case "SBY"
9
         Print "Funktioniert 2"
10
         Case "RPM"
11
         Print "Funktioniert 3"
12
         Case Else
13
         Print "Case Else"
14
      End Select
15
      End If
16
17
      A = "" : Command = ""
18
      End If
19
Loop
20
End

Ich kann mir aber denken das der empfang und das senden über die 
serielle Schnittstelle eleganter gelöst werden könnte. Falls jemand dazu 
ideen hat bitte posten:).

von Bello (Gast)


Lesenswert?

Matthias B. schrieb:
> Ab da hüpfe ich mit interrupt in die Sub
> Serial0charmatch().
Ich sehe zwar Enable Interrupts aber kein "ON interrupt label" in deinem 
Programm.

von Matthias B. (matthias_b14)


Lesenswert?

Jup, da hast du recht. Ich hab das enable interruppts schon 
eingeschrieben obwohl ich im Programm noch keine weiteren Interrupts 
nutze. War sozusagen zur vorsorge weil ich später sicher noch nen Timer 
nutzen werde. Das Serial0charmatch() wird automatisch angesprungen 
sobald ein <CR> empfangen wurde.

Aber ich hab noch eine Frage: Ich nutze HTerm für die serielle 
Kommunikation mit dem PC. Dort empfange ich immer noch ein <LF> vor dem 
eigentlichen String der gesendet wurde (sieht man auch an den Bildern 
oben). Woran kann das liegen bzw. wie kann man das verhindern?

von Karl H. (kbuchegg)


Lesenswert?

Du empfängst nicht LF vor dem String. Das LF ist ein Überbleibsel aus 
dem vorhergehenden String, der mit CR LF abgeschlossen wurde.

In Bascom, als auch in HTerm, kann man konfigurieren, wie ein Zeilende 
gesendet werden soll.

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.