www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik [ASM]String von UART aufteilen


Autor: pilo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Ich glaube hier gibt es die richtigen Menschen, die mir bei meinem 
Problem helfen können :)

Problem ist folgendes:

Ein AVR (Mega8) soll vom PC per UART einen String nach dem Schema a/b/c 
gesendet bekommen.
Der AVR soll dies nun zerlegen und a -> R17 , b -> R18 und c -> R19 
speichern. Also treu nach der funktion split() in Bascom AVR.
Der Wertebereich: 0 =< a,b,c =< 255 (Also jeweils 1 Byte)

Meine Frage nun:
Wie genau läuft diese Splittung ab? Ich habe absolut keine Ahnung, wie 
ich das machen soll. Um Hilfe wäre ich sehr dankbar!

PS: Bin noch Neuling in ASM. Kenne mich zwar schon ein wenig aus, aber 
bitte nicht zu kompliziert :)

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es kommt für die Antwort auf Deine Frage an, ob Du selbst das 
Datenregister ausliest oder ob eine schon vorhandene Funktion die 
empfangenen Bytes in einem Buffer speichert. (Buffered IO)

Falls ersteres der Fall ist, dann würdest Du solange warten bis das 
Datenregister etwas enthält, also etwas empfangen wurde. Günstigerweise 
geschieht dies in einem Interrupt. In dem Interrupt lädst Du dann den 
Inhalt des Datenregisters erstmal irgendwohin. Damit der Interrupt immer 
das selbe machen kann, wird das empfangene Byte eben auch immer in das 
selbe Register geladen. Zusätzlich setzt Du ein weiteres (immer 
gleiches) Register. In der HAuptschleife fragst Du diese zweite Register 
ab und falls es gesetzt ist, speicherst Du das erste Register in das 
letztlich gewünschte R17, R18, R19. Zusätzlich brauchst Du also noch ein 
Register in dem Du die empfangenen Bytes zählst.

Im zweiten Fall, wird die Empfangsroutine auch irgendwie zu erkennen 
geben, das etwas empfangen wurde und es wird eine weitere Routine geben 
mit der das zuletzt empfangene Byte aus dem Buffer gelesen werden kann. 
Ab hier ist es dann wie im ersten Fall. Du zählst mit und speicherst je 
nach Zählerstand in R17, R18 oder R19.

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da Du sowieso noch am Anfang stehst, würde ich das Problem in zwei 
Schritten angehen.

1. Unabhängig davon, wieviele Bytes Du erwartest, erstmal einfach Bytes 
von der seriellen Schnittstelle lesen.
2. Dann erst anfangen mitzuzählen und in R17, R18 und R19 verteilen.

Autor: oldmax (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Ich habe bisher meine UART_Routinen mit einem Buffer geschrieben. So 
erklärt bspw. Buffer:   .Byte 100 einen 100 Byte großen Adressraum. Das 
Z-Register (R26 / R27) wird zum Adressierregister erklärt.
LDI  ZL,LOW(Alarm_CTRL_B)  ; Z-Pointer auf Pufferadresse
LDI  ZH,HIGH(Alarm_CTRL_B) 

Mit zwei Variablen
  Read_Pos: .Byte
  Write_Pos: .Byte
          hast du einen Offset auf die Pointeradresse.
   
IS_Was_Da:
   ;  Buffer lesen, wenn Read_Pos und Write_Pos unterschiedlich
   LDS Reg_1, Read_Pos ; Leseposition erhöhen
   INC Reg_1
   CPI Reg_1, 100  ; Grenze abfragen
   BRLO Store_RP ; Zeiger ablegen
   CLR Reg_1
Store_RP:
   STS Read_Pos, Reg_1
   ADD ZL, Reg_1    ; 
   ADC ZH, 0                 ; 16 Bit Addition für die Leseposition
   LD Reg_1, Z               ; Wert einlesen
   STD Work_Byte, Reg_1  ; und zur Verarbeitung ablegen
   .... ; oder weiter auswerten
  RET
Wie funktioniert’s? Eigentlich ganz einfach. Die beiden Variablen 
Read_pos und Write_pos sind zuerst gleich, daher wird im Main – Programm 
zyklisch auf Ungleichheit geprüft.
   LDS Reg_1, Read_Pos
   LDS Reg_2, Write_Pos
   CP Reg_1, Reg_2
   BREQ Is_Nix
   RCALL IS_Was_Da
Is_Nix:
   .....

Die Interrupt-Routine vom USART läuft in gleicher Weise wie die 
Leseroutine, nur das ein Wert in den Puffer geschrieben wird. Dabei 
verändert sich der Zeiger Write_Pos und das Hauptprogramm erkennt eine 
eingetroffene Information. Das erste Byte wird bearbeitet. Laufen 
weitere Bytes ein, wird die Differenz zwischen Read_pos und Write_Pos 
größer, kommen keine Daten mehr, findet irgendwann ein Ausgleich beider 
Zeiger statt.
Gruß oldmax

Autor: pilo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm..
Ich blicke durch diese ganzen Beispiele nicht ganz durch..
Der String, den der AVR bekommt ein String a'la "255/255/255" (Das ist 
maximum)

