Ringpuffer im Ram und keine Ahnung !! in Assembler

OP #460962
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
Gast #460966
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,...)
Gast #460967
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.
#461049
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
(Firma: TravelRec.) Persönliche Seite #461100
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.
OP #461386
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 ?
Gast #461418
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.
OP #461431
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.
OP #461538
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
(Firma: TravelRec.) Persönliche Seite #461574
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.
(Firma: TravelRec.) Persönliche Seite #462013
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren