Forum: Mikrocontroller und Digitale Elektronik tabellen auslesen


von Rene (Gast)


Lesenswert?

Fragen über Fragen

ich habe eine tabelle mit 255 x 4 Zeichen

ich muß über einen wert von 0 bis jewals 255 4 Byts auslesen.

Wie macht man das am besten?

Die tabelle sieht so aus

meine_tabelle:  db. 255,0,0,0          ;0
                db. 254,1,0,0          ;1
                db. 253,2,0,0          ;2
                ...usw bis 255 zeilen  ;255
ich muß jetzt über z.B 2 den entsprechenden vierersatz auslesen
können.

um den Anfang zu finden habe ich das gemacht

ldi zl,low(meine_tabelle*2)
ldi zh,high(meine_tabelle*2)

mit lpm habe ich dann die werte ausgelesen

oder Brauche ich 4 tabellen mit je 255 werten?

danke für eure hilfe

von Rene (Gast)


Lesenswert?

ich verwende den mega8515

von Florian (Gast)


Lesenswert?

Was willst du den genau machen? So wie du das mit der Tabelle machen
willst, sieht sehr aufwendig aus....Geht bestimmt einfacher..



Erzähl mal,willst du, daß eine RGB Led ein und ausdimmt?????

Gruß Florian

von Rene (Gast)


Lesenswert?

genau das will ich

woher weißt Du?

die farben sollen sich aber "überlappen"

von Florian (Gast)


Lesenswert?

Hm, ist zwar auch nicht das einfachste, daß was ich dir heíer schreibe,
aber immer noch besser, als mit der langen Tabelle.

Nehmen wir mal 2 Register für rot:

.def pwm_red = r16
.def dir_red = r17

pwm_red ist die Helligkeit der Farbe rot.
dir_red ist die Richtung, ob die Led heller oder dunkler werden soll.

Lade am Anfang "dir_led" mit $01.

Dann machst du das:

add pwm_red,dir_red ;zähle 1 dazu oder eins ab
cpi pwm_red,$ff ;Vergleiche mit 255
breq end_red ;wenn ja, springe nach end_red
cpi pwm_red,$00 ;Vergleiche mit 0
breq end_red ;wenn ja, springe nach red_end
rjmp aus ;wenn es nicht 0 oder 255 ist, dann mache nichts

end_red:
com dir_red ; hier ist der Trick, sobald 0 oder 255 ist, machst du aus
$01 den Wert $ff

aus: weiter........

Wenn pwm_red 255 ist, das springt er ja zu pwm_end.
--> com dir_red
Beim nächten mal wird es dann:

add pwm_red,dir_red ; add pwm_red,255

Die 255 entsprechen dann eigentlich -1

-1 macht er solange, bi die Helligkeit auf 0 ist, und dann wieder
umgekehrt.

So jetzt kannst du mal eine Led ein und ausdimmen.

Das würde ich für alle 3 Farben so machen.

Nun brauchst du noch ein mode Register:

.def mode = r18

Mit mode sagst du, was ein oder ausgedimmt wird.

z.B. wenn mode 0 ist, dann dimme rot aus und grün ein.
wenn mode 1 ist, dann dimme grün aus und blau ein.
wenn mode 2 ist, dann dimme blau aus und rot ein.

wenn mode 3 ist, dann mache mode 0.

Also immer, wenn z.B die Helligkeit eines Wertes auf 0 oder 255 ist,
dann machst du com dir_red und com dir_green und inc mode.

Ich hoffe, du verstehst da irgendetwas, was ich schreibe.

Gruß Florian

von Rene (Gast)


Lesenswert?

danke Florian,
sehr guter Vorschlag

aber bei mir herrscht Registermangel die alle Irgendwo im Programm und
für Interupts schonmal gebraucht werden. Tabellen machen zwar mehr
arbeit sind aber so glaube ich auch flexibler wenn man andere
"Muster" haben will.

