Forum: Mikrocontroller und Digitale Elektronik Bascom: Hex per Software UART ausgeben


von Thomas H. (hubtom)


Lesenswert?

Hallo Zusammen,

Ich möchte per Software UART (der Hardware UART des Atmega wird zur 
kommunikation mit einem PC benötigt) 23 Hex Zahlen an eine Display 
senden das per RS232 an einen Atmega 32 angebunden ist. Folgenden unten 
angehängten Code habe ich im Bascom bereits programmiert.

Ich bekomme jedoch beim compilieren folgende Fehlermeldung von der ich 
nicht weis, wie ich diese beheben soll:

Line 36 Source Variable does not match the target variable

Ich würde mich sehr freuen, wenn mir bitte jemand weiterhelfen könnte.

Herzlichen Dank

Tom

 $regfile = "m32def.dat"
 $framesize = 40
 $swstack = 10
 $hwstack = 32
 $crystal = 14745600
 $baud = 9600


Dim S As String * 23
Dim Bytes_to_send(23) As Byte

Bytes_to_send(1) = &HA0
Bytes_to_send(2) = &H15
Bytes_to_send(3) = &H01
Bytes_to_send(4) = &H88
Bytes_to_send(5) = &H77
Bytes_to_send(6) = &H48
Bytes_to_send(7) = &H20
Bytes_to_send(8) = &H4F
Bytes_to_send(9) = &H71
Bytes_to_send(10) = &H22
Bytes_to_send(11) = &HF1
Bytes_to_send(12) = &H72
Bytes_to_send(13) = &HFF
Bytes_to_send(14) = &H00
Bytes_to_send(15) = &H11
Bytes_to_send(16) = &H23
Bytes_to_send(17) = &HA1
Bytes_to_send(18) = &H10
Bytes_to_send(19) = &H45
Bytes_to_send(20) = &H1C
Bytes_to_send(21) = &H22
Bytes_to_send(22) = &HFF
Bytes_to_send(23) = &HFA

S = Bytes_to_send(23)



Do

Serout S , 0 , B , 1 , 9600 , 0 , 8 , 1                     'Daten 
Senden

'                                      ^  1 stop bit

'                                  ^----  8 data bits

'                                ^------  even parity (0=N, 1 = E, 2=O)

'                        ^--------------  baud rate

'                  ^--------------------  pin number

'               ^-----------------------  port so PORTB.1 is used

'           ^---------------------------  for strings pass 0

'      ^--------------------------------  variable

Wait 1

Loop

End

von Karl H. (kbuchegg)


Lesenswert?

Thomas Huber schrieb:

> Line 36 Source Variable does not match the target variable

Sei nett und sag uns, welches die Zeile 36 ist

von Karl H. (kbuchegg)


Lesenswert?

Auch ohne jetzt der BASCOM Experte zu sein.

Ich kann mir nicht vorstellen, das das hier
1
Dim S As String * 23
2
Dim Bytes_to_send(23) As Byte
3
4
....
5
6
S = Bytes_to_send(23)

von den Datentypen her passen wird. Ich könnte noch nicht einmal sagen, 
was diese Zuweisung für eine Operation machen sollte.
S ist ein String, Bytes_to_send(23) ist ein einzelnes Byte

von Tobi W. (todward)


Lesenswert?

Also laut der Bascomhilfe sollte es mit
1
Hex(S(x))
x steht für den index von deinem Array

grüße
Tobias

von Holger S. (holli_1)


Lesenswert?

So wird aus den Bytes ein String:

Dim Bytes_to_send(23) As Byte At S Overlay

Dann braucht es das auch nicht mehr:

S = Bytes_to_send(23)

von Turbotoni (Gast)


Lesenswert?

ich vermte mal, das mit Dim Bytes_to_send(23) As Byte
ein Array mit den feldern 0 bis 22 dwfiniert wird.
Somit führt Bytes_to_send(23) = &HFA zur Fehlermeldung
Schreib bei dem Dim ne 24 in die klammer und der Fehler sollte behoen 
sein

