Forum: Mikrocontroller und Digitale Elektronik BASCOM probleme mit HW UART und Bytematch


von Michael L. (nightflyer88)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Habe ein Problem in BASCOM mit der HW UART und der Funktion Bytematch.

Mein Programm läuft auf einem ATmega328, und liest in der main loop 
verschiedene Sensorwerte ein und verarbeitet diese entsprechend weiter. 
Zusätzlich soll der AVR Daten von einem GPS verarbeiten, die über die HW 
UART rein kommen. Ein GPS-Datensatz beginnt mit '$' und endet mit CRLF. 
Um das ende zu erkennen habe ich die funktion Bytematch verwendet. 
Soweit funktioniert auch alles, jedoch nach ca. 500 empfangenen 
Datensätzen wird irgendwie das RAM oder der Stack durcheinander 
gebracht, und der AVR macht dann irgend welchen komischen sachen.

Ohne GPS, also ohne empfangenen UART Daten, läuft der AVR stundenlang 
ohne Probleme, der Fehler muss also irgendwo in der Empfangsroutine der 
HW UART liegen.

Um mal die ganze GPS Datenverarbeitung auszuschliessen sende ich zum 
testen '$TEST' an den AVR, und der soll dann mit '1234' antworten. Dies 
funktioniert die ersten 500 mal, und irgendwann gerät im RAM oder Stack 
etwas durcheinander...

Also hier mal ein Code Ausschnitt mit den UART relevanten Teilen (anbei 
der ganze Code):
1
'Serialport config
2
Config Com1 = 38400 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
3
Config Serialin = Buffered , Size = 100 , Bytematch = 13
4
Config Serialout = Buffered , Size = 20
5
Open "com1:" For Binary As #10
6
7
Enable Interrupts
8
9
'main loop
10
do
11
  ....
12
  Call Read_serial()
13
loop
14
15
end
16
17
18
Serial0charmatch:
19
  Input Serial_txt Noecho
20
Return
21
22
23
Sub Read_serial()
24
  Local X As Byte
25
26
  Disable Interrupts
27
  Tmp_serial_txt = Serial_txt
28
  Serial_txt = ""
29
  Enable Interrupts
30
31
  X = Instr(tmp_serial_txt , "$")
32
  X = Len(tmp_serial_txt) - X
33
  Incr X
34
  Tmp_serial_txt = Right(tmp_serial_txt , X)
35
36
  Select Case Tmp_serial_txt
37
      Case "$TEST"
38
        Print #10 , "1234"
39
    End Select
40
End Sub


in der Bascom Hilfe steht, dass man bei Verwendung von Bytematch die 
register selber sichern muss, habe ich bereits mit Pushall/popall 
versucht, hat aber auch nichts genützt.

Hat jemand Erfahrungen mit dem Bytematch ? gibt es irgendwelche 
speziellen eigenheit von Bascom die man berücksichtigen muss ?

von Frickelfinker (Gast)


Lesenswert?

Machs zu Fuß mit Overlay, das funz.

von Frickelfinker (Gast)


Lesenswert?

'0011.BAS: Optimierter String-Empfang
$Regfile = "2313def.dat"
$Crystal = 3686400
$Baud    = 9600

Dim s As String*10 At &H60
Dim b(11) As Byte At &H60 Overlay
Dim n As Byte

On URXC OnRxD
Enable URXC
Enable Interrupts

Main:
  If n > 9 Then
    Print s
    n = 0
  End If
Goto Main

OnRxD:
  Incr n
  b(n) = UDR
Return
Der String wird auf Adresse &H60 im AVR abgelegt. Dies ist die Adresse 
des ersten Bytes im SRAM (da der AT90S2313 über 128 Bytes SRAM vefügt, 
ist die höchste SRAM-Adresse &HDF). Quasi "darüber", also auf die selbe 
Adresse, legen wir ein Feld, das genauso lang wie der String ist. Das 
ist alles. Der Trick ist nur, daß wir beim Füllen des Strings in unserem 
Anwendungsfall am effizientesten mit einem Feld arbeiten können, während 
in anderen Fällen die Arbeit mit einem String günstiger sein kann. 
Welche Wege man in der Praxis gehen will, hängt natürlich immer von der 
Anwendung ab. Die Anwendung des Overlay-Tricks kostet weder zusätzlichen 
Code, noch SRAM. Es ist vielleicht eher wie die Auswahl zwischen 
Buddelschippe, Schaufel und Bagger bei ein und dem selben Haufen Sand.

Und noch ein drittes UART-Mißverständnis trat wiederholt auf: Der 
UART-Empfangs-Interrupt meldet, daß ein Zeichen empfangen wurde. In der 
Interrupt-Routine kann man deshalb auch immer nur ein Zeichen auslesen. 
Zum Beispiel macht es daher keinen Sinn, in der Interrupt-Routine den 
Bascom-Befehl Input einzusetzen, um doch mehrere Zeichen empfangen zu 
können.

von Michael L. (nightflyer88)


Lesenswert?

also ich habe den Fehler jetzt ziemlich gut eingrenzen können: es liegt 
wie vermutet an der Bytematch routine, das Problem dabei ist, dass 
dadurch die main loop zu stark ausgebremst wird.
In der Main loop werden per Soft-i2c sensoren ausgelesen. Es kann dann 
passieren, dass eine fehlübertragung der messwerte erfolgt, und 
dementsprechend bei der weiterverarbeitung krumme sachen rauskommen...


Frickelfinker schrieb:
> Machs zu Fuß mit Overlay, das funz.

Dein beispiel sieht super aus, einfach und effektiv..

Wie muss ich den die UART Schnittstelle initialisieren ? Wird die 
baudrate mit $baud automatisch in den registern gesetzt ? Und die 
anderen Parameter 8,N,1 ? Oder sowiso per ASM einstellen und 
initialisieren ?

Wie sieht es mit dem senden aus ? Hast du da auch so eine einfache 
lösung parat mit dem TXCn Interrupt ;-) ?

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.