Forum: Mikrocontroller und Digitale Elektronik Erzeugung von 25kHz PWM mit Hilfe von Timer 1


von Julian D. (Gast)


Lesenswert?

Hallo,

ich bräuchte ein bisschen Hilfe für meine Projekt 4-Kanal 
Lüftersteuerung.
Kurze Zusammenfassung:
-At Mega32
-3x 3 Pin Lüfter Ansteuerbar; Stufenlos Regelbar mit Hilfe von PWM => 
RC-Glied => OP => Mosfet;
-1x 4 Pin Lüfter Anschluss mit 25 kHz PWM zur Regelung.(Timer1)

Und zwar habe ich ein Problem mit der Erzeugung des 25kHz Pwm mit Hilfe 
des Timers1.
Ich setzt brav meine Register:
1
   TCCR1A = (1<<COM1A1)          // Nicht invertierende PWM.
2
            |(1<<WGM13);//|(1<<WGM10); // FAST PWM Phase Frequ. Correct
3
   TCCR1B =  (1<<CS11);             // Prescaler 8 ( N )
So. Nun geh ich nach der Formel aus dem Datenblatt vor um meine 25 kHz 
zu erzeugen:
Fclk =  clk       (16MHz)
      --------
      2*N*TOP

Top kann ich verändern durch setzen des Registers ICR1.
Wenn ich jetzt die Formel umstelle um 25kHz zu erzeugen ( bei Prescaler 
8 ) komm ich auf ein TOP von 40.
Dies schreib ich dann ins Register ICR1.
1
   ICR1   = 40;                     // F: 25kHz

So wenn ich die Frequenz mit dem Oszilloskop nachmesse komme ich auf 250 
Hz. Wieso?!
-Wo ist mein Rechenfehler?
-Welche Register Muss ich sodann setzen um die Pulsbreite zu 
verändern?OCR1?
-Ist der Modus dafür dann auch richtig gesetzt?

von Matthias (Gast)


Lesenswert?

Also ich würde mir an deiner Stelle die Registerwerte nochmal genau 
ansehen.
Mir fällt dabei schonmal auf, dass TCCR1A kein Bit mit der Bezeichnung
WGM13 enthält. Da gibt es nur WGM11 und WGM10 !

Versuch mal TCCR1A = (1<<COM1A1); und TCCR1B = (1<<WGM13)|(CS11);

Die Berechnung mit der Frequenz hab ich nicht geprüft!

von Matthias (Gast)


Lesenswert?

Nachtrag:

Die Pulsbreite wird über OCR1A eingestellt. Die Anzahl der Schritte
von 0 bis TOP gibt die Periodendauer an. Der Abstand von 0 bis OCR1A 
(mal zwei!) ist in dem Fall die ON-Zeit und von OCR1A bis TOP (mal zwei) 
die OFF-Time. Bei 25KHz (40us Periode) und 16Mhz ( 2MHz Timertakt = 
0,5us)
Braucht es 80 Timerinkremente für eine Periode. Da die Zeiten mal Zwei 
gerechnet werden, sollte der Wert von 40 als TOP stimmen.
Wird OCR1A = 20 gesetzt muss sich am Ausgang ein PWM Signal mit 50% 
Tastverhältnis zeigen. OCR1A = 0 -> Signal immer AUS und OCR1A = TOP 
Signal immer AN.

von Julian D. (Gast)


Lesenswert?

Also ich habe meine Register nun wiefolgt gesetzt:
1
   TCCR1A = 0x00
2
         |(1<<COM1A1)          // Nicht invertierende PWM.
3
            |(1<<WGM10) ;          // FAST PWM Phase Frequ. Correct
4
   TCCR1B = 0x00
5
         |(1<<CS11)              // Prescaler 8 ( N )
6
            |(1<<WGM13);            // FAST PWM Phase Frequ. Correct 
7
   ICR1  = 40;                     // F: 25kHz
8
   OCR1A = 5;
9
10
   DDRD = 0x00;
11
   DDRD  |= (1<<PD5);        
12
   DDRD  |= (1<<PD6);
Jetzt hab ich mal ein Kleines Test Main geschrieben um die PWM mal zu 
testen:
1
   uint8_t bPortD=0x00;
2
   uint16_t PWM=0;  
3
4
   while(1)
5
   {
6
       PORTD = 0x40;
7
       bPortD = PIND;
8
       if (bPortD & (1<<PIND3))
9
       {
10
           if(PWM>=5)
11
           {
12
         PWM-=5;
13
           }
14
       }
15
       if (bPortD & (1<<PIND4))
16
       {
17
           if(PWM<=35)
18
           {
19
               PWM+=5;
20
           }
21
       }
22
   OCR1A = PWM;
23
   }