von Rolf I. (for_ro)


Lesenswert?

Zwei Sachen dazu:
Ein 0-Byte wird als String End interpretiert. Wenn du S mit dem 
vorgeschlagenen Overlay setzt, wird S beim ersten 0-Byte enden. In 
deinem konkreten Beispiel bei Byte(14). An den Rest kommst du über 
String Funktionen nicht ran.
Falls überhaupt kein 0-Byte in den 23 Bytes vorkommt wird der String auf 
diese Weise nicht terminiert und könnte zu anderen Überraschungen 
führen.
Daher wäre es besser, das Byte-Array auf die Länge 24 zu setzen und das 
24. Byte explizit auf 0.

Für Serout brauchst du meines Wissens nach auch keinen String zur 
Ausgabe.
D.h. du könntest komplett auf S verzichten und so ausgeben:

Serout Bytes_to_send(1) , 23 , B , 1 , 9600 , 0 , 8 , 1      'Daten

Falls Serout das doch nicht kann, geht es mit
Printbin Bytes_to_send(1); 23

von neuer (Gast)


Lesenswert?

"S" ist ein String....steht in der Bascomhilfe

S=chr(Bytes_to_send(23))

dann geht es.

oder du machst es mit "printbin Bytes_to_send(23)"


gruss

von neuer (Gast)


Lesenswert?

...Ein 0-Byte wird als String End interpretiert. Wenn du S mit dem
vorgeschlagenen Overlay setzt, wird S beim ersten 0-Byte enden....

So ein kauderwelsch mit 0-Byte in String gibt es in bascom nicht beim 
programmieren.

von Tobi W. (todward)


Lesenswert?

wieso muss es eigentlich die Soft-Uart sein? Die HW-Uart ist doch besser 
und einfacher...

Ansonsten versuch es nochmal über google.
Und ganz wichtig: Poste mal den ganzen code....

Grüße
Tobias

von Oliver J. (skriptkiddy)


Lesenswert?

To W. schrieb:
> wieso muss es eigentlich die Soft-Uart sein? Die HW-Uart ist doch besser
> und einfacher...


Hier ist die Antwort ;)

Thomas Huber schrieb:
> Ich möchte per Software UART (der Hardware UART des Atmega wird zur
> kommunikation mit einem PC benötigt)

von Tobi W. (todward)


Lesenswert?

