Forum: Mikrocontroller und Digitale Elektronik Ringpuffer im Ram und keine Ahnung !! in Assembler


von M. _. (nover81)


Lesenswert?

ich möchte Daten an ein LCD aus geben. Da ich aber auch variablen habe 
kann ich die Daten nicht einfach aus dem flach holen und gut is, ein 
zwischenspeicher muss her und ich dachte ein Ring ist dafür am besten 
geeignet da ich aber Assembler Anfänger bin weiß ich nicht genau wies 
geht jede Hilfe nehme ich dankend an !!!

dank euch schon im voraus

von Ronny (Gast)


Lesenswert?

Zunächst: Welcher Mikrocontroller ist es den?Falls 'flach' Flash heissen 
soll könnte ich jetzt raten,das du einen AVR benutzt und aufgrund der 
Harvard- Architektur nicht RAM und Flash mit dem selben Assembler-Befehl 
ansprechen kann.

Ganz wichtig ist auch die Frage wieviel RAM dein Controller hat.Wenn der 
nämlich knapp ist,muss dann trickreich zwischen den konstanten Daten 
(aus dem Flash) für z.B. Menüeinträge und den variablen Werten (aus dem 
SRAM) für z.B. berechnete Ergebnisse oder Werte aus dem A/D-Wandler 
unterschieden werden.

Auf dem AVR würdest du dann wahrscheinlich 2 Funktionen (hier mal als 
C-Prototypen) benötigen:

void LCD_FromFlash(char *buffer,int nsize);
void LCD_FromSRAM(char *buffer,int nsize);

Wie diese beiden Funktionen dann aufgebaut sein müssen,hängt von deiner 
Hardware ab.(Controllertyp,LCD-Typ/Anbindung,internes/externes 
Flash/Ram,...)

von Stefan (Gast)


Lesenswert?

Beschreibe die Rechenvorschrift mit eigenen Worten oder einer anderen 
Programmiersprache und daraus kann man später einen Assemblerquellcode 
bauen.

Wenn du in C formulieren kannst, ist - wenn du verrätst welchen µC du 
benutzen willst - wahrscheinlich sogar eine automatische Umwandlung 
möglich.

von M. _. (nover81)


Lesenswert?

SRY flach )es ist nen avr Noch als probe ein mega8 laut Daten Blatt hat 
er 1k Byte ; dir rotine fürs LCD habe ich sebst gebastelt das ist das 
8x24 Seiko C338008 /Samsung 0282A

von Peter D. (peda)


Lesenswert?

Ringpuffer haben die unangenehme Eigenschaft, überlaufen zu können.

Obendrein kann der Mensch nur langsam lesen, Überschriebenes geht 
verloren.

Auch brauchst Du im Ringpuffer zusätzliche Positionierungsdaten.


Daher ist ein Display-Puffer besser geeignet, der von den Tasks gefühlt 
wird und z.B. alle 200ms ausgegeben wird.


Peter

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Genau, so viele Speichezellen (Bytes) im SRAM anlegen, wie das Display 
Zeichen hat. Diesen SRAM-Bereich gibst Du Timergesteuert ständig, oder 
nur wenn´s nötig ist, an das Display aus. Wenn Du dies in eine 
schnuckelige Routine packst, die ein Timerinterrupt startet, brauchst Du 
Dich im Programm gar nicht mehr darum zu kümmern. Willst Du die ein 
Zeichen auf dem Display ändern, schreibst Du einfach an die betreffende 
Stelle im SRAM einen anderen Wert. Mit dem nächsten Ausgabezyklus steht 
der dann auf dem Display. Mittels der Pointer X, Y, und Z kannst Du 
ganze Texttabellen aus dem Flash sehr einfach einblenden oder auch 
scrollen oder sonstwas.

von M. _. (nover81)


Lesenswert?

Danke für die Hilfe!!!
Mir ist heute morgen noch eine andere Idee gekommen. könnte man nicht 
jeder variable einen eigenen string im Ram  geben? Ich könnte mir 
vorstellen das man sich damit eine menge Arbeit spart, und man könnte 
jedem string einer bestimmten Adresse im Ram des Display zuordnen. Die 
string Adressen kann man ja dann einfach aus dem Flash laden.

Geht das so auch oder ist das eine schlechte Idee ?

von Philipp B. (philipp_burch)


Lesenswert?

In Assembler gibt es keine Strings, da hast du nur Speicherbereiche.
Ausserdem solltest du dir angewöhnen, deinen Text vor dem Absenden 
nochmal zu überlesen und gegebenenfalls so anzupassen, dass ein Dritter 
drauskommt, was du eigentlich sagen willst.

von unbeschreiblicher Rahul (Gast)


Lesenswert?

Du kannst auch jede Variable an eine entsprechende Funktion übergeben, 
die dir den "Text" dann auf dem Display an einer bestimmten Stelle 
ausgibt.

von M. _. (nover81)


Lesenswert?

@ Philipp Burch

Mit string ist eine Aneinanderreihung von auf einander folgenden ram 
Adressen gemein. Aber ich hoffe das dass grundlegende in meinem Post 
herauszulesen ist.

@unbeschreiblicher Rahul

Wie soll ich mir das mit den Funkionen vorstellen?

von unbeschreiblicher Rahul (Gast)


Lesenswert?

Du übergibt der Funktion bspw. ein Byte, dann noch Zeile und Spalte.
Die Funktion macht dann aus der Zahl einen Text, der auf dem Display 
ausgegeben wird.
Dann gibt es eine Funktion, die Text an einer bestimmten Stelle ausgibt.
Dann gibt es eine Funktion, die einzelne Zeichen an einer bestimmten 
Position ausgibt.

Man braucht also 2-3 Funktionen, die sich damit beschäftigen, Zahlen in 
ASCII-Zeichen zu wandeln und diese dann auszugeben. Text braucht man 
natürlich nicht mehr wandeln...

Ich merke gerade: Ich programmiere zu viel C...Du willst es ja in 
Assembler machen.

von M. _. (nover81)


Lesenswert?

In umrissen kann ich mir jetzt vorstellen wie es geht. aber das ist dann 
ja ganz ähnlich wie das was ich vor hatten. Nur geht es mir mehr oder 
minder darum, wie ich es Speicher. Da ich nicht immer warten möchte bis 
alles übertragen ist. sonder auch noch Taster etc. auswerten möchte.

von M. _. (nover81)


Lesenswert?

Ich habe mal in groben umrissen geschrieben  wie ich mir das ungefähr 
gedacht habe :

=======================================================
.equ string1=0x0060    ;+12 Byte
.equ string2=0x006c    ;+12 Byte
.equ string3=0x0078    ;+12 Byte
.equ string4=0x0084    ;+12 Byte

.def temp1,r16
.def str,r18

loop:
;(jetzt irgendwas an befehlen)
rjmp loop

dat1s:        ;Byte in den ram legen
  ldi yh,high(string1)
  ldi yl,lowe(string1)
  st y+,temp1
  ret

dat1l:        ;Byte aus den ram holen
  ldi yh,high(string1)
  ldi yl,lowe(string1)
  ld y+,temp1
  tst t1mp1
  breq out_end
    rjmp lcd_out

out_end:
sbrc str,0
ret
===================================================================

Das str Register ist nur da damit man weiß wann es etwas zu tun gibt. 
Das was ich mir denke ist:
ich schreibe die variable in den ram (string1) und setze bit0 von str 
auf 1 wenn alles im ram ist. danach würden die Daten nacheinander an das 
LCD übergeben werden, nach jedem byte geht es dann erstmal wieder in das 
Hauptprogramm usw. wen dann alles Übertragen wurde setze ich bit0 von 
str wider  auf 0 . so spare ich mir das warten bis ich das nächste byte 
senden kann.

p.s. Wen das nicht so geht (der code komplett falsch ist ) dann wäre ich 
sehr froh wen ihr mir helfen würdet!!!

danke nochmals für alles

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Paar Schreibfehler: muß low(...) statt lowe(...) heißen. Und tst templ 
statt tst tlempl. Wenn man den ganzen Code sehen könnte, wäre es auch 
hilfreich. Und das ret am Ende bedingt zu überspringen, macht keinen 
Sinn, es kann zu einem Stackoverflow kommen. Etwas konfus das. Jede 
Unterroutine sollte einen an sich schlüssigen Block ergeben, der seine 
Aufgabe erledigt und aus dem nicht spaghettimäßig heraus- und 
hiningesprungen wird.

von M. _. (nover81)


Lesenswert?

Ich dachte das dass nicht bei jeder Sprungbefehl gemacht würd (z.B. rjmp 
werden da doch keine Sprungadressen in denn stack gelesen oder nicht ??? 
) Danke war schon sehr spät gestern habe mich gleich ran gesetzt und 
noch korrigiert XD .

von M. _. (nover81)


Lesenswert?

P.S. ich werde es posten wen es fertig ist !!!

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Nein, normale Sprünge schreiben nichts auf den Stack. Wenn Du aber das 
ret überspringst und somit nicht ausführst, steht jene Rücksprungadresse 
solange auf dem Stack, bis Du wieder ein rcall ausführst, woraufhin eine 
neue Rücksprungadresse dazugeschrieben wird. Geschieht das dann noch ein 
paar Male, läuft Dein Stack über, da die Adressen nicht abgeholt wurden. 
Im Gegenzug kann ein ret auch auf eine Adresse stoßen, die gar nicht für 
dieses bestimmt war. Somit läuft Dein Programm völlig aus dem Ruder. 
Somit sollte jedes rcall nach Abarbeitung einer kompakten Unterroutine 
auch immer ein passendes ret durchlaufen.

von M. _. (nover81)


Lesenswert?

das mache ich doch in der lcd_out rotine !!da würd der ret befel am ende
duchgefürt. aber das was ich vor habe get so oder nicht ???

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Poste mal, wenn fertig, Deinen kompletten Code - so wird das hier 
nichts.

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.