www.mikrocontroller.net

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


Autor: Markus Gäbel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Philipp Sªsse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jadeclaw Dinosaur (jadeclaw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht 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...

...

Autor: Markus Gäbel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.