ATmega32 fast PWM 38kHz berechnung

OP #2145101
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?
OP #2151510
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren