Forum: Mikrocontroller und Digitale Elektronik ATtiny2313 4xPWM + Timer Interrupt Problem


von ben (Gast)


Lesenswert?

Hallo,

Bin jetzt von Bascom auf AVR GCC umgestiegen und wollte mit einem 
ATTiny2313  4 LEDs per PWM Dimmen. Die Dimmung funktioniert soweit 
super, allerdings wollte ich noch eine Zeitmessung per Timerinterrupt 
realisieren. Das muss nicht genau sein. Zum Stromsparen sollte sich der 
Controller nach ca. 1 - 2h in den Sleep bzw. Standby Modus versetzten. 
Allerdings ist mir, als Anfänger, etwas schleierhaft wie ich einen 
Timerinterrupt nach ca. 1ms Programmieren kann da beide interne Timer 
für die 4 PWM Kanäle benutzt werden.

Hat einer von euch eine Idee wie man das Realisieren kann?

Hier mein bisheriger Test-Programmcode:



1
//Define
2
#define F_CPU 1000000UL      //Taktfrequenz des uC für die Delay festlegen
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
7
/* Globale Variablen */
8
volatile unsigned char interbw = 0;
9
10
11
//Long Delay festlegen
12
void long_delay(uint16_t ms)
13
{
14
    for(; ms>0; ms--) _delay_ms(1);
15
}
16
17
18
19
//Hauptprogramm
20
int main (void) {
21
cli();          //interrupts Deaktivieren
22
23
//Config
24
//////INT/////
25
TIMSK  |= ( 1 << OCIE1B);
26
27
28
29
DDRD |= (1 << PD5);    // Ausgangspin für PWM
30
DDRB |= (1 << PB4);    // Ausgangspin für PWM
31
DDRB |= (1 << PB3);    // Ausgangspin für PWM
32
DDRB |= (1 << PB2);    // Ausgangspin für PWM
33
34
TCCR0A = 0b10100001 ;   //FastPWM
35
TCCR0B = 0b00000001;  //Kein Prescaler
36
TCCR1A = 0b10100001 ;   //FastPWM
37
TCCR1B = 0b00000001;  //Kein Prescaler
38
39
40
/* DEKLARATIONEN */
41
char i = 0;
42
unsigned char pwm = 1;
43
unsigned int zeit = 0;
44
//unsigned char 
45
46
/*Bereitschaft anzeigen
47
 Initialisierung*/
48
OCR0B=150;
49
OCR0A=150;
50
OCR1B=150;
51
OCR1A=150;
52
long_delay(500);
53
54
//Hauptschleife
55
56
while(1){
57
sei();          //interrupts Aktivieren
58
59
// PWM-Werte zum Test erzeugen -> Fader
60
if (pwm>=25){
61
  i=1;
62
  }
63
64
if (pwm <=15){
65
  i=0;
66
  }
67
68
if (i==1){
69
  pwm--;
70
  }
71
else {
72
  pwm++;
73
  }
74
75
//PWM-Wert an jeweiligen Port zuweisen
76
OCR0B = pwm;
77
OCR0A = pwm;
78
OCR1B = pwm;
79
OCR1A = pwm;
80
81
long_delay(10);        //10ms Warten
82
83
}
84
                          
85
   return 0;                
86
}
87
/*
88
============== I S R =================
89
*/
90
91
ISR(TIMER1_COMPB_vect) 
92
{
93
cli();
94
  //Diese ISR funktioniert nicht
95
sei();  
96
}

Vielen Dank & Grüße
Ben

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Prüfe, ob Bit WGM00 allein bei Timer0 den gewünschten PWM Modus 
einschaltet.  Prüfe, ob Bit WGM10 allein bei Timer1 den gewünschten PWM 
Modus einschaltet.
Deine Bit-Auswahl kann ich keinem FAST-PWM Modus zuordnen.

Warum willst du dir per TIMSK einen Interrupt geben lassen, wenn die ISR 
eh leer ist (cli/sei gehören dort nicht hin)? Die PWM kann ohne 
Interrupt-ISR laufen.

von ben (Gast)


Lesenswert?

Hallo Stefan,

danke für deine Antwort. Die ISR ist momentan leer, habe gerade getestet 
ob sie funktioniert (LED einschalten in der ISR). Das war nicht der 
Fall. Die CLI() / SEI() Funktion habe ich auch mal getestet um 
auszuschließen das der Interrupt die ISR unterbbricht und somit einen 
Stack-Überlauf verursacht. Die PWM an sich funktioniert hervorragend. 
Die Bitsetztung werde ich gleich morgen nocheinmal prüfen.

Gruß Ben

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.