Forum: Mikrocontroller und Digitale Elektronik ATTiny2313 Timer1 - Problem mit Interrupt


von -Tom-Tom- (Gast)


Lesenswert?

Hallo Leute,

ich möchte mit dem ATTiny2313 mit dem Timer1 impulse ausgeben, bloß 
irgendwie scheitert das Vorhaben bei der Initialisierung:
1
    out    TCCR1C, temp0
2
    ldi    temp0, (3<<WGM12)|(5<<CS10) ;Vorteiler auf 1024
3
    out    TCCR1B, temp0
4
    ldi    temp0, (1<<WGM11)       ;Timer1 konfigurieren (Fast-PWM)
5
    out    TCCR1A, temp0
6
7
    ldi    temp0, (1<<TOIE1)      ;Overflow-Interrupt aktivieren
8
    out    TIMSK, temp0
9
10
    ldi    temp0, 0b00100000
11
    out    ICR1H, temp0
12
    clr    temp0
13
    out    ICR1L, temp0

das ganze soll einen Interrupt auslösen. Für's erste zum kontrollieren 
wollt ich mir am Oszi Impulse ausgeben.

Solange ich die Begrenzung des Zählers über das ICR weglasse, krieg ich 
meine Impulse, aber warum nicht mit?

von Floh (Gast)


Lesenswert?

-Tom-Tom- schrieb:
> ich möchte mit dem ATTiny2313 mit dem Timer1 impulse ausgeben,
                                                        ^^^^^^
dann benutze als Vergleichsregister OCR1AH und OCR1AL.

ICR1L und ICR1H sind für die Input-Capture-Unit.

von -Tom-Tom- (Gast)


Lesenswert?

Ja genau da ist der Hacken,
an die Pins kann ich nicht ran, weil wegen dem Layout schon anders 
belegt sind.
Außerdem will ich den 16bit Timer hauptsächlich wegen der Zeit.

Das eigentliche Problem ist ja, dass der Interrupt nicht funktioniert 
...

von Floh (Gast)


Lesenswert?

-Tom-Tom- schrieb:
> Das eigentliche Problem ist ja, dass der Interrupt nicht funktioniert

Mal langsam zum mitdenken:

Du stellst in deinem Programm eine Fast-PWM ein, naja eigentlich nicht:

-Tom-Tom- schrieb:
> ldi    temp0, (3<<WGM12)|(5<<CS10) ;Vorteiler auf 1024

wenn schon, dann (1<<WGM12)|(1<<CS10).
Deaktivierst aber deine PWM-Ausgänge (wo willst du dein Signal raus 
haben).
dann stellst du einen Timeroverflow interrupt ein.
Pfuscht noch kurz im Input-Capture-Ergebnis-Register und wunderst dich, 
dass nichts geht (was überhaupt)?

Poste mal schaltplan und kompletten Code, ansonsten siehe:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer

von -Tom-Tom- (Gast)


Lesenswert?

Oke, vielleicht versuch ich mal zu erklären, auf was das ganze 
rauslaufen soll, sry dass ich das davor noch nicht hab ...

unterm Strich möchte ich eine variable Pausenzeit zwischen 0,05s und 
1,6s haben. Das ganze soll den AVR so wenig wie möglich belasten, weil 
der nebenbei ja noch ein DMX-signal auswertet und ein paar andere sachen 
macht.

Deswegen war meine Idee den Timer 1 mit seinen 16bit zu nehmen.

Und da es ja die Möglichkeit gibt mit ICR1 eine Obergrenze festzulegen, 
wie weit der zählt, wollte ich dies nutzen, dass ich variabel das ICR1 
einstelle und dann halt nach ablauf der Zeit einen Overflow-Interrupt 
auslöse.

Wollte ja den normalen Timer-Modus nehmen, aber bei dem geht ja das mit 
der Obergrenze nicht.

von Floh (Gast)


Lesenswert?

