Forum: Mikrocontroller und Digitale Elektronik Compare-Wert mit LPM schreiben geht nicht (AVR-Classic)


von Markus Gäbel (Gast)


Lesenswert?

Hallo,

habe ein Problem.

Verwendeter Controller AT90S 8535
Unter  AVR-Studio 3.52 (habe noch 4.0 auf de Rechner, da das gleiche)
auf dem STK500 getestet.

Ich will PinD5 mittels Compare-Match toggeln, so Frequenzen erzeugen
(Lautsprecher an PinD5)
Gebe ich den Compare-Wert „händisch“ ein geht es.
Ich gebe die Inititerung mal mit an, vielleicht habe ich ja eines der
T1-Register

.def tmp= r16
INIT:  ;Stack init
  ldi tmp,LOW (RAMEND)       ;Stack
  out SPL, tmp
  ldi tmp ,HIGH (RAMEND)
  out SPH, tmp

  ;Port initieren
      ldi tmp,1<<PinD5    ;setze Bit5 in tmp
    out DDRD,tmp     ;PinD5 = Output

  ;Timer1 init
    ldi tmp, 1<<CS10|1<<CTC1    ;Prescaler 1,Bit0
    out TCCR1B,r16      ;Timer1 bei erreichen des Comparewertes auf Null
setzten,Bit4


  ldi tmp,1<<COM1A0    ;toggle PinD5 bei erreichen des Comparewertes
    out TCCR1A,tmp
;---------------------
;  Hauptprogramm
;---------------------
LADE:
  ldi tmp,high($2383)    ;schreibe Compare-Wert in Compare-RegisteAr H
  out OCR1AH,tmp
  ldi tmp,low($2383)    ;schreibe Compare-Wert in Compare-RegisteAr L
  out OCR1AL,tmp
START:
  nop
  rjmp START
;---------------------------------------------------------------------
Gebe ich den Compare-Wert aber über Tabelle und LPM ein geht es nicht.

Rest wie oben und

LADE:
  ldi  ZL,LOW(2*LISTE)  ;Registerpaar Z zeigt auf das
  ldi  ZH,HIGH(2*LISTE)
  lpm
  out OCR1AL,r0    ;lade 1Byte in CompareL
  inc ZL
  lpm
  out OCR1AH,r0    ;lade Compare_Low
  inc ZL

START:
  nop
  rjmp START

LISTE:
.dw $2383

Im Simulator geht es, aber in Natura nicht.
Sprich erster Code erzeugt Frequnez 440 Hz (bei 8Mhz), zweiter gibt
keinen Ton von sich, und im Simulator gehen beide :-(

Was mache ich falsch ?

Der Code ist auf das Problem reduziert, ich möchte später verschiedene
Compare-Werte über LPM und Programm-Memory auslesen.

Vielen Dank für Hilfe

Ein dummer(?), verzweifelter Markus

von crazy horse (Gast)


Lesenswert?

LADE:
  ldi  ZL,LOW(2*LISTE)  ;Registerpaar Z zeigt auf das
  ldi  ZH,HIGH(2*LISTE)
  lpm
  out OCR1AL,r0    ;lade 1Byte in CompareL
  inc ZL
  lpm
  out OCR1AH,r0    ;lade Compare_Low
  inc ZL

consequently, the high byte must be written first for a full 16bit
register write operation....

von Philipp Sªsse (Gast)


Lesenswert?

Stimmt im Simulator auch die Frequenz? Wenn die LISTE gerade auf einer
Seitengrenze zu liegen kommt, reicht z.B. das das inc ZL nicht, weil
sich das ZH erhöhen müßte (oder macht AVRstudio Auto-Align bei .dw --
keine Ahnung). Egal: wenn Du eine echte Liste hast, mußte Du es sowieso
richtig machen.

Andere Möglichkeit: werden im restlichen Code r0 oder Z in
Interruptroutinen benutzt, ohne vorher gerettet zu werden? Wenn der
Interrupt nicht mitsimuliert wird, entgeht Dir das Problem in der
Simulation.

von Jadeclaw D. (jadeclaw)


Lesenswert?

Ich würde sagen, das muss gehen.
Bis auf eins: Bei deinem LPM-Teil lädst du OCR1AL zuerst.
Ist es nicht so, dass bei 16Bit-Registern erst das High-Byte
geschrieben werden muss und dann das Low-Byte?
Schreib mal OCR1AH zuerst, dann OCR1AL.

Gruss
Jadeclaw.

von crazy horse (Gast)


Lesenswert?

stimmt, auch wenn das hier nicht das eigentliche Problem ist:
statt
inc zl
lieber
adiw z,1 benutzen. Sonst kann es passieren, dass man sich
"unerklärliche " Effekte einbaut, insbesondere nach
Programmänderungen, die scheinbar damit gar nichts zu tun haben.
Ich liebe Compiler, die verschonen mich von solchem Geraffel :-)

von Hannes L. (hannes)


Lesenswert?

Das Erhöhen des Z-Pointers sollte mit
 adiw zh:zl,1
erfolgen, damit der Übertrag nach ZH (Pagegrenze) berücksichtigt wird.

Dann wäre es sicher zweckmäßig, nach dem ersten LPM den Wert von r0 in
ein anderes Register zu sichern, dann das zweite Byte aus der Tabelle
zu holen und dann direkt hintereinander ocr1ah und ocr1al zu
beschreiben.

Ob der Timer im korrekten Modus ist, habe ich jetzt nicht überprüft...

...

von Markus Gäbel (Gast)


Lesenswert?

Danke,

das war der Fehler, erst das highByte schreiben...

Mann, echt peinlich, da muß man aber durch

Vielen Dank für schnelle Hilfe.

Markus

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.