Archiv verlassen und diese Seite im Standarddesign anzeigen : Uart-Abfrage mit Atmega128 - Mit Lösung!
Hallo,
Ich versuche mit einem ATmega128 und daran angeschlossenem Funkmodul Daten zu empfangen. Die Daten werden von einem weiteren Prozessor (A32) über ein Funkmodul gleichen Typs gesendet.
Aber leider funktioniert das Auswerten und Beschreiben des Strings nicht.
Als Daten werden gesendet: "Chr(15)" und danach ""Hallo!""
Schließe ich das Sendeboard direkt an das Display an, wird das auch korrekt angezeigt, dort kann der Fehler nicht liegen.
Bitte guckt einmal meinen Programmcode durch:
$regfile = "m128def.dat" ' Bei Mega 128 "
$framesize = 40
$swstack = 40
$hwstack = 40
$crystal = 16000000 'Quarzfrequenz
$baud = 19200 'Baudrate für Funkmodul
$baud1 = 19200
Config Pine.2 = Output
Rdy_hostempfangsbereit Alias Porte.2
Open "com2:" For Binary As #2
Config Serialin = Buffered , Size = 50 , Bytematch = 15
Enable Interrupts
' ---------------------------------------------------
Dim Z As Byte
Dim Text As String * 6
Print #2 , "RN Mega128Funk"
Rdy_hostempfangsbereit = 0
Echo Off
Do
Print #2 , Text
Waitms 500
Loop
Serial0charmatch:
Text = Inkey()
Return
Wem die 2te konfigurierte RS232-Schnittstelle auffällt:
Dort habe ich ein Display angeschlossen(RN KeyLCD), das die gleiche Funktion eines Terminalprogramms hat.
Das Ergebnis was dann im Display angezeigt wird sind nur einzelne 'H's, keine 6 Zeichen "Hallo!"
Bitte versucht meinen Fehler zu finden!
Mit freundlichen Grüßen
Jimmy
Che Guevara
23.11.2010, 22:06
Hallo Jimmy,
in dem Serial0charmatch Unterprogramm ist dein Fehler. In deinem Programm überschreibt die Zeile "Text = Inkey()" nämlich immer die Variable Text mit dem neuesten UART "Textzeichen".
Du musst folgendes Schreiben:
Serial0charmatch:
buffer = inkey()
text = text + buffer
return
Wobei ich mir momentan nicht sicher bin, ob inkey() hier richtig ist oder man besser "udr" nehmen soll....
buffer ist hier eine zusätzliche Variable als Zwischenspeicher, welche vom gleichen Typ wie Text sein sollte.
Gruß
Chris
Hallo Jimmy,
Inkey() liest nur ein einzelnes Zeichen aus dem Input Buffer. Daher bleibt es immer bei dem "H".
Wenn hinter dem "!" ein <CR> kommt, dann schreib doch mal
Input Text, Noecho
Ansonsten wäre es besser, du würdest nach deinem Text ein bestimmtes Zeichen, wie z.B. CHR(15) senden.
Wenn jetzt der SerialCharMatch kommt, dann sind schon alle Zeichen im Puffer und das Programm braucht nicht mehr auf das Eintreffen zu warten.
Hi Chris,
Danke für deine konstruktive Antwort!
Meinst du das weil der Inkey-Befehl immer nur ein Zeichen aufnehmen kann?
Ich habs in der Library nachgelesen, man kann auch den ganzen String damit befüllen.
Ich habe deinen Vorschlag trotzdem mal ausprobiert und siehe da, nun zeigt er nicht nur eine Stelle "H" an, sondern "Ha".
Ich müsste also das "text = text + buffer" nur für jede Stelle die der String hat wiederholen und hätte dann die ganze Nachricht.
Aber plötzlich resettet sich der Controller immer nach einigen Sekunden selbständig, nur nach diesem Einschub...
Läuft da eventuell "text" über?
Hallo for_ro,
Auch dir danke ich für deinen Beitrag!
Du meinst man kann zwar einen String mit "Inkey" beschreiben, dieser wird aber dann imer nur ein Zeichen haben?
Warum steht aber dann in der Bascom-Library ein Beispiel mit einem 2-Zeichen-String?
Über die Reihenfolge von Erkennunsgzeichen und den eigentlichen Daten habe ich schon nachgedacht, doch ich kam zu dem Schluss dass die Funktion ab dem Erkennunsgzeichen alle x viele Zeichen liest.
Danke dass du mich darüber nochmal aufgeklärt hast!
In der Library ist aber doch ein Loop drinnen, der Inkey immer wieder aufruft.
SerialCharMatch funktioniert so, dass zu dem Label gesprungen wird, wenn das Zeichen empfangen wurde, welches du vorgegeben hast.
Dort fragst du mit Inkey das erste Zeichen des Puffers ab. Danach geht das Programm wieder zurück zu dem befehl, wo es unterbrochen wurde.
Dies ist bei dir die Do..Loop mit dem Print alle 500ms. D.h. du kannst so nur ein Zeichen einlesen. Überleg es dir noch einmal.
Du könntest es auch so machen:
Serial0charmatch:
While IsCharWaiting() = 1
Text = Text + Inkey()
Wend
Return
Ich habe die Änderungen eingebaut, eine gute Idee mit der while-Schleife, doch nun gibt der Controller gar nichts mehr aus, sondern resettet sich sofort.
Sobald der Atmega etwas empfängt setzt er sich selbst zurück.
Wenn ich das Sendeboard ausmache läuft das Programm weiter durch, nur kann es dann natürlich nichts mehr empfangen.
Hier nochmal mein Programmcode:
$regfile = "m128def.dat" ' Bei Mega 128 "
$framesize = 40
$swstack = 40
$hwstack = 40
$crystal = 16000000 'Quarzfrequenz
$baud = 19200 'Baudrate für Funkmodul
$baud1 = 19200
Config Pine.2 = Output
Rdy_hostempfangsbereit Alias Porte.2
Open "com2:" For Binary As #2
Config Serialin = Buffered , Size = 10 , Bytematch = 15
Enable Interrupts
' ---------------------------------------------------
Dim Text As String * 6
Dim Buffer As String * 1
Print #2 , "RN Mega128Funk"
Rdy_hostempfangsbereit = 0
Echo Off
Do
Print #2 , Text
Waitms 500
Loop
Serial0charmatch:
While Ischarwaiting() = 1
Buffer = Inkey()
Text = Text + Buffer
Wend
Return
Übrigens hat die Buffergröße keinerlei Einfluss auf die Zeit bis zum Reset, auch wenn ich sie erhöhe.
Ich verstehe zwar nicht, warum du unbedingt bei der Version mit Startzeichen bleiben willst, aber sei's drum.
Mach mal in die Sub ein Pushall und ein Popall, so wie es in der Hilfe steht.
Nach dem Printen würde ich die Variable Text leeren, sonst wird sie immer größer.
Ich habe die Änderungen eingebaut, doch leider tat sich nach wie vor nichts, außer dem periodischen Selbst-Reset des Controllers.
Dann habe ich nach einem anderen Weg gesucht und bin schließlich auf einen Thread gestoßen, wo du in der gleichen Frage Jemandem anders geantwortet hast.
Damit klappt es!!! \:D/
Hier mein endgültiger Code:
$regfile = "m128def.dat" ' Bei Mega 128 "
$framesize = 40
$swstack = 40
$hwstack = 40
$crystal = 16000000 'Quarzfrequenz
$baud = 19200 'Baudrate für Funkmodul
$baud1 = 19200
Config Pine.2 = Output
Rdy_hostempfangsbereit Alias Porte.2 'Auf Low setzen wenn Empfangsbereit für Daten vom Funkmodul
Open "com2:" For Binary As #2
Config Serialin = Buffered , Size = 20 , Bytematch = 13
Enable Interrupts
' ---------------------------------------------------
Dim Command_key As Byte
Dim Command_count As Byte
Dim Command_string As String * 12
Dim Empfang As Bit
Empfang = 0
Rdy_hostempfangsbereit = 0
Echo Off
Do
If Empfang = 1 Then
Sound Portg.2 , 200 , 650
Waitms 1
Print #2 , Command_string
Empfang = 0
Command_string = ""
End If
Loop
Serial0charmatch:
Empfang = 1
Command_count = 0
Command_string = ""
While Ischarwaiting() = 1
Command_key = Inkey()
If Command_key <> Chr(13) Then
Incr Command_count
If Command_count < 12 Then
Command_string = Command_string + Chr(command_key)
End If
End If
Wend
Clear Serialin
Return
Der String ist 12 Zeichen lang, wer eine andere Länge haben will muss sie oben bei "Dim String as" und unten bei "If Command_count" ändern.
Wer ein anderes Erkennungszeichen als Chr(13) nehmen will, muss es oben bei "Config Serialin [...] Bytematch=" und unten bei "If command_key" ändern.
Das Bit "Empfang" sorgt dafür dass nur dann Text ausgegeben wird, wenn neue Daten empfangen wurden.
Die Geschwindigkeit ist super! Mein Sender sendet im Abstand von 200 Millisekunden "Hallo" mit einer Zählvariable die von 1 bis 9 läuft und jede Message wird korrekt angezeigt.
Hier noch der Link zum Original-Thread:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=42559&highlight=input+string
Viel Spaß mit dem Programm und nochmals Danke an dich Rolf! =D>
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.