-Tom-Tom- schrieb:
> Und da es ja die Möglichkeit gibt mit ICR1 eine Obergrenze festzulegen,
> wie weit der zählt, wollte ich dies nutzen, dass ich variabel das ICR1
> einstelle und dann halt nach ablauf der Zeit einen Overflow-Interrupt

So hier sind die Verständnisfehler :-)
Die PWM-Einstellungen haust du raus, nur CTC (Clear timer on compare 
match) bleibt drin.
Mit dem Registerpaar OCR1AH und ORC1AL stellst du deine Obergrenze ein.
Dann benutzt du nicht den Timer-Overflow, sondern den 
Timer-Compare-MAtch A interrupt.

Dieser wird ausgelöst, sobald der Zählwert im Timer gleich der 
Einstellung im OCR1A ist. Die CTC-Einstellung löscht dir bei 
erfolgreichem Vergleich auch gleich den Timer-Wert, damit er wieder von 
vorne anfängt.
:-)

von spess53 (Gast)


Lesenswert?

Hi

>Und da es ja die Möglichkeit gibt mit ICR1 eine Obergrenze festzulegen,
>wie weit der zählt, wollte ich dies nutzen, dass ich variabel das ICR1
>einstelle und dann halt nach ablauf der Zeit einen Overflow-Interrupt
>auslöse.

Dann nimm den Timer-Mode 15 und den OCR1A-Interrupt. Der 
Overflow-Interrupt wird mit ICR1 als Top nicht ausgelöst, weil ein 
Overflow nicht erreicht wird.

MfG Spess

von -Tom-Tom- (Gast)


Lesenswert?

Floh schrieb:
> So hier sind die Verständnisfehler :-)
> Die PWM-Einstellungen haust du raus, nur CTC (Clear timer on compare
> match) bleibt drin.
> Mit dem Registerpaar OCR1AH und ORC1AL stellst du deine Obergrenze ein.
> Dann benutzt du nicht den Timer-Overflow, sondern den
> Timer-Compare-MAtch A interrupt.

Danke :)

aber ganz funktionierts noch nicht:
1
    clr    temp0
2
    out    TCCR1C, temp0
3
    ldi    temp0, (1<<WGM12)|(5<<CS10)
4
    out    TCCR1B, temp0
5
    clr    temp0
6
    out    TCCR1A, temp0
7
8
    ldi    temp0, (1<<OCIE1A)      ;Overflow-Interrupt aktivieren
9
    out    TIMSK, temp0
bis hierher tuts was es tun soll ... löst den Interrupt aus,
aber wenn ich dann den max-wert einstelle:
1
    ldi    temp0, 0b00010000
2
    out    OCR1AH, temp0
3
    clr    temp0
4
    out    OCR1AL, temp0