von Florian (Gast)


Lesenswert?

Registermangel? Dann machst du was falsch. Was macht das Programm den
noch, da du keine Register mehr zu verfügung hast. Es gibt ja dann noch
Register r0 bis r15.

Zu den Tabellen:

Viel Arbeit und viel Speicherverbrauch. Wenn du da mehrer modes haben
willst, dann geht sehr schnell der Speicher zu Ende.

Tabellen machen dann Sinn, wenn man z.B. ein unregelmäßiges Muster hat.
0b10000001,0b11000011,0b11100111 <---z.B sowas
Aber nicht bei 1,2,3,4,5,6,7,8,9,.........

Mein Tip, mach dir Gedanken darüber, wie man Tabellen vermeiden kann.

Wie man das z.B. machen kann, hab ich oben beschrieben.

Achja, zu deinen Registern... Machst du bei einem Interuppt auch push
und pop? Verwendest du das SRAM? Vielleicht stellst hier mal das
Programm rein, oder du schickst es mir, dann kann man mehr dazu sagen.

Gruß Florian

von A. N. (netbandit)


Lesenswert?

Registermangel?
Bei 32 Registern?
Andere µCs kommen mit nur einem Arbeitsregister aus :)

von Florian (Gast)


Lesenswert?

@ Rene

Mit welchem µC Arbeitest du?

Gruß Florian

von Rene (Gast)


Lesenswert?

AT Mega8515

Ist man mit einer tabelle nicht flexibler?
Speicher ist noch genug da.

von Florian (Gast)


Lesenswert?

Und was macht das Programm noch?

von Florian (Gast)


Lesenswert?

Ups, ein Fehler



add pwm_red,dir_red ; add pwm_red,254

Die 254 entsprechen dann eigentlich -1

von Hannes L. (hannes)


Lesenswert?

Bei mir sind 254 aber -2

...

von Florian (Gast)


Lesenswert?

Auwe, Hannes, jetzt hab ich semmel geschrieben...

255 = -1
1   = +1

und es heisst nich "com dir_red" sondern "neg dir_red".

Danke fürs korrigieren

Gruß Florian

von Florian (Gast)


Lesenswert?

@Rene

Wo ich angefangen habe zu programmieren, da habe ich auch ein Register
nach den anderen verbraten. Es ist auch verständlich, weil man von
einem Register verwöhnt wird. Ein normales Register muß man nicht erst
reinladen, sowie beim S-Ram. Man muß auch nichts abspeichern, sondern
einmal beschrieben, und es bleibt solange erhalten, bis man es löscht
oder anders benötigt.

Fang doch einfach an, dich mit dem S-Ram auseinanderzusetzen. Das blöde
ist nur, wenn ich einen Wert verändern will, dann brauch ich mindestens
3 Befehle:

lds temp,0x0060 ;<--laden ins tempregister
inc temp        ;<--Wert verändern
sts 0x0060,temp ;<--und wieder abspeichern

ist natürlich aufwendiger als:

inc r20

Am besten gehst du her, und bastelst dir macros für deine "eigenen"
Befehle.

Nehmen wir an, du hast zuwenig Register, willst aber mit S-Ram nix
machen, weil es dich nervt, zuerst laden, dann verändern und dann
wieder speichern...

Dann machst du folgendes:

.equ r32 = 0x0060
.equ r33 = 0x0061
.equ r34 = 0x0062
.equ r35 = 0x0063 ;usw....

So kannst du dir hunderte Register anlegen..
dann:
.macro incs
            lds  temp,@0
    inc   temp
    sts  @0,temp
.endmacro


.macro decs
            lds   temp,@0
    dec   temp
    sts   @0,temp
.endmacro

.macro ldo
            ldi   temp,@1
    sts   @0,temp
.endmacro


So, hier sind 3 Beispielbefehle, um dir das Leben zu erleichtern:

1.) Hier machen wir ein:
incs r32;wobei incs der neue Befehl ist, den du selber erschaffen hast

2.)Und hier:
decs r33; hier das gleiche, aber nur mit dec

3.) ldo r34,$10

Heißt soviel wie, lade "Register 34" 0x0062 mit dem Wert $10.

So kannst du deine eigenen Befehle machen und das Sram wie ein Register
behandeln.

@0,@1 <-----

das bedeutet:

ldo r34,$10

ldo ist dein Befehl
@0 ist das, was nach dem Befehl steht, also r34 oder 0x0062
@1 ist der Wert $10, weil es nach dem komma an zweiter Stelle steht.

Du kannst sogar @2 oder @3 nehmen.

z.B.

cps wert1,100,wert2,150

cps ist wieder ein erfundener Befehl

Im macro vergleichst du dann @0 mit @1 also wert1 mit 100
und @2 mit @3 also wert2 mit 150.

Ich hoffe, das programmieren wird für dich dadurch leichter. Und nimm
mehr S-Ram her, denn davon gibt es ja genug. Wahre Register sind vielzu
Wertvoll, um sie für das ganze Programm einfach so zu verbraten, weil
wenn man dann wirklich eines braucht, dann steht man da....

Gruß Florian

von Hannes L. (hannes)


Lesenswert?

Register nimmt man für die Variablen, auf die man sehr oft zugreifen
muss. Und auch für die Sachen, die sehr schnell gehen müssen
(Timer-ISR, die sehr oft aufgerufen wird). Die anderen Sachen kann man
ohne Weiteres im SRAM verwalten. Also bei mir waren Register und SRAM
noch nie knapp.

Das mit den Makros ist ja ganz nett (ich arbeite auch mit Makros, aber
nicht für solch triviale Dinge), sollte man aber erst machen, wenn man
es auch ohne kann. Sonst verliert man schnell die Übersicht und wundert
sich, wo die Rechenzeit oder der Flash-Speicher verbraten wird. Denn
STS/LDS belegen jeweils 2 Worte im Flash und brauchen auch jeweils 2
Taktzyklen zur Ausführung. Es ist also 5-facher Flash-Verbrauch und
5-facher Verbrauch an Rechenzeit. Da sollte man schon die Übersucht
behalten...

...

von Hannes L. (hannes)


Lesenswert?

"Sucht" iss gut... ("Übersicht")...

von Florian M. (----florian----)


Lesenswert?

"Das mit den Makros ist ja ganz nett, sollte man aber erst machen, wenn
man es auch ohne kann."

Da gebe ich dir recht, aber wenn man es versteht, dann sind macros
super, weil der Code meiner Meinung nach übersichtlicher wird. Man muß
nicht immer den S_Ram Wert in ein temp Register laden, dann verändern
und wieder speichern.

Ob ich es jetzt mit macros oder ohne macros mache, ist vom Speicher her
egal, da ja eigentlich nur das macro anstelle des neuen Befehles
eingebunden wird.

Wenn der Speicher nebensächlich ist, und es zeitlich nicht so eng ist,
dann kann man mit 2 Temp Registern auskommen.

Bei Rene ist es glaube ich so, das er ohne push und pop arbeitet und r0
bis r15 nicht nutzt, obwohl es auch Register sind.

von Hannes L. (hannes)


Lesenswert?

Nunja, r0..r15 sind ja nur "dumme Register". ;-)

Die werden bei mir meist zuerst verplant. Mit den oberen Registern bin
ich dann etwas geiziger. Als Temp-Register haben sich bei mir wl
(Working Low, r24) und wh (Working High, r25) eingebürgert.

Makros benutze ich hauptsächlich für die LCD-Ausgabe (Umwandlung aller
möglicher Dinge in ASCII und Ausgabe auf LCD).

Sicher kann man sich mittels Makros seine eigene Programmiersprache
basteln, aber ob dann das Programm noch für Andere verständlich ist?

...

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.