Moin moin, ich habe eine (?) Frage zur HW UART Kommunikation und vor allem zur interpretierung der gesendeten Zahlen. Ich muss von einem PC aus eine Dezimalzahl vorgeben, die dann im Atmel als Anzahl der Schleifendurchläufe einer For-Next Schleife eingesetzt wird. Diese Zahl liegt zwischen 0 und 999999. Auf dem PC wird die Zahl über ein Labview Programm über die RS232 in HEX gesendet. Wie bekomme ich nun die Zahl in eine Variable, mit der die For-Next Schleife arbeiten kann? Unten ist das Programm, mit dem ich momentan etwas experimentiere, aber es kann nur einen Tastendruck verarbeiten. Wie kann ich z.B. 50.000 aus den vom PC gesendeten HEX Zahlen in eine Variable quetschen? Das kommt ja soweit ich weiß als String an. Ich wäre für gute Tipps sehr sehr dankbar! $regfile = "m8def.dat" $crystal = 16000000 $baud = 115200 Dim i As Byte Dim A As Byte Config Portb.3 = Input Portb.3 = 1 Do If Usr.rxc = 1 Then 'Wenn Byte empfangen... I = Udr 'Byte aus UART auslesen End If If Pinb.3 = 0 Then 'wenn Taster gedrückt, wird die 'Schleife gestartet For A = 0 To I Print "Durchlauf Nr.: " ; A '"A" zeigt den ASCII Wert des 'gedrückten Buchstabens Bsp. 'ENTER = 13 => 13 Durchläufe Next Waitms 200 End If Loop End
So vielleicht: >Do A=0 Loop >If Usr.rxc = 1 Then 'Wenn Byte empfangen... > I = Udr 'Byte aus UART auslesen if i<>13 A = A*10+(asc(i)-'0') >End If until I = 13; Loop Die Schleife endet mit dem Drücken der Enter-Taste.
Fehler über Fehler. Das hilft mir leider nicht weiter.
>Fehler über Fehler. Das hilft mir leider nicht weiter.
Das liegt vermutlich daran, dass ich keine Ahnung von Bascom habe, und
du keine vom Programmieren...
Toller Post, deshalb frage ich ja hier. Mehr als "hängengeblieben!" fällt mir dazu nicht ein. Geh ins Bett!
>Mehr als "hängengeblieben!" fällt mir dazu nicht ein. Geh ins Bett! OK: Es läuft so, dass man die Zeichen, die von der seriellen Schnittstelle empfangen werden in Zahlen wandelt. Der Zahlenwert eines Zeichens wird in manchen Basic-Dialekten mit "ASC()" bestimmt (das Gegenteil dazu ist "chr()"). >A=0 >Loop >If Usr.rxc = 1 Then 'Wenn Byte empfangen... > I = Udr 'Byte aus UART auslesen > if i<>13 A = A*10+(asc(i)-'0') >End If >until I = 13; Etwas Quatsch steht da auch (war aus der Hüfte geschossen...): >asc(i) - '0' sollte eher i-asc("0") heissen (asc("0") müsste 48 sein siehe hier: http://de.wikipedia.org/wiki/Ascii) Eine "1" steht im ASCII-Zeichensatz an der Stelle 49. Eine "2" steht im ASCII-Zeichensatz an der Stelle 50. . . . Durch die Subtraktion wird also aus dem ASCII-Wert ("0"..."9") ein numerischer Wert (0...9). A = A*10 sollte klar sein. A = A*10 +(i-48) auch... Diese Abfrage soll einfach so lange erfolgen bis die Entertaste (I=13) empfangen wurde. Ist das kompliziert?
Ja ist es leider. Ich will 999.999 vom PC aus in HEX senden und im Atmel in eine For Schleife einsetzen. ... Variable = UDR '(999.999 geht natürlich so nicht! Hilfe!!) For I = 0 To Variable blablabla Next ...
Hallo, schau mal in der Bascom Hilfe mit der Suche nach "Val" und "Uart" jeweils das erste Ergebnis an. Gruß Jürgen
> Ich will 999.999 vom PC aus in HEX senden
Was schickst du genau?
Schickst du die Zahl in einer Textform
oder schickst du sie in binärer Form?
Wenn du also eine Zahl 48 hast, was kommt
über dann über die Schnittstelle:
Ein String, sprich eine Abfolge von ASCII Zeichen mit
dem Inhalt '4' '8' oder schickst du nur 1 Byte mit
dem Inhalt 48.
Die Angabe von Hex in deiner Frage macht hier nicht wirklich
Sinn. Entscheidend ist erstmal: Textform oder Binärform.
>Ich will 999.999 vom PC aus in HEX senden und im Atmel in eine For >Schleife einsetzen. Was soll der Atmel in einer sooo ungeraden Schleife?
>Was soll der Atmel in einer sooo ungeraden Schleife? Ok, die Schleife soll eine bestimmte Anzahl von Messzyklen an IGBTs abarbeiten. Die sollen im Einschaltverhalten geprüft werden und werden mit 150A bestromt, bis sie sich auf eine bestimmte Temperatur erhitzt haben und dann wird noch anderer Kram gemacht, um den es erstmal nicht geht. Die Anzahl der Zyklen will ich per PC an den uC übermitteln. >Die Angabe von Hex in deiner Frage macht hier nicht wirklich >Sinn. Entscheidend ist erstmal: Textform oder Binärform. Das glaub ich gerne, ich bin nämlich momentan sehr verwirrt. Es ist so, dass in Labview (kennst Du das Programm? Ist graphische Programmierung in Richtung Messtechnik würde ich mal so sagen.) Daten über die RS232 geschickt werden können. Soweit ich es rausfinden konnte, werden die Daten in HEX über das Kabel geschickt. Das hab ich mit dem Programm "Free Serial Monitor" oder so ähnlich gemacht. Wenn ich z.B. die Entertaste drücke, wird ein 0D gesendet, also HEX. Darum hab ich davon geredet. Wenn das erstmal egal ist, um so besser. Es muss nur möglich sein, dass ich Zahlen bis 999999 (999 tausend, nicht 999,999!) von PC aus als Variable in die For Next Schleife bekomme. Ich habe gelesen dass man ein Feld anlegen kann, in dem dann ein String mit einer bestimmten Anzahl von Bytes gespeichert wird. Das ist prinzipiell ja schonmal ganz gut. Dann würde ich ja einen String so deklarieren: Dim Zyklenanzahl as String * 6 Des weiteren habe ich gelesen, dass man das Feld dann an einer bestimmten Stelle speichern kann und dann von der Stelle als Byte wieder auslesen und dann hat man es schon in eine Zahl gewandelt. Aber da ich erst seit kurzem uCs Programmiere, bin sitz ich wie das Schwein vorm Uhrwerk. Eigentlich wollte ich nicht soviel schreiben, weil das wahrscheinlich keiner bis zum Ende liest, aber ichhoffe es hilft weiter. nochmal in kurz: Es muss nur möglich sein, dass ich Zahlen bis 999999 (999 tausend, nicht 999,999!) von PC aus als Variable in die For Next Schleife bekomme. (Ob ich nun als String, HEX oder Byte von PC aus sende ist egal, das kann ich in Labview machen wie ich will, denk ich, die Umsetzung im uC ist das Problem)
Tut mir Leid, das hab ich jetzt vergessen: >Wenn du also eine Zahl 48 hast, was kommt >über dann über die Schnittstelle: >Ein String, sprich eine Abfolge von ASCII Zeichen mit >dem Inhalt '4' '8' oder schickst du nur 1 Byte mit >dem Inhalt 48. Die 48 bekomme ich bis jetzt über einen Tastendruck, also als ASCII '4' und '8' (wenn ich das richtig verstanden habe.) Mit dem Programm, dass den Serialport abhören kann, sieht man aber, dass die Zahl 48 in HEX gesendet wird. Aber das ist ja vielleicht egal und interessiert nicht weiter. ich wollte nur irgendwie verstehen, wer da was wie sendet.
>Wenn ich z.B. die Entertaste drücke, wird ein 0D gesendet, also HEX. >Darum hab ich davon geredet. Womit hast du das festgestellt? Es wird ein EINZIGES Byte übertragen. Ob HEX, DEC oder Binär - Das sind alles nur verschiedene Darstellungsformen für eine Zahl. Gehen wir von einer "normaldummer Mensch"-lesbaren Variante aus: Dezimale Schreibweise. Falls du dir inzwischen die ASCII-Tabelle angeguckt haben solltest, wirst du festgestellt haben, dass die '9' an der Stelle 0x39 = 57 dec steht. (Momentan aber irrelevant). Deine 999999 würde dann als 0x39 0x39 0x39 0x39 0x39 0x39 übertragen werden. Um dann noch festzustellen, dass alle Ziffern übertragen wurden, sendet man hinten dran noch ein Enter (CR = "Carriage return = 0x0D). So, jetzt wollen wir Zahlen empfangen: Dim i As Byte Dim A As Byte 'kann Zahlen zwischen 0 und 255 enthalten, LONG wäre passender... Config Portb.3 = Input Portb.3 = 1 Do A = 0; Do If Usr.rxc = 1 Then 'Wenn Byte empfangen... I = Udr 'Byte aus UART auslesen if (I <> 13) AND (I>=ASC("0")) AND (I<=ASC("9")) Then I = I-ASC("0") A = A*10 A = A+I END IF End IF LOOP UNTIL I = 13 'Enter wurde gedrückt If Pinb.3 = 0 Then 'wenn Taster gedrückt, wird die 'Schleife gestartet For I = 0 To A Print "Durchlauf Nr.: " ; I '"A" zeigt den ASCII Wert des 'gedrückten Buchstabens Bsp. 'ENTER = 13 => 13 Durchläufe Next Waitms 200 End If Loop End Könnte sein, dass da jetzt noch irgendwelche Syntax-Fehler drin sind...
> Die 48 bekomme ich bis jetzt über einen Tastendruck, also als ASCII '4' > und '8' (wenn ich das richtig verstanden habe.) > > Mit dem Programm, dass den Serialport abhören kann, sieht man aber, dass > die Zahl 48 in HEX gesendet wird Vergiss das HEX. Das ist eine ganz normale Textübertragung. HEX ist nur eine Darstellungsform für Zahlen, bzw in diesem Fall für Codes. Entscheidend ist aber was diese Codes bedeuten. Und bei dir ist: Eine Code -> Ein Buchstabe -> Eine Ziffer der Zahl die du Übertragen willst. Auf der Gegenstell musst du die Zahl wieder zusammensetzen. Du nimmst jedes Zeichen einzeln entgegen, ziehst den ASCII Codefür '0' davon ab und 'summierst' alles auf. Total = 0 while( nächstes Zeichen von der UART gehört noch zur Zahl ) Total = 10 * Total + ( nächstes Zeichen - '0' ) Die Umsetzung in BASCOM musst du delbst besorgen. Ah ich seh grade, Rahul war schon so freundlich
Ok, das sind schonmal gute Tipps. Ich werde mich da nachher mal ranmachen, ich habe ersmal mit dem Rest des Programms weiter gemacht. Viele Dank soweit!
>Ok, das sind schonmal gute Tipps.
Natürlich sind das gute Tipps! Die komme ja auch von Karl Heinz und mir.
So, durch die unglaublich tollen, geradezu übermenschlich guten Tipps von Rahul rennt der Hase. Vielen Dank an Karl Heinz. :) Hier der Code für Leute, die das gleiche Problem haben: ------------------------------------------------------------------------ -- $regfile = "m8def.dat" 'uC = Mega8 $crystal = 16000000 'Takt des Quarzes $baud = 9600 'Baud Rate für UART Dim I As Byte 'In diesem Byte wird die aktuell 'ankommende Zahl (in ASCII) gespeichert Dim A As Long 'Eingabe bis 2147483647 Print "Soweit so gut." Do A = 0 'A wird nach vor jeder neuen Ausgabe 'initialisiert Do If Usr.rxc = 1 Then 'Byte über UART empfangen... I = Udr 'Byte aus UART auslesen und in I schreiben If I <> 13 And I >= 48 And I <= 57 Then 'Wenn Byte nicht 13 (ASCII für "Enter") und '>= 48 (ASCII für "0") und <= 57 (ASCII für '9) dann I = I - 48 'ziehe 48 (ASCII für "0") davon ab '(Bsp.: Aus 49 (ASCII für "1") wird 'A = 49 - 48 = 1 (nun dezimal)) A = A * 10 'Zehnersystem! A = A + I 'Aufaddierung der Zahlen End If End If Loop Until I = 13 'Enter wurde gedrückt If I = 13 Then Print "Aktueller Wert: " ; A 'Nun wird die eingegebene Zahl wieder 'auf dem PC angezeigt. I = 0 End If Loop End ------------------------------------------------------------------------ --
Nachdem du jetzt weist, was da abgeht: Bascom wäre nicht Bascom, wenns dafür nicht schon was Fertiges gäbe. Wenn die Zeichen in einem String gesammelt werden, dann kann man ganz einfach die Funktion Val benutzen, die dann den String in eine Zahl umwandelt: Dim Instring as String*10 Dim Varval as Integer Instring = " 781" Varval = Val(Instring) 'Varval = 781 Für das Sammeln von Zeichen von der Uart bis zum Return gibt es sicherlich auch etwas.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.