kommt nix mehr ... :( warum?

von Floh (Gast)


Lesenswert?

Poste mal dein komplettes Programm

von -Tom-Tom- (Gast)


Lesenswert?

1
.include "tn2313def.inc"
2
3
; ================================================================================================
4
; Register etc. definieren
5
; ------------------------------------------------------------------------------------------------
6
7
.def temp_ZL    = R1
8
.def temp_ZH    = R2
9
.def SREGbuf    = R3
10
.def temp0       = R16            
11
.def temp1       = R17
12
.def temp2       = R18
13
.def temp3      = R19
14
.def str_val    = R20
15
.def brightness    = R21
16
17
.def DMXstate    = R23
18
.def PWM_Count     = R24
19
20
.equ XTAL      = 16000000        ; Prozessortakt
21
.equ DMX_Daten    = 0x60          ; Startadresse DMX Array im RAM
22
.equ DMX_Kanaele  = 2           ; Zahl der DMX-Kanäle (Strobe,Helligkeit)
23
24
; ------------------------------------------------------------------------------------------------
25
; Interrupt-Vektor-Tabelle Tiny2313
26
; ------------------------------------------------------------------------------------------------
27
28
.CSEG
29
30
.org 0x0000
31
32
    rjmp    Start                      ; Reset Handler
33
    reti                ; External Interrupt Request 0
34
    reti                ; External Interrupt Request 1
35
    reti                ; Timer/Counter1 Capture Event
36
    rjmp  TMR_Overflow        ; Timer/Counter1 Compare Match A
37
    reti                ; Timer/Counter1 Overflow
38
    reti                     ; Timer/Counter0 Overflow --> PWM-Routine
39
    rjmp  DMX_Byte_Received      ; Rx Complete --> Byte empfangen
40
    reti                ; Data Register Empty
41
    reti                ; Tx Complete
42
    reti                ; Analog Comparator
43
    reti                ; Pin Change Interrupt
44
    reti                ; Timer/Counter1 Compare Match B
45
    reti                ; Timer/Counter0 Compare Match A
46
    reti                ; Timer/Counter0 Compare Match B
47
    reti                ; USI Start Condition
48
    reti                ; USI Overflow
49
    reti                ; EEPROM Ready
50
    reti                ; Watchdog Timer Overflow
51
52
; ------------------------------------------------------------------------------------------------
53
; Stackpointer, Ports setzen, etc.
54
; ------------------------------------------------------------------------------------------------
55
56
Start:
57
58
    ldi   temp0, LOW(RAMEND)      ; LOW-Byte der obersten RAM-Adresse
59
    out   SPL, temp0
60
61
    ldi   temp0, 0b00100000
62
    out   DDRD, temp0          ; PortD setzen
63
    ldi   temp0, 0b01000000
64
    out   PortD, temp0          ; Pullup an PortD
65
66
      clr    temp0
67
      out    TCCR1C, temp0        ;Timer 1 konfigurieren
68
      ldi    temp0, (1<<WGM12)|(5<<CS10)  ;Vorteiler 1024; Mode 4
69
      out    TCCR1B, temp0
70
      clr    temp0
71
      out    TCCR1A, temp0
72
73
       ldi    temp0, (1<<OCIE1A)          ;Overflow-Interrupt aktivieren
74
      out    TIMSK, temp0
75
76
77
      ldi    temp0, 0b00010000      ;irg einen Wert in OCR1 schreiben
78
      out    OCR1AH, temp0
79
      clr    temp0
80
      out    OCR1AL, temp0
81
82
    rcall  DMX_Init          ; DMX initialisieren
83
84
    sei                  ; Interrupts aktivieren
85
86
; ================================================================================================
87
; Hauptroutine, DMX-Daten empfangen und in die Kanal-Register schieben
88
; ------------------------------------------------------------------------------------------------
89
90
main:
91
    ldi   ZH, high(DMX_Daten)
92
    ldi    ZL, low(DMX_Daten)
93
    ld    str_val, Z+
94
    ld    brightness, Z+
95
              
96
97
98
    rjmp  main
99
100
TMR_Overflow:
101
102
    sbi    PORTD,5
103
    
104
    
105
    nop
106
    nop
107
    nop
108
    nop
109
    nop
110
    nop
111
    nop
112
    nop
113
    nop
114
    nop
115
    nop
116
    nop
117
    nop
118
    nop
119
    nop
120
    nop
121
    nop
122
    nop
123
    nop
124
    nop
125
    
126
127
    cbi    PORTD,5
128
129
    reti
130
131
; ================================================================================================
132
; DMX Initialisieren
133
; ------------------------------------------------------------------------------------------------
134
135
DMX_Init:
136
137
      ldi   temp0, ((XTAL/4000000)-1)   ; Usart auf 250 kbaud setzen
138
      out   UBRRL, temp0
139
      clr   temp0
140
      out   UBRRH, temp0
141
142
      ldi   temp0, (3<<UCSZ0)|(1<<USBS) ; 8 Datenbits, 2 Stoppbits
143
      out   UCSRC, temp0      
144
    sbi   UCSRB, RXEN          ; Receiver enable
145
    sbi   UCSRB, RXCIE        ; RX Complete Int. enable
146
147
    ldi   temp0, 0b00000000      ; PortB auf Eingang (DIP-Schalter)
148
    out   DDRB, temp0
149
    ldi   temp0, 0b11111111
150
    out   PortB, temp0          ; Pullup an PortB
151
152
    ldi    ZH, high(DMX_Daten)      ; alle Kanäle im RAM auf 0 setzen
153
    ldi    ZL, low(DMX_Daten)
154
    clr    temp0
155
    ldi   DMXstate, DMX_Kanaele
156
157
write_RxD:  
158
159
    st     Z+,temp0
160
    dec    DMXstate
161
    brne  write_RxD
162
163
    ret
164
165
166
; ================================================================================================
167
; ISR für DMX-Empfang
168
; ------------------------------------------------------------------------------------------------
169
170
DMX_Byte_Received:
171
    in      SREGbuf, SREG
172
    push  temp1
173
    push  temp0    
174
    push  ZH
175
    push   ZL
176
    mov    ZL, temp_ZL
177
    mov    ZH, temp_ZH
178
179
    in    temp0,UCSRA          ; Status und Daten holen
180
    in    temp1,UDR
181
182
    sbrc  temp0,FE          ; Frame-Error: neuer Durchgang
183
    rjmp  dmx_frame_error  
184
    
185
    cpi    DMXstate, 1           ; Startbyte testen
186
    breq  dmx_startbyte
187
188
      cpi   DMXstate, 2           ; Startadresse abfragen
189
    breq    dmx_startadr
190
      
191
     cpi   DMXstate, 3  
192
      brsh  dmx_handle_byte
193
194
dmx_finish:
195
    mov    temp_ZH, ZH
196
    mov    temp_ZL, ZL
197
    pop    ZL
198
    pop    ZH
199
    pop    temp0
200
    pop    temp1
201
    out     SREG, SREGbuf  
202
    reti      
203
204
dmx_startbyte:
205
    tst   temp1             ; Byze = 0 --> Startbyte, sonst Fehler
206
    brne   dmx_err
207
    inc    DMXstate
208
209
    in     ZL, PinB           ; Startadresse vom DIP holen (PortB)
210
    com     ZL
211
    clr    ZH
212
    sbis  PinD, 6            ; 9. Bit von PortD1 holen
213
    inc    ZH
214
215
    rjmp  dmx_finish
216
217
dmx_startadr:
218
    sbiw  ZH:ZL, 1          ; Adresse runterzählen
219
    brne  dmx_finish          ; Startadresse noch nicht erreicht
220
221
    ldi   ZH, high(DMX_Daten)
222
    ldi    ZL, low(DMX_Daten)
223
    inc    DMXstate
224
    
225
dmx_handle_byte:  
226
    st    Z+, temp1
227
228
    cpi    ZL, low(DMX_Daten+DMX_Kanaele)
229
    brne  dmx_finish
230
    cpi    ZH, high(DMX_Daten+DMX_Kanaele)
231
    brne  dmx_finish  
232
    clr    DMXstate
233
    rjmp  dmx_finish
234
  
235
dmx_frame_error:
236
    ldi   DMXstate, 1          ; Frame-Error --> neuer Durchlauf
237
    cbi    UCSRA,FE          ; Flag löschen, falls längere Pause
238
    rjmp  dmx_finish
239
240
dmx_err:
241
     clr   DMXstate          ; auf nächsten FE warten      
242
    rjmp  dmx_finish
243
244
; ================================================================================================

von -Tom-Tom- (Gast)


Lesenswert?

Die Empfangsroutine ist nicht von mir, aber funktioniert, hab ich schon 
bei mehreren Programmen verwendet.

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
Noch kein Account? Hier anmelden.