Forum: Mikrocontroller und Digitale Elektronik ATiny25, Timer0 PWM + Timer1 Interrupt


von Alexander G. (illness)


Angehängte Dateien:

Lesenswert?

Hallo, ich hab hier leichte Probleme mit einen kleinen ATiny25. Ich habe 
FastPwm auf Timer 0 laufen was auch funktioniert. Nun wollte ich mit 
Timer 1 einen Interrupt machen aber irgendwie beißt sich da was.

//TCCR1 = 0x02;

Wenn dies ausgeklammert ist funktioniert alles. Sobalt ich den Timer 
starte ist vorbei. Als wenn der Timer permanent einen Interrupt auslöst.

Was auch komisch ist, wenn ich "TCCR1A" oder "TCCR1B" Tippe meint er das 
es diese Register nicht gibt. Laut Datenblatt hab ich die aber ?!

Hab alles unwichtige raus genommen. Komplettes Programm im Anhang.
1
#include <inttypes.h>
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <avr/pgmspace.h>
5
#include <avr/sleep.h>
6
#define  F_CPU 1000000UL 
7
...
8
volatile int count1 =0;
9
volatile int count2 =0;
10
...
11
ISR(TIMER1_OVF_vect)
12
{
13
    TCNT1 = 6; 
14
    count1++;  
15
  if(count1>1000)
16
  {
17
    count1=0;
18
    count2++;
19
  }
20
}
21
22
...
23
24
25
// 8-Bit PWM with 32 different settings
26
.....
27
 
28
void init_pwm (void)
29
{    
30
  // Timer 0 PWM Init
31
32
  TCCR0A = (1 << WGM00)
33
       | (1 << WGM01)
34
     | (0 << COM0A1)
35
     | (0 << COM0B1);
36
  TCCR0B = (0 << WGM02)
37
       | (1 << CS00)
38
     | (1 << CS01)
39
     | (0 << CS02);
40
41
  // OC0A PWM Port
42
43
  DDRB   |= (1 << PB0);
44
  OCR0A = 0;
45
46
  // OC0B PWM Port
47
  
48
  DDRB   |= (1 << PB1);
49
  OCR0B = 0;  
50
}
51
52
void init(void)
53
{
54
    PORTB = (0<<Led1);
55
  PORTB = (0<<Led2);
56
57
58
  //TCCR1 = 0x02;          // Timerstart
59
    TCNT1 = 6;            // Startwert nachladen, 0xFA
60
                      // 250* 64us=16ms bis Overflow
61
    SREG = (1<<7);           // Allgemeine Interruptfreigabe;
62
    TIMSK=(1<<TOIE1);       // Freigabe Timer1 Iterrupt  
63
  
64
}   
65
66
int main(void)
67
{
68
  init();
69
  init_pwm();
70
  
71
    while(1)
72
  { 
73
74
    if(count2 >= 15)     
75
    {                
76
            count2 = 0;
77
      pwm_8_32(step_time/8,10); // feld 1 aus
78
      TCCR0A = (1 << WGM00) | (1 << WGM01) | (0 << COM0A1);
79
    }
80
81
   ......
82
83
return 0;
84
   
85
}

von Michael L. (eagle87)


Lesenswert?

Alexander G. schrieb:
> Hallo, ich hab hier leichte Probleme mit einen kleinen ATiny25. Ich habe
> FastPwm auf Timer 0 laufen was auch funktioniert. Nun wollte ich mit
> Timer 1 einen Interrupt machen aber irgendwie beißt sich da was.
>
> //TCCR1 = 0x02;
>
> Wenn dies ausgeklammert ist funktioniert alles. Sobalt ich den Timer
> starte ist vorbei. Als wenn der Timer permanent einen Interrupt auslöst.
Sicher bin ich mir nicht, aber eine mögliche Erklärung wäre das fehlende
1
#include <avr/interrupt.h>
Wenn du den Timer startest und der Overflow Interrupt eintritt springt 
der Program Counter zu der ISR Einsprungadresse. Da der Compiler deine 
ISR aber nicht kennt, gibt es keinen Rücksprung zum eigentlichen 
Programm. Wenn du den Timer nicht startest wird auch kein Interrupt 
ausgelöst und das Programm läuft normal durch.

> Was auch komisch ist, wenn ich "TCCR1A" oder "TCCR1B" Tippe meint er das
> es diese Register nicht gibt. Laut Datenblatt hab ich die aber ?!
Also in dem Datenblatt das ich grad vor mir hab gibt es die Register 
nicht. Beim Timer 0 gibt es die Unterscheidung zwischen TCCR0A und 
TCCR0B, aber Timer 1 besitzt nur TCCR1

Außerdem ist mir aufgefallen, dass du immer wieder ne 6 in das 
TCNT1-Register schreibst. Schau dir mal den CTC-Mode an. Damit sollte 
sich dies erübrigen.

Gruß
Michael

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Alexander G. schrieb:
> SREG = (1<<7);           // Allgemeine Interruptfreigabe;

Schreib da ruhig
1
   sei();   // globale IRQ freigeben
2
// und 
3
   cli();   // globale IRQ sperren
Im Moment wird das evtl. funktionieren, aber auf einem anderen MC könnte 
das unerwünschte Effekte haben wenn z.B. die Position des Flags sich 
ändert.

Alexander G. schrieb:
> //TCCR1 = 0x02;          // Timerstart
>     TCNT1 = 6;            // Startwert nachladen, 0xFA

Bist du sicher, das in den Steuerregistern von Timer 1 alles schon 
richtig steht? Schreibe lieber explizit rein, was du für Modi einstellen 
willst, damit nach einem Reset oder wiederholten Aufruf von init() alles 
korrekt gesetzt wird.

von Alexander G. (illness)


Lesenswert?

-___-

#include <avr/interrupt.h>

Jetzt geht es...ich würd glatt sagen typischer fall von "man sieht den 
Wald vor lauter Bäumen nicht" ..

Danke!

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.