Bascom und ATMega 8, String zerlegen, auf kommandos reagieren

OP #2692703
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.
Angehängte Dateien:
OP #2692829
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:).
OP #2692857
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren