Forum: Mikrocontroller und Digitale Elektronik ATmega32 fast PWM 38kHz berechnung


von Johannes S. (gnubert)


Lesenswert?

Hallo,
ich möchte gerne ein 38kHz Signal an meinem AtMega32 augeben um eine IR 
Fernbedienung nachzubilden.

Habe im Datenblatt gelesen für eine Fast PWM müssen folgende 
Einstellungen vorgenommen werden
1
int main (void) {
2
3
//fast PWM
4
DDRD |= (1<<PD5); // Ausgang schalten
5
TCCR1A |= (1 << WGM12) | (1 << WGM11); 
6
TCCR1B |= (1 << WGM13) | (1 << CS10);
7
8
//Formel zur Berechnung von TOP als ICR1
9
10
ICR1 = ((16000000 / 38000) - 1); //AVR läuft mit 16MHz
11
OCR1A = ((16000000 / 38000) - 1)/4 ; // Tastverhältnis von 1:4

Am e*scope kommt auch alles schön und gut an, leider Stimmt die 
Periodenlänge nicht.

eigentlich müsste ich eine Periodendauer von 0,0263ms bekommen.

Berechne ich es wie oben, wie im Datenblatt, bekomme ich aber die 
doppelte Periode.


Klar kann ich einfach einen Teiler 2 einbauen - aber wie kommt das zu 
stande? Was habe ich übersehen?

Bin über jeden Hinweis dankbar :)

btw: wieso werden LaTeX Formel so groß dargestellt?

von spess53 (Gast)


Lesenswert?

Hi

Wieso Fast PWM und nicht CTC?

MfG Spess

von Stefan E. (sternst)


Lesenswert?

Johannes Xy schrieb:
> Habe im Datenblatt gelesen für eine Fast PWM müssen folgende
> Einstellungen vorgenommen werden

Dann hast du falsch gelesen. Schau nochmal nach.

von Johannes S. (gnubert)


Lesenswert?

>Dann hast du falsch gelesen. Schau nochmal nach.
ahhh (1 << WGM12) gehört zu TCCR1B ;)

>Wieso Fast PWM und nicht CTC?

hmm, was habe ich für ein Vorteil durch CTC? Macht das hier mehr Sinn?

von Johannes S. (gnubert)


Lesenswert?

Also,ich bin schon einmal einen großen Schritt weiter.

Auf dem Oszi, sieht das PWM Signal sehr gut aus. Timings passen auch 
sehr gut. Hab leider gerade kein Bild sind aber ziemlich exakt 27us bei 
38khz.


Problem ist, dass die IR Diode (unter dem Blick einer Handy Kamera) 
nicht blinkt. Normale Diode ist zu erkennen.
IR Diode ist an auch zu erkennen, wenn man sie an einen Konstanten VCC 
Pin anschließt. -> also nicht defekt.

Schaltung:
                 VCC
                  |
                  D1
                  |
                  R2
                  |
                  |
                 /
                /
               |
               |
OC1A----R1-----| T1 = BC337
               |
               |
                \
                 \
                  G

D1 = LD274
R1=4,7k
R2=27

Über der Diode fallen genau die 1,3V ab die im Datenblatt angegeben 
sind. Ucesat = 0,7V.

Kann es sein, das die Verstärkung noch zu gering ausgelegt ist?
Arbeite mit einem Tastverhältnis von 1:2, sollte doch schon ausreichend 
sein, oder?

Zum Code:
Man könnte den IR Code natürlich über ein Array auslesen um ihn etwas 
schlanker zu machen, aber das ist erstmal egal.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#include <util/delay.h>
5
6
int main (void) {
7
8
9
//fast PWM
10
DDRD |= (1<<PD5);
11
TCCR1A |= (1 << WGM11);
12
TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10);
13
14
ICR1 = ((16000000 / 38000) - 1); //TOP
15
OCR1A = ((16000000 / 38000) - 1)/2;
16
17
18
19
/*      Start-Bit   4500µs Puls, 4500µs Pause
20
      0-Bit     550µs Puls, 450µs Pause
21
      1-Bit     550µs Puls, 1450µs Pause
22
      Stop-Bit   550µs Puls 
23
*/
24
25
while(1)
26
{
27
    TCCR1A |= (1 << COM1A1);    //Start
28
      _delay_us(4500);        
29
    TCCR1A &=~(1 << COM1A1);    
30
    _delay_us(4500);      
31
    
32
    TCCR1A |= (1 << COM1A1);    //1
33
      _delay_us(550);          
34
    TCCR1A &=~(1 << COM1A1);    
35
    _delay_us(1450);        
36
    
37
    TCCR1A |= (1 << COM1A1);    //0
38
      _delay_us(550);          
39
    TCCR1A &=~(1 << COM1A1);    
40
    _delay_us(450);          
41
    TCCR1A |= (1 << COM1A1);    //0
42
      _delay_us(550);          
43
    TCCR1A &=~(1 << COM1A1);    
44
    _delay_us(450);          
45
46
    
47
    TCCR1A |= (1 << COM1A1);    //1
48
      _delay_us(550);          
49
    TCCR1A &=~(1 << COM1A1);    
50
    _delay_us(1450);      
51
    TCCR1A |= (1 << COM1A1);    //1
52
      _delay_us(550);          
53
    TCCR1A &=~(1 << COM1A1);    
54
    _delay_us(1450);        
55
    
56
57
   ....
58
   USW
59
   ...
60
61
62
    TCCR1A |= (1 << COM1A1);    //1
63
      _delay_us(550);          
64
    TCCR1A &=~(1 << COM1A1);    
65
    _delay_us(1450);        
66
    
67
    TCCR1A |= (1 << COM1A1);    //0
68
      _delay_us(550);          
69
    TCCR1A &=~(1 << COM1A1);    
70
    _delay_us(450);          
71
    
72
    TCCR1A |= (1 << COM1A1);    //Stop
73
      _delay_us(550);      
74
    TCCR1A &=~(1 << COM1A1);    
75
    _delay_ms(45);            
76
77
78
  
79
}
80
81
}

von Johannes S. (gnubert)


Lesenswert?

funktioniert alles - kalte Lötstelle... :-(

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.