Nun möchte ich die bytes einzeln in Register speichern.
Täusche ich mich, oder sind die / auch Bytes? Dann wären es 5 Bytes, 
wobei die Slashes wegfallen sollen. Mich interessieren nur die Integers 
:)

Oder sollte ich da überhaupt keinen trenner einbauen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
pilo schrieb:
> Hm..
> Ich blicke durch diese ganzen Beispiele nicht ganz durch..
> Der String, den der AVR bekommt ein String a'la "255/255/255" (Das ist
> maximum)

OK, also String Übertragung

> Nun möchte ich die bytes einzeln in Register speichern.
> Täusche ich mich, oder sind die / auch Bytes?

Klar.
Alles was du vom PC bekommst, jedes einzelne Zeichen, ist letztendlich 
ein Byte

> Dann wären es 5 Bytes,

Nein. Es sind 11
Das heißt: ohne das Trennzeichen, das du noch benötigst um das Triplet 
einwandfrei erkennen zu können

Für den Text  "255/255/255" bekommst du nacheinander die Bytes

0x32 0x32 0x35 0x2F 0x32 0x32 0x35 0x2F 0x32 0x32 0x35

geliefert. Einfach mal nach "ASCII Tabelle" googeln und du verstehst wie 
diese Bytes zustandekommen.

> wobei die Slashes wegfallen sollen. Mich interessieren nur die Integers
> :)
>
> Oder sollte ich da überhaupt keinen trenner einbauen?

Wie willst du dann im Text
   234512
die 3 Zahlen identifizieren. Ist das jetzt 234 51 2 oder 23 45 12 oder 
234 5 12 oder ....

Als allererstes musst du dir im klaren sein, wie du in Assembler einen 
String (also eine Abfolge von Zeichen) speichern willst. Damit fängt 
alles an.

Autor: oldmax (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi
Ich nehme an, Pilo redet von Bytes, die er überträgt, das wären dann 5, 
nur ist dies äußerst ungeschickt ausgedrückt. Also, entweder du 
überträgst Bytes oder ASCII, da solltest du dir schon klar drüber sein. 
Dem Controller ist's so ziemlich egal, was die USART- Routine bekommt, 
daher hab ich dir das Beispiel mit dem Puffer geschrieben. Wenn du es 
richtig machst, löst der USARt einen Interrupt aus, wenn er ein Byte 
erhalten hat. Dieses muß nun irgendwo gemerkt werden, um irgendwann 
einmal bewertet zu werden. Das kann man in einem Puffer machen. ( 
Ringpuffer) Wenn du ASCII überträgst, könnte es sein, das dein PC gar 
nicht erst etwas sendet, weil er Steuerzeichen oder sonstwas aus dem 
ASCII-Code liest. Da mußt du schon wissen, was du tust. Willst du 
wirklich die 255 als ASCII verschicken, dann sieht das oaus, wie vorher 
beschrieben
"2","5","5", Bytewert 32h,35h,35h oder binär 00110010b, 00110101b, 
00110101b doder oder oder....
Befaß dich erst mal mit den grundlegenden Begriffen, dann verstehst du 
auch, im Controller diese zu bewerten.
Gruß oldmax

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.