Bascom und UART wiedermal

Gast #1229096
Lesenswert?

Guten Tag zusammen!

Ich habe ein Problem mit dem UART von meinem ATmega32 und ankommenden 
Befehlen. Das Protokoll besteht aus 4 Bytes, die ausgewertet werden.
Wenn nun andere Sachen am UART ankommen, die mehr als 4 Bytes haben dann 
hängt sich das Programm auf. Woran könnte das liegen? Hier der Code:
1
On Urxc Receive
2
Enable Urxc
3

4
Enable Interrupts
5

6
Dim I as Byte
7
Dim Frame(4) as Byte
8
Dim Byte1 as Byte
9
Dim Byte2 as Byte
10
Dim Byte3 as Byte
11
Dim Byte4 as Byte
12

13
Main:
14
Do
15
  If I = 4 and Byte1 = &H10 and Byte2 = &H20 and Byte4 = &H40 Then
16
    Select Case Byte3
17
      Case &H01 :
18

19
      Case &H02 :
20
    End Select
21
    I = 0
22
  End If
23
Loop
24

25
Receive:
26
  Incr I
27
  Frame(i) = UDR
28
  Byte1 = Frame(1)
29
  Byte2 = Frame(2)
30
  Byte3 = Frame(3)
31
  Byte4 = Frame(4)
32
Return

Danke schonmal und schönen Tag,
Toni
Persönliche Seite #1229108
Lesenswert?

Weil I 5 wird wenn nicht deine gewünschte Bytefolge in der IF Abfrage 
ankommt und dein Array nur 4 Byte groß ist.

Mach mal das hier:
1
On Urxc Receive
2
Enable Urxc
3

4
Enable Interrupts
5

6
Dim I as Byte
7
Dim Frame(4) as Byte
8
Dim Byte1 as Byte
9
Dim Byte2 as Byte
10
Dim Byte3 as Byte
11
Dim Byte4 as Byte
12

13
Main:
14
Do
15
  If I = 4 then
16
    If Byte1 = &H10 and Byte2 = &H20 and Byte4 = &H40 Then
17
      Select Case Byte3
18
        Case &H01 :
19

20
        Case &H02 :
21
      End Select
22
    End If
23
    I = 0
24
  End If
25
Loop
26

27
Receive:
28
  Incr I
29
  Frame(i) = UDR
30
  Byte1 = Frame(1)
31
  Byte2 = Frame(2)
32
  Byte3 = Frame(3)
33
  Byte4 = Frame(4)
34
Return
#1229292
Lesenswert?

Diese ganze Auswertung ist ziemlicher Müll, weil der Empfänger nie 
wieder synchronisiert, wenn er einmal ausser Tritt gekommen ist (zb. 
weil der Sender mal 5 Bytes statt 4 gesendet hat)

Frag dich einfach mal (bzw. spiels in Gedanken durch) was passiert wenn 
der Sender

  &H00 &H80 &H10 &H20 &H01 &H40 &H10 &H20

sendet (zb. weil dein Mega mitten in eine laufende Übertragung 
einsteigt). Wie kann er aus dem Datenstrom den gültigen Frame  &H10 &H20 
&H01 &H40 rausfiltern und darauf reagieren?
Die Antwort darauf ist nicht: indem er darauf wartet, dass jeweils 4 
Bytes zusammen gekommen sind. Denn dann würde deine Erkennung die ersten 
4 Bytes

 &H00 &H80 &H10 &H20

untersuchen, feststellen dass das kein gültiger Frame war und auf die 
nächsten 4 Bytes warten

 &H01 &H40 &H10 &H20

ebenfalls kein gültiger Frame. Und so gehts dann weiter (Genau das was 
ich oben sagte: Dein Empfänger synchronisiert sich nicht mehr, wenn er 
einmal ausser Tritt gekommen ist)

Funktionieren tut das nur, indem man nach jedem empfangenen Byte die 4 
zuletzt Empfangenen untersucht (wenn denn schon 4 Empfangen wurden) und 
nachsieht ob das ein gültiger Frame war.

Das erste Byte kommt rein: &H00

  &H00            (noch keine 4 vorrätig, daher keine Analyse möglich)

Das nächste kommt rein: &H80

  &H00 &H80            (erst 2, 4 sind aber notwendig)

Das nächste: &H10

  &H00 &H80 &H10       (erst 3, immer noch keine 4)

Nächster Empfang: &H20

  &H00 &H80 &H10 &H20   jetzt sinds 4, aber das ist kein gültiger Frame
                        -> keine Aktion

Nächster Empfang: &H01
Das erste zwischengespeicherte Byte wird verworfen, alle anderen rücken 
nach

  &H80 &H10 &H20 &H01   immer noch kein gültiger Frame

Nächster Empfang: &H40

  &H10 &H20 &H01 &H40   holla, diese 4 Bytes sind ein gültiger Frame
                        -> Auswerten und den Empfangsbuffer löschen

Nächster Empfang: &H10

  &H10                  noch keine 4 Bytes empfangen

Nächster Empfang: &H20

  &H10 &H20

....


Und wozu das Frame-Array gut sein soll, ist mir auch nicht wirklich 
klar.
Moderator (Firma: Titel) Persönliche Seite #1229307
Lesenswert?

> Und wozu das Frame-Array gut sein soll, ist mir auch nicht wirklich
> klar.
Mir auch nicht...
Es reicht die Erkennung der Startsequenz:
1
Main:
2
Do
3
  If datensindda=1 then
4
    Select Case datenbyte
5
      Case &H01 :
6

7
      Case &H02 :
8
    End Select
9
    datensindda=0   <-- Daten verarbeitet
10
  End If
11
Loop
12

13

14
Receive:
15
  rcvbyteold = rcvbyte
16
  rcvbyte = UDR
17
  if getbyte=1 then
18
     datenbyte=rcvbyte     
19
     datensindda=1   <-- Handshake
20
     getbyte=0;
21
  end if
22
  if rcvbyte=&H10 and rcvbyteold=&H20 then   <-- auf Startsequenz synchronisieren
23
     getbyte=1   <-- nächstes Byte einlesen
24
  end if
25
Return
Gast #1230111
Lesenswert?

Hallo und vielen Dank für die Antworten. Habe das jetzt verstanden. Das 
Programm von Lothar Miller funktioniert soweit einwandfrei, nur die 
Zeile:

if rcvbyte=&H10 and rcvbyteold=&H20 then

muss in

if rcvbyte=&H20 and rcvbyteold=&H10 then

geändert werden (weil zuerst &H10 ankommt und dann &H20)

Jetzt habe ich das ganze erweitert und will aus einem Paket 4 Bytes 
rausholen, die nach &H60 &H40 kommen. Ich habe das jetzt so eingebunden 
und es funktioniert. Ist das der richtige Weg oder gibt es vielleicht 
eine elegantere Lösung:
1
Dim daten(4) as Byte
2
Dim rcvbyte as Byte
3
Dim rcvbyteold as Byte
4
Dim datensindda as Bit
5
Dim Getbyte as Bit
6
Dim i as Byte
7

8
rcvbyteold = rcvbyte
9
rcvbyte = UDR
10

11
If Getbyte = 1 Then
12
  daten(i) = rcvbyte
13
  incr i
14
  If i = 4 Then
15
    i = 1
16
    datensindda = 1
17
    Getbyte = 0
18
  End If
19
End If
20

21
If rcvbyte = &H40 and rcvbyteold = &H60 Then
22
  Getbyte = 1
23
End If

Toni

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