LotharK
28.10.2007, 17:19
Hallo,
ich versuche mit dem AtTiny2323 einen Sekundentakt zu erzeugen. Leider gelingt mir das in keiner Weise.
Ich dachte, wenn ich einen 4 MHz Quarz verwende und den Vorteiler TCCR0 auf 256 stelle und den Hardwarezähler TCNT0 auf 125 stelle, brauchte ich nur noch durch 125 zu teilen und schon habe ich den Impuls.
Könnte sich mal jemand deen simplen Code betrachten und im Studio laufen lassen?
; ************************************************** ****
.NOLIST
.INCLUDE "tn2313def.inc"
.LIST
;
; Definition der Register
;
.DEF mp = R16
.DEF ri = R1
.DEF rT = R17
.DEF rVT = R18
.DEF rTCNT0 = R19
; Beginn des Codes, Init I/O-Ports
rjmp main ; Springe zum Anfang
; Die Interrupt-Vektoren zu je 1 Byte:
reti ; Int0-Interrupt
reti ; Int1-Interrupt
reti ; TC1-Capture
reti ; TC1-Compare A
reti ; TC1-Overvlow
rjmp iTakt; TC0-Overvlow
reti ; UART0 RX
reti ; UART0 UDRE
reti ; UART Tx
reti ; Analog COMP
reti ; PCINT
reti ; Timer/Counter1 Compare Match B
reti ; Timer/Counter0 Compare Match A
reti ; Timer/Counter0 Compare Match B
reti ; USI Start
reti ; USI Overflow
reti ; EEReady
reti ; WDT Overflow
; Interrupt-Service-Routine für den Zähler
iTakt:
in ri,SREG ; Rette den Inhalt des Flag-Registers
push ri
OUT TCNT0, rTCNT0 ; Hardwarezähler so stellen, dass bei 125 Impulsen der Überlauf erfolgt
inc rVT ; im 1 Byte erhoehen
cpi rVT,124 ; Wenn 125 erreicht, ist 1 Sekunde um: (4000000 / 256 / 125/ 125 = 1)
BRNE jVT
INC mp
OUT PORTB, mp ; Zum Test an LEDs ausgeben
LDI rVT,0
jVT:
pop ri
out SREG,ri ; Stelle Flag-Register wieder her
reti ; Kehre vom Interrupt zurück
; Hauptprogramm beginnt hier
main:
ldi mp,LOW(RAMEND) ;Initiate Stackpointer
out SPL,mp ; wegen Interrupts und Unterprogr.
ldi mp,0x04 ;Initiate Timer/Counter 0 Vorteiler auf 265 da 4000000 / 256 /125 / 125 = 1 ist
out TCCR0,mp ; an Timer 0 Control Register
LDI mp,0x00 ; PORTD 2 und 3 als Ausgang (INT0 und INT1)
out DDRD,mp ; in Datenrichtungsregister
LDI rTCNT0, 125
OUT TCNT0, rTCNT0 ; Hardwarezähler so stellen, dass bei 125 Impulsen der Überlauf erfolgt
; Interrupts bei Timer 0 einschalten
LDI mp,2
out TIMSK,mp ; in Timer Interupt Mask Register um Zähler zu aktivieren
LDI mp, 0x00
OUT PortB, mp
LDI mp,0xFF
OUT DDRB,mp
sei ; Gib Interrupts im Status-Register frei
loop:
rjmp loop
;************************************************* **********
Wenn ich einen Breakpoint setze und mit Stop-Watch stoppe, komme ich auf 1039,61 ms. Wie kommt das? Ich verstehe das nicht.
Wenn ich das Programm auf dem STK500 laufen lasse, ändern sich die LEDs alle 9 Sekunden. Die Fusebits sollten korrekt sein. Wenn ich den Quarz entferne, kann ich nicht mehr auf den AtTiny schreiben. Da sollte der Quarz doch aktiv sein - oder?
MfG Lothar
ich versuche mit dem AtTiny2323 einen Sekundentakt zu erzeugen. Leider gelingt mir das in keiner Weise.
Ich dachte, wenn ich einen 4 MHz Quarz verwende und den Vorteiler TCCR0 auf 256 stelle und den Hardwarezähler TCNT0 auf 125 stelle, brauchte ich nur noch durch 125 zu teilen und schon habe ich den Impuls.
Könnte sich mal jemand deen simplen Code betrachten und im Studio laufen lassen?
; ************************************************** ****
.NOLIST
.INCLUDE "tn2313def.inc"
.LIST
;
; Definition der Register
;
.DEF mp = R16
.DEF ri = R1
.DEF rT = R17
.DEF rVT = R18
.DEF rTCNT0 = R19
; Beginn des Codes, Init I/O-Ports
rjmp main ; Springe zum Anfang
; Die Interrupt-Vektoren zu je 1 Byte:
reti ; Int0-Interrupt
reti ; Int1-Interrupt
reti ; TC1-Capture
reti ; TC1-Compare A
reti ; TC1-Overvlow
rjmp iTakt; TC0-Overvlow
reti ; UART0 RX
reti ; UART0 UDRE
reti ; UART Tx
reti ; Analog COMP
reti ; PCINT
reti ; Timer/Counter1 Compare Match B
reti ; Timer/Counter0 Compare Match A
reti ; Timer/Counter0 Compare Match B
reti ; USI Start
reti ; USI Overflow
reti ; EEReady
reti ; WDT Overflow
; Interrupt-Service-Routine für den Zähler
iTakt:
in ri,SREG ; Rette den Inhalt des Flag-Registers
push ri
OUT TCNT0, rTCNT0 ; Hardwarezähler so stellen, dass bei 125 Impulsen der Überlauf erfolgt
inc rVT ; im 1 Byte erhoehen
cpi rVT,124 ; Wenn 125 erreicht, ist 1 Sekunde um: (4000000 / 256 / 125/ 125 = 1)
BRNE jVT
INC mp
OUT PORTB, mp ; Zum Test an LEDs ausgeben
LDI rVT,0
jVT:
pop ri
out SREG,ri ; Stelle Flag-Register wieder her
reti ; Kehre vom Interrupt zurück
; Hauptprogramm beginnt hier
main:
ldi mp,LOW(RAMEND) ;Initiate Stackpointer
out SPL,mp ; wegen Interrupts und Unterprogr.
ldi mp,0x04 ;Initiate Timer/Counter 0 Vorteiler auf 265 da 4000000 / 256 /125 / 125 = 1 ist
out TCCR0,mp ; an Timer 0 Control Register
LDI mp,0x00 ; PORTD 2 und 3 als Ausgang (INT0 und INT1)
out DDRD,mp ; in Datenrichtungsregister
LDI rTCNT0, 125
OUT TCNT0, rTCNT0 ; Hardwarezähler so stellen, dass bei 125 Impulsen der Überlauf erfolgt
; Interrupts bei Timer 0 einschalten
LDI mp,2
out TIMSK,mp ; in Timer Interupt Mask Register um Zähler zu aktivieren
LDI mp, 0x00
OUT PortB, mp
LDI mp,0xFF
OUT DDRB,mp
sei ; Gib Interrupts im Status-Register frei
loop:
rjmp loop
;************************************************* **********
Wenn ich einen Breakpoint setze und mit Stop-Watch stoppe, komme ich auf 1039,61 ms. Wie kommt das? Ich verstehe das nicht.
Wenn ich das Programm auf dem STK500 laufen lasse, ändern sich die LEDs alle 9 Sekunden. Die Fusebits sollten korrekt sein. Wenn ich den Quarz entferne, kann ich nicht mehr auf den AtTiny schreiben. Da sollte der Quarz doch aktiv sein - oder?
MfG Lothar