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 :)
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.
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.
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.
1 | LDI ZL,LOW(Alarm_CTRL_B) ; Z-Pointer auf Pufferadresse |
2 | LDI ZH,HIGH(Alarm_CTRL_B) |
Mit zwei Variablen Read_Pos: .Byte Write_Pos: .Byte hast du einen Offset auf die Pointeradresse.
1 | |
2 | IS_Was_Da: |
3 | ; Buffer lesen, wenn Read_Pos und Write_Pos unterschiedlich |
4 | LDS Reg_1, Read_Pos ; Leseposition erhöhen |
5 | INC Reg_1 |
6 | CPI Reg_1, 100 ; Grenze abfragen |
7 | BRLO Store_RP ; Zeiger ablegen |
8 | CLR Reg_1 |
9 | Store_RP: |
10 | STS Read_Pos, Reg_1 |
11 | ADD ZL, Reg_1 ; |
12 | ADC ZH, 0 ; 16 Bit Addition für die Leseposition |
13 | LD Reg_1, Z ; Wert einlesen |
14 | STD Work_Byte, Reg_1 ; und zur Verarbeitung ablegen |
15 | .... ; oder weiter auswerten |
16 | 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.
1 | LDS Reg_1, Read_Pos |
2 | LDS Reg_2, Write_Pos |
3 | CP Reg_1, Reg_2 |
4 | BREQ Is_Nix |
5 | RCALL IS_Was_Da |
6 | Is_Nix: |
7 | ..... |
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
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?
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.
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
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.