PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UART Problem. Verhalten nicht nachvollziehbar, bitte um Hilfe.



Accenter
15.06.2013, 20:53
Habe ein Problem mit dem Uartempfang. Wenn ich das Programm das erste mal starte läuft alles wie es soll. Ich sende über ein Terminal einen String und wenn ich Enter drücke wird dieser String ausgegeben und aus den ersten 3 Stellen des Strings eine ID rauskopiert und der Variablen "ID" übergeben. Läuft soweit perfekt.

Sende ich nun erneut einen String wird mir von der ID die letzte Stelle weggeschnitten. Es werden also nur noch 2 Stellen rauskopiert. Ich hab keine Erklärung für dieses Verhalten.

Der Code ist gekürzt aber natürlich lauffähig und produziert so wie er hier gepostet ist das genannte Problem. Bin absolut ratlos.





$regfile = "m128def.dat"
$crystal = 8000000
$baud = 9600
$baud1 = 9600
$framesize = 400
$swstack = 400
$hwstack = 400

Config Watchdog = 2048
Config Portf.5 = Output
Config Portf.6 = Output
Config Pinf.7 = Input
Config Portf.1 = Output
Config Porte.6 = Output
Config Porte.5 = Output
Config Porte.4 = Output
Config Porta.0 = Output
Config Portb.7 = Output
Config Portb.6 = Output
Config Portb.5 = Output
Config Portc.7 = Output
Config Portd.6 = Output
Funkpinintertechno Alias Porta.0
Funkpinfs20 Alias Portb.7
Enablefs20tx Alias Portb.6
Enablefs20rx Alias Portf.1
Ledgruen Alias Porte.6
Ledrot Alias Porte.5
Ledblau Alias Porte.4
Speaker Alias Portb.5
Lanreset Alias Portc.7
Lanconfig Alias Portd.6
Ausgabebestaetigt Alias Portf.5
Starteausgabe Alias Portf.6
Befehlvorhanden Alias Pinf.7
Config Sda = Portd.1 'DS1307 wird configuriert'
Config Scl = Portd.0
I2cinit
Config Twi = 100000
Waitms 100
Dim Ds1307w As Byte , Ds1307r As Byte : Ds1307w = &B11010000 : Ds1307r = &B11010001
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin1 = Buffered , Size = 60 , Bytematch = 13
Config Serialout1 = Buffered , Size = 60
Open "Com2:" For Binary As #2 'UART 2 wird aktiviert. Schicken mit Print #2 , "Text"'
Clear Serialin1
Enable Interrupts

Dim Buffer As Byte , Uart2eingang As String * 82

Dim Zaehler As Long , A As Byte
Dim Id As String * 3
Dim Abfrageuartfunk As String * 50 , Abfrageuartlan As String * 50 , Empfangenerstringuartlan As Byte , Empfangenerstringuartfunk As Byte

Declare Sub Serial1charmatch()
Config Timer0 = Timer , Prescale = 1024 'Timer für 1 sek takt'
Enable Timer0
On Timer0 1seksub
Timer0 = 0
Enable Interrupts
Config Watchdog = 2048
Start Watchdog
Lanconfig = 1
Lanreset = 1

Wait 1 'Warte 3 Sekunden bis das LAN Modul betriebsbereit ist'
Reset Watchdog
Wait 1
Reset Watchdog
Wait 1
Reset Watchdog


'##################### Hauptschleife #######################'

Hauptschleife:
Do
Reset Watchdog

If Ischarwaiting(#2) = 1 Then 'LAN Uart''
Gosub Uart2auswertung
End If
If Empfangenerstringuartlan = 1 Then 'Flag ist 1 wenn über Serialcharmatch ein string fertig empfangen wurde'
Empfangenerstringuartlan = 0
Gosub Scriptauswertunglan 'Werte diesen String aus'
End If
Loop

'############################# 1 Sekundentakt Schleife ########################'

1seksub:
Incr Zaehler
If Zaehler > 29 Then
Zaehler = 0 : Timer0 = 0
Gosub 1sektakt
End If
Return

'################## Alles was hier steht wird jede Sekunde ausgeführt #####################'

1sektakt:
Return

'############## UART Auswertung LAN Modul TCP ###############'

Uart2auswertung:
Disable Interrupts
Buffer = Inkey(#2)
If Len(uart2eingang) < 50 Then
Uart2eingang = Uart2eingang + Chr(buffer)
Else
Uart2eingang = ""
Clear Serialin1
End If
Enable Interrupts
Return
Sub Serial1charmatch()
Disable Interrupts
Abfrageuartlan = Uart2eingang
Empfangenerstringuartlan = 1 'Flag gesetzt, es wurde etwas empfangen, werte in der Hauptschleife aus'
Enable Interrupts
Clear Serialin1
Uart2eingang = ""
End Sub

'####################### Scriptauswertung Lan Modul UART ####################'

Scriptauswertunglan:
Id = Mid(abfrageuartlan , 1 , 3)
Print #2 , "abfrageuartlan: " ; Abfrageuartlan
Print #2 , "ID: " ; Id
Print #2 , "" 'leerzeile'
Return
End

MagicWSmoke
15.06.2013, 21:07
Du betrachtest den String bei CR als angekommen, der Sender wird aber CRLF schicken, damit befindet sich noch ein LF im Puffer, denn es kommt zeitlich nach dem Clear Serialin an.
Musst Dir nur den empfangenen String mal in Hex oder Dezimal ansehen.

Accenter
15.06.2013, 21:20
Danke für deine Hilfe. Wie kann ich das in meinem Code verhindern? Hast du da vielleicht einige Zeilen Code für mich? Bin beim UART Empfang leider nicht so fit.

MagicWSmoke
15.06.2013, 21:29
Dein Programm solltest Du Dir schon selber schreiben. Aber erstmal solltest Du überprüfen, ob das mit dem LF das tatsächliche Problem ist.
Die absolut einfachste Lösung wäre sicher Bytematch = 10 zu konfigurieren. Nur musst Du sicherstellen, dass der Sender sich immer daran hält.
Das CR befindet sich in diesem Fall dann mit LF am Ende der empfangenen Daten.
Ich find' ja Deinen Code fürchterlich umständlich, Du setzt den Empfang gepuffert auf, machst dann den Empfang doch wieder selbst, statt einfach nur den Puffer abzuholen, wenn Du einen Charmatch hast.

Uart2eingang = Uart2eingang + Chr(buffer)
Eine andere Lösung, wenn Du den Code so beibehalten willst, füge buffer nur hinzu, wenn's ungleich LF, also 10 ist.

Accenter
15.06.2013, 21:41
Läuft! Herzlichen Dank! Bytematch=10 und es lief perfekt. :-)
Wie ich es anders machen könnte weiß ich leider nicht. Bin für jeden Tipp der Codeoptimierung dankbar.

MagicWSmoke
15.06.2013, 21:51
Wie ich es anders machen könnte weiß ich leider nicht. Bin für jeden Tipp der Codeoptimierung dankbar.
Du hast im Moment 3 Puffer, den Puffer des Serialin, dann Uart2eingang und von dort nach Abfrageuartlan. Statt dessen könntest Du bei einem Charmatch per Input der Abfrageuartlan gleich den Puffer der Serialin zuweisen.
Das Verhalten von Input muss mit Config Input auf das Format des CRLF angepasst werden.