Hallo!
Die Kommunikation über die UART ist ziemlich nützlich und vielseitig. Damit kann der µC Daten zum Computer oder an andere µC schicken und empfangen. Bascom stellt dafür mehrere Befehle bereit auf die ich in diesem Beitrag näher eingehen möchte. Der ATmega8 besitzt eine eingebaute Hardware-UART-Schnittstelle. Man kann UART aber auch per Software nachbilden. Das ist zwar nicht mehr so schnell wie die Hardware-UART, aber immerhin kann man damit gleichzeitig Verbindung zu mehreren Gegenstellen aufnehmen. Wenn man nichts besonderes einstellt, dann verwendet Bascom die Hardware-UART.
Damit stellt man die gewünschte Übertragungsgeschwindigkeit ein. Diese ist von der Frequenz abhängig, mit der der µC getaktet wird. Diese muss Bascom mit $crystal
bekannt gegeben werden. Beispiel:
$baud = 9600
Bascom Hilfe zu diesem Befehl: http://avrhelp.mcselec.com/index.html?baud_1.htm
Dieser Befehl sendet eine Zeichenfolge (einen Text) über die UART. Mehrere Zeichenfolgen können mit einem Strichpunkt (;) getrennt werden. An diese Zeichenfolge werden autmatisch die unsichtbaren Zeichen CARRIAGE RETURN (CR) und LINEFEED (LF) angehängt. Diese unsichtbaren Zeichen kennzeichnen einen Zeilenumbruch. Möchte man nicht, dass diese unsichtbaren Zeichen angehängt werden, dann muss der PRINT-Befehl mit einem Strichpunkt (;) abgeschlossen werden. Wird an PRINT eine Zahl übergeben, dann wird diese in einen Text umgewandelt. Es wird also nicht die Zahl übermittelt, sondern der ASCII-Code dafür. Die Zahl 123 besteht aus den drei Zeichen "1", "2" und "3". Es werden die drei ASCII-Codes für die Zeichen "1", "2" und "3" und die ASCII-Codes der beiden unsichtbaren Zeichen CR und LF übertragen.
Dieser Code
PRINT "Hallo Welt!"
übermittelt die Zeichenfolge "Hallo Welt!" und fügt die unsichtbaren Zeichen CR und LF an. Das sieht in einem normalen Terminalprogramm so aus:
Hallo Welt!
Analysiert man aber die übermittelten Daten, dann sieht man, dass für jedes Zeichen der ASCII-Code übermittelt wurde. Hier der Dezimal- und Hex-Code der übermittelten Zeichen:
Dezimal: 72 97 108 108 111 32 87 101 108 116 33 13 10
Hex: 48 61 6C 6C 6F 20 57 65 6C 74 21 0D 0A
Text: H a l l o W e l t ! CR LF
Wenn man diese Codes mit einer ASCII-Tabelle vergleicht, dann erkennt man die Zusammenhänge.
Dieser Code
PRINT 1
übermittelt das Zeichen "1" und nicht die Zahl 1. In einem normalen Terminalprogramm wird also das Zeichen "1" angezeigt. Analysiert man was wirklich übermittelt wird, dann sieht das so aus:
Dezimal: 49 13 10
Hex: 31 0D 0A
Text: 1 CR LF
Will man die Zahl 1 ohne Umwandlung in ein Zeichen übermitteln, dann nimmt man dafür den Befehl PRINTBIN.
Bascom Hilfe zu diesem Befehl: http://avrhelp.mcselec.com/index.html?print.htm
Mit PRINTBIN werden die Daten, ohne Umwandlung in einen Text, übermittelt. Folgender Befehl übermittelt wirklich die Zahl 1:
PRINTBIN 1
Analysiert man das was an den Computer gesendet wurde, dann sieht das so aus:
Dezimal: 1
Hex: 01
Text: <unsichtbar>
So können reine Daten, ohne umwandeln, übermittelt werden. Diese lassen sich aber dafür nicht mehr in einem normalen Terminalprogramm anzeigen. Dafür bräuchte man einen Anzeigemodus der die empfangenen Daten in Hex oder Dezimal anzeigt.
Bascom Hilfe zu diesem Befehl: http://avrhelp.mcselec.com/index.html?printbin.htm
Der Befehl INPUT erwartet eine Zeichenfolge von der UART und schreibt diese in eine Variable. INPUT wartet so lange auf die Zeichenfolge bis CARRIAGE RETURN (CR) übermittelt wurde. Das Programm bleibt also stehen, bis CR über die UART rein kommt. Das ist ideal, wenn das Programm in der MainLoop nur kommuniziert. Es ist nicht ideal, wenn in der MainLoop auch noch andere Dinge erledigt werden sollten. Dafür gibt es andere Befehle wie INKEY oder ISCHARWAITING. Außerdem gibt es sogar die Möglichkeit, einen Interrupt auslösen zu lassen, wenn eine Zeichenfolge angekommen ist.
Dieses Beispiel wartet bis eine mit CR abgeschlossene Zeichenfolge übermittelt wurde und schickt diese über die UART zurück:
Dim Empfangen As String * 20
Do
Input Empfangen
Print "Empfangen: " ; Empfangen
Loop
End
Mit CONFIG INPUT kann man einstellen, welches unsichtbare Zeichen oder welche unsichtbare Zeichenfolge einen Empfang abschließt. Und mit ECHO OFF kann man einstellen, dass in ein Terminal eingegebene Zeichen nicht sofort wieder zurück geschickt werden.
Bascom Hilfe zu diesem Befehl: http://avrhelp.mcselec.com/index.html?input.htm
Bei diesem Befehl wartet Bascom auf Binärdaten. Es wartet also nicht auf Text, wie es INPUT macht, sondern auf reine Daten. An diesen Befehl wird als Argument eine Variable übergeben. INPUTBIN stoppt das Programm so lange, bis diese Variable befüllt wurde. Wird also eine BYTE-Variable übergeben, dann genügt ein Byte und das Programm läuft weiter. Wird eine WORD-Variable übergeben, dann wartet INPUTBIN bis zwei Byte (=WORD) übergeben wurden. Beispiel:
Dim My_word_var As Word
Do
Inputbin My_word_var
Printbin My_word_var
Loop
End
Bascom Hilfe zu diesem Befehl: http://avrhelp.mcselec.com/index.html?inputbin.htm
Dieser Befehl wartet bis ein Zeichen über die UART zum µC übertragen wurde und gibt dieses zurück. WAITKEY blockiert so lange bis ein Zeichen übermittelt wurde. Wird eine BYTE-Variable damit befüllt, dann steht in der BYTE-Variable der ASCII-Code des übermittelten Zeichens. Wird eine STRING-Variable befüllt, dann weiß Bascom, dass der übermittelte ASCII-CODE ein Textzeichen ist und gibt dieses bei PRINT als solches zurück. Beispiel:
Dim My_byte As Byte
Dim My_string As String * 1
Do
My_byte = Waitkey()
Print "Empfangen: " ; My_byte 'Gibt den ASCII-Code des Zeichens zurück
My_string = Waitkey()
Print "Empfangen: " ; My_string 'Gibt den Text zurück
Loop
End
Bascom Hilfe zu diesem Befehl: http://avrhelp.mcselec.com/index.html?waitkey.htm
Wenn ein Zeichen im zwei Byte großen UART-Buffer steht, dann gibt INKEY ein Zeichen zurück. Steht nichts mehr im UART-Buffer, dann gibt INKEY die Zahl 0 zurück. INKEY bleibt also nicht stehen wie es bei WAITKEY der Fall ist. Das ist oft eine feine Sache, aber nicht ideal wenn in den zu übermittelnden Daten auch mal ein Nullbyte vorkommen kann. In so einem Fall sollte man vorher mit ISCHARWAITING prüfen ob etwas im UART-Buffer steht. Beispiel:
Dim My_string As String * 1
Do
My_string = Inkey()
If My_string <> Chr(0) Then
Print "Empfangen: " ; My_string
End If
Loop
oder so:
Dim My_string As String * 1
Do
If Ischarwaiting() = 1 Then
My_string = Inkey()
Print "Empfangen: " ; My_string
End If
Loop
Bascom Hilfe zu diesem Befehl: http://avrhelp.mcselec.com/index.html?inkey.htm
ISCHARWAITING gibt 1 zurück, wenn im UART-Buffer ein Zeichen wartet. ISCHARWAITING gibt 0 zurück, wenn kein Zeichen im UART-Buffer wartet. Beispiel: siehe INKEY
Bascom Hilfe zu diesem Befehl: http://avrhelp.mcselec.com/index.html?ischarwaiting.htm
Die Einstellung ECHO ON gibt an, dass vom Befehl INPUT sofort nach dem Empfang eines Zeichens, dieses Zeichen zurück geschickt werden soll. Das ist die Standardeinstellung! Die Einstellung ECHO OFF gibt an, dass nichts zurück geschickt werden soll.
Bascom Hilfe zu diesem Befehl: http://avrhelp.mcselec.com/index.html?echo.htm
Es gibt noch weitere Befehle zum Arbeiten mit der UART. Die Befehle CONFIG SERIALIN, CONFIG SERIALOUT und CONFIG COM1 werde ich im nächsten Beitrag vorstellen.
mfg Gerold :-)
Den zugehörigen Original-Beitrag findest du im Loetstelle-Forum.
Ich programmiere Progressive Web Applications, Mobile Apps, Desktop-Programme und noch vieles mehr. Falls es dich interessiert, findest du mehr Informationen darüber auf meiner Business-Website.