Re: Kummer mit CTC (mode 4)
Oha ...
- Die push & pop Dinger müssen sein. Ohne die bringst du dein Programm total durcheinnder.
- heisst es: in r20, SREG und nicht ldi r20, SREG
- Hast du bei den Werten für das OCR1A Register einen Denkfehler drin. Da du bei einem Überlauf des Timers einen Pin togglest, musst du schon mit der doppelten Frequenz rechnen. daher wären 33 kHz = 14 für das OCR1A Register.
- In den verfügbaren 15 Takten kann deine ISR aber niemals abgearbeitet werden.
Lösungsmöglichkeiten:
- den Takt erhöhen. Damit ergibt sich natürlich auch ein anderer Wert für das OCR1A
- oder dem µC das togglen komplett überlassen. d.H. COM1A0 im TCCR1A setzen und die ISR komlett wegfallen lassen (siehe Datenblatt Seite 97)
Im übrigen haste hier schonmal einen sortierten Code für die 2te Version.
Code:
.NOLIST
.INCLUDE <m8def.inc>
.LIST
; MCU Takt für diverse Berechnungen festlegen
.equ tosc = 1000000
; Ausgabefreq festlegen
.equ fout = 33000
; Timer 1 Ladewert
.equ ladewert = (tosc / (2 * fout)) - 1
.CSEG
.org 0
; Interupt Vektoren
rjmp init ; Reset Handler
reti ; IRQ0 Handler
reti ; IRQ1 Handler
reti ; Timer2 Compare Handler
reti ; Timer2 Overflow Handler
reti ; Timer1 Capture Handler
reti ; Timer1 CompareA Handler
reti ; Timer1 CompareB Handler
reti ; Timer1 Overflow Handler
reti ; Timer0 Overflow Handler
reti ; SPI Transfer Complete Handler
reti ; USART RX Complete Handler
reti ; UDR Empty Handler
reti ; USART TX Complete Handler
reti ; ADC Conversion Complete Handler
reti ; EEPROM Ready Handler
reti ; Analog Comparator Handler
reti ; Two-wire Serial Interface Handler
reti ; Store Program Memory Ready Handler
init:
ldi r16, high(RAMEND); Stackpointer initialisieren
out SPH, R16
ldi r16, low(RAMEND)
out SPL, R16
ldi r24, 255
out DDRB, r24 ; Port B als Ausgang
out DDRD, r24 ; Port D auch
out PORTC, r24 ; Pullups von Port C aktivieren
; (-> damit hat dieser einen definierten Pegel
; und nicht osziliert sinnfrei rum)
ldi r17, (1<<COM1A0) ; Timer 1 konfigurieren (Mode 4 -> CTC)
ldi r16, (1<<WGM12)|(1<<CS10)
out TCCR1A, r17
out TCCR1B, r16
ldi r16, high(ladewert)
out OCR1AH,r16
ldi r16, low(ladewert)
out OCR1AL,r16
; in r16, TIMSK ; Diese auskommentierten Zeilen sind hier unnötig,
; ori r16, (1<<OCIE1A) ; ich habe sie nur drinne gelasen um zu zeigen,
; out TIMSK, r16 ; wie ich es machen würde
sei ; Interrupts aktivieren
loop: ; hauptschleife
ldi r24, 32
out PORTD, r24
ldi r17, 0x09 ; delay loop, 1Hz
WGLOOP0:
ldi r18, 0xBC
WGLOOP1:
ldi r19, 0xC4
WGLOOP2:
dec r19
brne WGLOOP2
dec r18
brne WGLOOP1
dec r17
brne WGLOOP0
nop
ldi r24, 192
out portd, r24 ; PD5+6 auf HIGH
ldi r17, 0x09 ; delay loop, 1Hz
WGLOOP3:
ldi r18, 0xBC
WGLOOP4:
ldi r19, 0xC4
WGLOOP5:
dec r19
brne WGLOOP5
dec r18
brne WGLOOP4
dec r17
brne WGLOOP3
nop
rjmp loop
Ich hoffe dir damit geholfen zu haben.
Grüße,
da Hanni.