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
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,...)
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.
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
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
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.
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 ?
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.
Du kannst auch jede Variable an eine entsprechende Funktion übergeben, die dir den "Text" dann auf dem Display an einer bestimmten Stelle ausgibt.
@ 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?
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.
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.
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
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.
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 .
P.S. ich werde es posten wen es fertig ist !!!
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.
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 ???
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.