Forum: Mikrocontroller und Digitale Elektronik Problem mit Adressierung, ADC Wert nutzen um "funktion" aufzurufen


von J. T. (chaoskind)


Angehängte Dateien:

Lesenswert?

Hallo Forum,
ich hab mal wieder ein kleines Problem, ich bin dabei n Programm für 
einen Atmega32 zu schreiben, um damit ein Display mit SED1520 Treiber 
anzusteuern, was soweit auch ganz gut funktioniert.

Den 2Khz Takt, den das Display
(http://www.pollin.de/shop/dt/NTE0OTc4OTk-/Bauelemente_Bauteile/Aktive_Bauelemente/Displays/LCD_Datavision_DG_12232.html)
braucht generiere ich noch aufm Breadboard mit nem NE555 fürs Debuggen, 
da als kleine Nebenfrage die Timer im Debugmodus nicht laufen. Ich 
debugge mit nem Dragon per JTAG, und meine mich zu erinnern irengdwo mal 
gelesen zu haben, "Timer laufen lassen während JTAG-Pause" oder so 
ähnlich, wenn jdm weiß, ob man das einstellen kann und wo, wär auch 
darauf ein kleiner Hinweis nett =).
Das Display, bzw der Treiber ist wohl gekillt, als mir das Poti zur 
Frequenzeinstellung auf 0Ohm rutschte, nur noch die 100Ohm die ich in 
Reihe hatte waren noch da, das ergab dann im einen im Nachhinein 
gemessenen Takt von ca  385KHz, das hat wohl den Speicher gegrillt? 
zumindest zeigt es jetzt nur sehr verzerrt und mit viel Phantasie das 
an, was ich eingebe, und es ist sehr "verrauscht".

Nunja zurück zum Thema, ich schreibe nun eine Funktion in Assembler 
(AVR-Studio 4.19) die mir "selbsgemalte Zeichen" aufs Display ausgeben 
kann,
was auch schon funktioniert, mit "festen" Zeichen. Nun hab ich das ganze 
erweitert, das auch variable Zeichen generiert werden können. 
Genaugenommen messe ich nen Wert per ADC, wenn ich den auf dem Display 
ausgeben möchte, steh ich ja nun vor dem Problem, das ich bei 8bit 256 
verschiedene "Zeichen" "malen" müsste, um jeden Wert ausgeben zu können. 
Um das zu umgehen hab ich mir eine Funktion geschrieben, die den 
Messwert in drei Ziffern umwandelt, ich glaub das ganze schimpft sich 
dann BCD.

Während dessen wird ein Wert generiert (die Länge des variablen 
Zeichens) diesen Speicher ich im RAM.
1
ldi    yh,high(Zusammengesetzt)    ;errechnete Zeichenlänge an den Anfang der 
2
    ldi    yl,low(Zusammengesetzt)      ;Tabelle für das zusammengestzte Zeichen schreiben
3
    st    y,Schleifen

Y-pointer steht auf 0x0060 der Wert in Schleifen ist 18.

Wenn ich nun diesen Wert wieder aufrufe,
1
 ldi    zh,high(Zusammengesetzt)
2
 ldi    zl,low(Zusammengesetzt)
3
 call          ZeichenAusgeben

in Zeichen ausgeben wird er dann mit
lpm             schleifen,z+
geladen, ist aber nicht wie zu erwarten 18, sondern10...

den gesamten Quelltext gibs im Anhang, gerne "hör" ich mit Anregungen 
für Verbesserung, Fragen usw an =)

MfG Chaos

P.S. Ich war mir nicht ganz sicher, ob die .aps oder .asm der Quelltext 
ist, da hab ich einfach beide angehängt =), evtl könnte ein Moderator ja 
die falsche wieder abhängen?

Ob die Zeichen wirklich hinauen so, weiß ich nicht genau, wie gesagt, 
mein Display macht nix vernünftiges mehr.

von J. T. (chaoskind)


Lesenswert?

P.P.S.
Während ich das geschrieben hab, sind mir einige Sachen am Code auf- und 
eingefallen, deshalb ist der Titel nicht mehr bzw irreführend. Das 
Problem mit dem ADC hat sich "unterwegs" geklärt.

von J. T. (chaoskind)


Lesenswert?

Ich versteh es einfach nicht,

ich hab inzwischen die Position von der Tabelle in die gespeichert ein 
wenig verschoben, sie ist nun an Position 0x0063, wenn ich nun auslese, 
was er an die erste Position gespeichert hat, bekomme ich zurück was 
gespeichert wurde.
Das ganze aber nur, wenn ich per
lds (Adresse) auslese...

wenn ich versuche, einen Pointer an die Adresse zu setzen, egal ob Z 
oder Y, liest er völlig wirre Werte aus...
ldi  zh,(high) (adresse)
ldi  zl,(low) (adresse)
lpm  a1,z+

von spess53 (Gast)


Lesenswert?

Hi

>wenn ich versuche, einen Pointer an die Adresse zu setzen, egal ob Z
>oder Y, liest er völlig wirre Werte aus...
>ldi  zh,(high) (adresse)
>ldi  zl,(low) (adresse)
>lpm  a1,z+

Ich gehe mal davon aus, das deine Tabelle im Flash liegt.

Der Flash wird 'word'-weise adressiert. Also zeigt 'adresse' auf ein 
Word. LPM verlangt aber eine Byteadresse. Da ein Word zwei Bytes enthält 
muss also der Inhalt von Z doppelt so groß sein wie 'adresse':

ldi  ZH,high(adresse<<1)
ldi  zl,low(adresse<<1)

Statt 'adresse<<1' kann man auch 'adresse*2' benutzen.

MfG Spess

von nobi (Gast)


Lesenswert?

lpm liest im Gegensatz zu lds aus dem Programm memory, also aus dem ROM;

Daher bekommst Du natürlich nicht das zurück, was Du zuvor ins Ram 
geschrieben hast.

von J. T. (chaoskind)


Lesenswert?

Und wie lese ich dann aus dem Ram aus?

wenn ich es per

lds a1,(adresse) mache, dann klappt es, dann gibt er mir die Länge aus, 
aber damit kann ich ja nicht auf die nächsten Bytes der Tabelle 
zugreifen...

Gibt es nicht auch einen Befehl, mit dem ich per Pointer aus dem Ram 
laden kann?  So wie "st  pointer+,reg"?

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

j. t. schrieb:
> Gibt es nicht auch einen Befehl, mit dem ich per Pointer aus dem Ram
> laden kann?  So wie "st  pointer+,reg"?

Logisch, der Befehl heißt "ld".

Hast du das PDF "8-bit AVR Instruction Set"? Da sind alle Befehle 
erklärt.

von nobi (Gast)


Lesenswert?

Aus dem Ram kanns Du mit LD Auslesen
LD

Auszug aus ASM Hilfe:
ii)LD Rd, X+             0 ≤ d ≤ 31

aber wenn du schon eine Tabelle verwendest, wäre es nicht sinnvoler 
diese im ROM abzulegen?

.CSEG
TABELLE: .DB  data1,data2...

von J. T. (chaoskind)


Lesenswert?

Und wie lese ich dann aus dem Ram aus?

wenn ich es per

lds a1,(adresse) mache, dann klappt es, dann gibt er mir die Länge aus, 
aber damit kann ich ja nicht auf die nächsten Bytes der Tabelle 
zugreifen...

Gibt es nicht auch einen Befehl, mit dem ich per Pointer aus dem Ram 
laden kann?  So wie "st  pointer+,reg"?

Also nochmal, ich setze an anderer Stelle aus mehreren Zeichen die im 
Flash liegen, ein neues Zeichen zusammen.

Die Zeichen hab ich mir so definiert, das die erste Stelle der Tabelle 
als Zeichenlänge interpretiert wird.

also in pseudocode
1
ldi y,(zusammengesetztesZeichen+1)
2
ldi z,(zeichen1*2)
3
4
lpm a1,z+
5
add neuesZeichenLänge,a1
6
mov aktuellesZeichenLänge,a1
7
call weitere zeichenauslesen
8
9
ldi z,(zeichen2*2)
10
lpm a1,z+
11
add neuesZeichenLänge,a1
12
mov aktuellesZeichenLänge,a1
13
call weiteres zeichenauslesen
14
15
16
ldi y,(zusammengesetztesZeichen)
17
st  y,neuesZeichenLänge
18
19
weitere zeichenauslesen:
20
lpm a1,z+
21
st  (zusammengesetztesZeichen),a1
22
dec aktuellesZeichenLänge
23
brne weiteres zeichenauslesen
24
ret

damit wird das neue Zeichen erstellt.

Es müsste also an Adresse (zusammengesetztesZeichen) liegen. Aber da es 
ja länger ist als ein Byte, kann ich da ja nicht direkt drauf 
zugreifen...

von J. T. (chaoskind)


Lesenswert?

Während ich das hier schrieb, trudelten die Antworten mit LD ein ~an 
kopf hau. Klar da hät ich auch von selbst drauf kommen können.

Kann ich den so eine veränderliche Tabelle auch ins Rom tun?, das hat 
doch nur ne begrenzte Anzahl Schreibzyklen? Da die Tabelle ja je nach 
Zugriff geändert wird, hab ich die lieber ins Ram getan.

Ich werd mal Versuchen die Änderungen einzubauen und sehen obs dann 
läuft, wenn ja, und falls Intresse besteht, kann ich den aktuellen Code 
dann nochmal hochladen

MfG und vielen Dank schonmal, Chaos

von nobi (Gast)


Lesenswert?

Ne sorry, mit der veränderlichen Tabelle hab ich zu spät gelesen, dann 
ist das RAM schon richtig, ausser Du hast genug Platz fuer alle 256 
Zeichen, und generierst Diese zum Beispiel über ein kleines PC Programm, 
und fuegst das Ergebniss dann per Copy Paste als Konstannte Tabelle ins 
Rom ein.

von J. T. (chaoskind)


Lesenswert?

Genau so soll es am Ende gelöst sein =), ich habe einen Zeichensatz im 
Rom, und daraus werden die benötigten Zeichen, je nach Bedarf zu einem 
neuen Zeichen zusammengesetzt

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.