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
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....
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.
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.
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 :-)
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... ...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.