duck und wegrenn
:( Hätte ich das mal genauer gelesen :(

von Rolf I. (for_ro)


Lesenswert?

neuer schrieb:
> So ein kauderwelsch mit 0-Byte in String gibt es in bascom nicht beim
> programmieren.

Na, du scheinst dich ja richtig gut mit Bascom auszukennen.
Vielleicht liest du dir erst einmal die Hilfe zu Strings durch und 
merkst dann, was bei dem Overlay passiert.

neuer schrieb:
>S=chr(Bytes_to_send(23))
>dann geht es.
>oder du machst es mit "printbin Bytes_to_send(23)"

Beides wird nicht funktionieren, denn er will ja alle 23 Bytes ausgeben. 
Überlege mal, was bei deinen beiden Vorschlägen gemacht wird.

von Tobi W. (todward)


Lesenswert?

Rolf Im forum schrieb:
> ...denn er will ja alle 23 Bytes ausgeben.

Dann bau dir eine for-Next-schleife in der du die 23 bytes raushaust...
1
for i = 1 to 23
2
    Serout bytes_to_send(i) , 0 , B , 1 , 9600 , 0 , 8 , 1
3
next i

das ganze geht natürlich nur wenn die byte auch nacheinander eintreffen 
dürfen

von Rolf I. (for_ro)


Lesenswert?

To W. schrieb:

> for i = 1 to 23
>     Serout bytes_to_send(i) , 0 , B , 1 , 9600 , 0 , 8 , 1
> next i
Hast du dir schon mal den Sinn der 0 im Befehl Serout angesehen.
>
> das ganze geht natürlich nur wenn die byte auch nacheinander eintreffen
> dürfen

Gleichzeitig eintreffen geht ja schlecht.

von Tobi W. (todward)


Lesenswert?

Rolf Im forum schrieb:
> Hast du dir schon mal den Sinn der 0 im Befehl Serout angesehen.

Der Original befehl aus der hilfe lautet:
1
SEROUT var , bts , port , pin, baud , parity , dbits , sbits

Die null die du meinst findet man dort unter bts

Weiter unten in der Hilfe ist die funktion von bts beschrieben
Zitat:
1
The number of bytes to receive. String variables will wait for a return (ASCII 13). There is no check if the variable you assign is big enough to hold the result.

Wenn mich jetzt nicht all meine Englisch kenntnisse im stichlassen 
bedeutet das, dass dort lediglich die anzahl der zu empfangenen bytes 
festgelegt wird. Da er aber keine Bytes empfangen will sondern nur 
senden, kann das ruhig auf 0 bleiben und der Compiler gibt auch keine 
fehlermeldung aus (zumindest bei mir)

Rolf Im forum schrieb:
> Gleichzeitig eintreffen geht ja schlecht.

Du hast zwar recht aber ich meinte eigentlich was anderes! Ich wollte 
wissen ob es schlimm ist, dass nach jedem byte_to_send() ein LF CR 
angehängt wird also eine neue "zeile" beginnt. Würde er alles zu einem 
String zusammenfassen, hätte erlediglich ein LF CR

Grüße
Tobias

von Rolf I. (for_ro)


Lesenswert?

To W. schrieb:
> Rolf Im forum schrieb:
>> Hast du dir schon mal den Sinn der 0 im Befehl Serout angesehen.
>
> Der Original befehl aus der hilfe lautet:
>
1
> SEROUT var , bts , port , pin, baud , parity , dbits , sbits
2
>
>
> Die null die du meinst findet man dort unter *bts*
>
> Weiter unten in der Hilfe ist die funktion von bts beschrieben
> Zitat:
> The number of bytes to receive. String variables will wait for a
> return (ASCII 13). There is no check if the variable you assign is big
> enough to hold the result.
>
> Wenn mich jetzt nicht all meine Englisch kenntnisse im stichlassen
> bedeutet das, dass dort lediglich die anzahl der zu empfangenen bytes
> festgelegt wird. Da er aber keine Bytes empfangen will sondern nur
> senden, kann das ruhig auf 0 bleiben und der Compiler gibt auch keine
> fehlermeldung aus (zumindest bei mir)
>
Dein Englisch trügt dich nicht, aber hier ist die Anzahl an "bytes to 
send"
gemeint.
Daher kann man einfach schreiben.

Serout Bytes_to_send(1) , 23 , B , 1 , 9600 , 0 , 8 , 1      'Daten


> Rolf Im forum schrieb:
>> Gleichzeitig eintreffen geht ja schlecht.
>
> Du hast zwar recht aber ich meinte eigentlich was anderes! Ich wollte
> wissen ob es schlimm ist, dass nach jedem byte_to_send() ein LF CR
> angehängt wird also eine neue "zeile" beginnt. Würde er alles zu einem
> String zusammenfassen, hätte erlediglich ein LF CR

Weder Printbin noch Serout senden irgendetwas hinterher. Das musst du 
schon selber machen.

von Tobi W. (todward)


Lesenswert?

Rolf Im forum schrieb:
> Weder Printbin noch Serout senden irgendetwas hinterher. Das musst du
> schon selber machen.

Hmmm, irgentwie komisch... Bei meinen Terminals (Sowohl das von der 
Bascom IDE als auch andere) fangen immer eine neue Zeile an wenn ich 
einzelne printbefehle hinter einander habe, es sei denn ich packe alle 
zusammen und mache da einen einzigen raus.

Grüße
Tobias

von Rolf I. (for_ro)


Lesenswert?

Es gibt einen Unterschied zwischen Print und Printbin.

von Thomas H. (hubtom)


Lesenswert?

Hallo,

Die Fehlermeldung kam in dieser Zeile (36): S = Bytes_to_send(23)
Danke erstmal für das Feedback. Ich habe zwar jetzt ein anderes Hex 
Muster im Programm aber das ändert ja ansich nichts.

Folgende Lösung hat nicht Funktioniert: (Vorschlag von Gast)

 $regfile = "m32def.dat"
 $framesize = 40
 $swstack = 10
 $hwstack = 32
 $crystal = 14745600
 $baud = 9600


Dim S As String * 6                                         'Deklaration 
eines String Array mit 6 Elementen
S = Chr(bytes_to_send(6))

Bytes_to_send(1) = &HAA
Bytes_to_send(2) = &H52
Bytes_to_send(3) = &HCC
Bytes_to_send(4) = &H33
Bytes_to_send(5) = &HC3
Bytes_to_send(6) = &H3C





Do

Serout S , 0 , B , 1 , 115200 , 0 , 8 , 1                   'Daten 
Senden

'                                      ^  1 stop bit

'                                  ^----  8 data bits

'                                ^------  even parity (0=N, 1 = E, 2=O)

'                        ^--------------  baud rate

'                  ^--------------------  pin number

'               ^-----------------------  port so PORTB.1 is used

'           ^---------------------------  for strings pass 0

'      ^--------------------------------  variable

Wait 1

Loop

End


Die Lösung von Holgar hat funktioniert:

 $regfile = "m32def.dat"
 $framesize = 40
 $swstack = 10
 $hwstack = 32
 $crystal = 14745600
 $baud = 9600


Dim S As String * 6                                         'Deklaration 
eines String Array mit 6 Elementen
Dim Bytes_to_send(6) As Byte At S Overlay                   'Macht aus 
dem Byte einen String

Bytes_to_send(1) = &HAA
Bytes_to_send(2) = &H52
Bytes_to_send(3) = &HCC
Bytes_to_send(4) = &H33
Bytes_to_send(5) = &HC3
Bytes_to_send(6) = &H3C





Do

Serout S , 0 , B , 1 , 115200 , 0 , 8 , 1                   'Daten 
Senden

'                                      ^  1 stop bit

'                                  ^----  8 data bits

'                                ^------  even parity (0=N, 1 = E, 2=O)

'                        ^--------------  baud rate

'                  ^--------------------  pin number

'               ^-----------------------  port so PORTB.1 is used

'           ^---------------------------  for strings pass 0

'      ^--------------------------------  variable

Wait 1

Loop

End


Eine Frage hätte ich noch, ich nutze ja den Software UART mit 115200 
Baud und den Hardware UART zur kommunikation mit einem PC will ich mit 
9800 Baud Betreiben (Quellcode hierfür hab ich noch nicht). Mein Quarz 
hat 14,745600 Mhz (laut Tabelle 70 im Atmega Datenblatt beträgt er 
Fehler bei beiden f 0%), ist das schon möglich? Oder können Software und 
Hardware UART nur mit der gleichen Baudrate betrieben werden?

Gruß und herzlichen Dank nochmals

Tom

von Tobi W. (todward)


Lesenswert?

Nein du kannst beide Uarts von ein ander getrennt behandeln.
Also wenn meinet wegen die HW-Uart mit 2400 Baud läuft, kann die 
Soft-Uart auch mit 19200 Baud laufen, das ist föllig egal.
Worauf du lediglich achten solltest ist der fehler aber da hattest du ja 
schon gestätigt das es geht.

Grüße
Tobias

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.