Ich hab zusätzlich noch ein Display daran hängen am PORTC um den 
aktuellen   Wert von PWM zu prüfen. Das ganze funktioniert so weit das 
ich die Pulsbreite über OCR1A einstellen kann sodass bei 0 KEIN Signal 
am OC1A anliegt. Sobald Werte >0 eingestellt werden ist nur der 5V Pegel 
vorhanden.
Wo ist mein Fehler?
Die Werte von ICR1 wurdne laut der Formel( siehe oben ) berechnet.

von Julian D. (Gast)


Lesenswert?

//edit Mit 5V Pegel ist ein Dauer-5V-Pegel gemeint.

von Matthias (Gast)


Lesenswert?

Bei TCCR1A den WGM10 Teil weglassen!

Dann ist ICR1 der TOP Wert und OCR1A die PWM Einstellung. Wenn du WGM10
machst, dann wird OCR1A als TOP benutzt und ICR1 hat keine Funktion!

Frage:
Wie werden die Eingänge PIND3 und PIND4 entprellt?
Sowas hab ich auch mal programmiert und dann hat ein Tastendruck
den jeweils zugehörigen "Endanschlag" eingestellt, da der Controller
sehr schnell ist!

von Julian D. (Gast)


Lesenswert?

Yap habs jetzt so zum laufne bekommen. Nur ist mir aufgefallen das 
entweder:
-Die Formel im Datenblatt nicht stimmt ( glaub ich mal nicht )
-Oder ich iwas falsch gemacht habe oder iwas ist defekt ( Quarz ? )

Auf jeden Fall komm ich entgegen der Formel durch Ausprobieren auf die 
Werte ICR=20 bei keinem Prescale.
Laut Formel komm ich jetzt damit auf:
16Mhz
--------- = 400kHz
2*1*20
Real mess ich am Oszilloskop nun 25kHz. Messfehler durch Oszi kann ich 
ausschließen durch Test mit Funktionsgenerator erzeugtem 10kHz Rechteck.

Wie kann man das erklären? Kann ich das Quarz iwie Testen ?


Tasten entprellen hab ich mich jetzt noch nich beschäftigt. Die Taster 
an meinem Pollin Eval-Board sin über ne RC-Kombination entprellt:

PINx ---|----|---Taster----> 5V
        |    |
        C    R
        |    |
       GND  GND


Nun habe ich ein weiteres Problem.
Da ich alle 4 Timer benötige für meine Steuerung brauche ich den 2ten 
PWM des Timers1 ebenfalls. Wenn ich jetzt mit OCR1B meinen 
Vergleichswert einstelle bekomme ich am Ausgangspin OC1B kein Signal 
hin.

Muss ich noch iwelche Register setzen um den OC1B zu "aktivieren"?

Oder ist es Sinnvoll einen Timer für andere Steuerungsaufgaben 
aufzuheben ? ( Entprellen, für iwas Interrupts zB will ich noch den UART 
für ne Kommunikaton mit dem PC nutzen )

Kann mir jemand meine Fragen beantworten?

Danke im Vorraus
Julian :)

von Michael Wilhelm (Gast)


Lesenswert?

400Khz errechnet
25KHz gemessen

ein Verhältnis von 1:16.

Ich glaube der interne Oszillator ist da am werkeln und nicht der Quarz.

MW

von Julian D. (Gast)


Lesenswert?

Danke. Jetzt funktioniert es. Habe nicht beachtet das die AT´s im 
Auslieferungszustand auf int. RC Oszi. eingestellt sind. Jetzt läuft der 
ext. 16 MHz Quarz.

Bleiben aber noch die anderen Probleme:
"
Nun habe ich ein weiteres Problem.
Da ich alle 4 Timer benötige für meine Steuerung brauche,brauche ich den 
2ten
PWM des Timers1 ebenfalls. Wenn ich jetzt mit OCR1B meinen
Vergleichswert einstelle bekomme ich am Ausgangspin OC1B kein Signal
hin.

Muss ich noch iwelche Register setzen um den OC1B zu "aktivieren"?

Oder ist es Sinnvoll einen Timer für andere Steuerungsaufgaben
aufzuheben ? ( Entprellen oder für iwelche Interrupts zB will ich noch 
den UART für ne Kommunikaton mit dem PC nutzen )
"

Währe über jede Hilfe dankbar.
mfg
Julian D

von Matthias (Gast)


Lesenswert?

TCCR1A = (1<<COM1A1)|(1<<COM1B1);

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.