Vielen Dank Search, es bliiiiinkt!
Ohne dich hätte ich das glaube ich nicht hinbekommen. Ich hoffe ich brauche das dann auch in meinen Projekten.
Zum einen lag es an den TIMSK Flags, die waren um eine Bitstelle verschoben.
Zum anderen an der zuvor von dir erwähnten Reihenfolge der Faktoren, spricht den Werten in den Vergleichsregistern (OCR1A und OCR1B).
Also einfach die 15625 ins OCR1B schreiben und die 31250 in OCR1A. Damit läuft der Timer zwei Sekunden hoch. "Oben" schaltet er über den Compare1A Interrupt die LEDs ein und auf dem Weg nach oben über den Compare1B Interrupt die LEDs aus.
Übrigens um genau zwei Sekunden zu erreichen sollte der Wert 31249 statt 31250, da der Timer noch einen Timertick braucht um auf Null zu kommen. Spiegelt sich auch im Datenblatt in der Formel zur Frequenzberechnung mit der -1 wieder. Eventuell auch die 15625 um eins vermindern?
Die ausgerechnete Zeit muss nicht ganz genau sein. Ich wollte einfach nur im ca. 1 Sekundentakt blinkende LEDs haben.
Falls also jemand mal einen funktionierenden Code braucht mit blinkenden LEDs (ca. 1s), hier ist er.
Code:
; Programm : This programm is written and tested on an Atmega32. It causes the LEDs on PORTC to blink on a frequency of 1 second.
; To do so it uses the timer 1 (16-Bit) on CTC mode with a prescaler of 1024. To reach the frequency of 1 second
; the compare register B has the value 15625 and register A the value 31250. The demension of these values result in
; the system clock of 16MHz.
; 1024 * 15625 = 16000000
; 1024 * 31250 = 32000000
; definitions
.def temp = R16
.def temp_1 = R17
; interrupt vectors
.org 0x000 ; reset handler
rjmp main
.org 0x00E ; Timer1 CompareA Handler
rjmp interrupt_compare_A
.org 0x010 ; Timer1 CompareB Handler
rjmp interrupt_compare_B
;Mnemonic target, source
main: ; main programm
;;; PORTC set as output
LDI temp, 0xFF
OUT DDRC, temp ; DDRC defines if PORTC is an output (1) or input (0)
;;; Timer Counter in CTC Mode -> self defined value; if timer reaches value, interrupt accours
;; Control Register A
LDI temp, 0x00 ; normal & Clear Timer on Compare Match (CTC) Mode
OUT TCCR1A, temp ; Control Register A
;; Control Register B
LDI temp, 0b00001101 ; Timer prescaler of 1024 & Clear Timer on Compare Match (CTC) Mode -> self adjust overflow value
OUT TCCR1B, temp ; Control Register B
;; Output Compare Register 1 A for CTC
; write value 31250 -> 31250 * 1024 = 32MHz -> 2 seconds count
LDI temp, 0b01111010
OUT OCR1AH, temp ; first write high register then low
LDI temp, 0b00010010
OUT OCR1AL, temp
;; Output Compare Register 1 B for CTC
; write value 15625 -> 15625 * 1024 = 16MHz -> 1 second count
LDI temp, 0b00111101
OUT OCR1BH, temp ; first write high register then low
LDI temp, 0b00001001
OUT OCR1BL, temp
;;; Interrupt handling
;; for timer 1 Interrupt Mask Register
LDI temp, 0b000011000 ; OCIE1A and OCIE1B -> Output Compare A and B Match Interrupt Enable
OUT TIMSK, temp
;; global interrupt enable
sei
loop:
rjmp loop ; endless loop
;-------------------------------------------------------------------------------------------
; interrupts
;-------------------------------------------------------------------------------------------
interrupt_compare_A: ; interrupt routine for compare register 1 B
IN temp_1, SREG ; save status register
LDI temp, 0x00
OUT PORTC, temp ; LEDs on
OUT SREG, temp_1 ; restore status register
reti ; finishes interrupt and enables global interrupt
interrupt_compare_B: ; interrupt routine for compare register 1 A
IN temp_1, SREG ; save status register
LDI temp, 0xFF
OUT PORTC, temp ; LEDs off
OUT SREG, temp_1 ; restore status register
reti ; finishes interrupt and enables global interrupt
;-------------------------------------------------------------------------------------------
;-------------------------------------------------------------------------------------------
Lesezeichen