Forum: Mikrocontroller und Digitale Elektronik PWM-Periodendauer einstellen bei Atmega32


von Karsten B. (residuen)


Lesenswert?

Hallo zusammen,

ich habe ein Problem mit PWM beim Atmega32. Ich habe ein für mein 
Verständnis funktionsfähiges Programm. Das PWM-Signal sieht auf dem 
Oszilloskop auch schön aus. Nur leider bekomme ich die Periodendauer 
nicht eingestellt. Laut Beschreibung der Register muss ich den Endwert 
des Counters ins Input Capture Register ICR1 schreiben. Bei Erreichen 
des Wertes in ICR1 sollte das ICFS-Flag zurückgesetzt werden. Für mein 
Verständnis stelle ich so die Periodendauer ein.
Mache ich was falsch? Hier der Quellcode:
1
#define F_CPU 8000000UL
2
3
#include <avr/io.h>
4
#include <util/delay.h>  
5
6
void pwm_Init()
7
{
8
  DDRD |= (1<< PD5); // PWM an PORTD PIN5
9
10
  TCCR1A |= (1<<WGM10) | (1<<WGM11);// 10-Bit PWM Betriebsart aktivieren. 
11
  TCCR1A |= (1<<COM1A1);  // Bei erreichtem Vergleichswert wird Output Pin OC1 auf 0 gesetzt. 
12
  
13
  TCCR1B |= (1<<WGM12);  // clear-counter in TCNT1
14
  TCCR1B |= (1<<ICNC1);  // Rauschunterdrueckung
15
  TCCR1B |= (1<<ICES1);  // HIGH-Pegel zur Auswertung
16
  TCCR1B |= (1<<CS11);  //Prescaler 8
17
  
18
  ICR1 = 512;  // Startwert des counters
19
  
20
  //OCR1A = 512; // Register mit PWM-Wert. Erlaubter Bereich: 0 bis 1023 da 10 Bit.
21
  
22
  //Die Pulsbreite kann nun über das Register OCR1A vorgegeben werden.
23
}
24
25
/*PWM-Demo */
26
int main()
27
{
28
  pwm_Init();
29
30
  //while(1);
31
  
32
  int i;
33
  
34
  while(1)
35
  {
36
    for(i=0; i<1023; i++)
37
    {
38
      OCR1A =  i;
39
      _delay_ms(5);
40
    }
41
  
42
    for(i=1023; i>0; i--)
43
    {
44
      OCR1A =  i;
45
      _delay_ms(5);
46
    }  
47
  }
48
}
Danke für die Hilfe

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Karsten B. schrieb:
> Laut Beschreibung der Register muss ich den Endwert
> des Counters ins Input Capture Register ICR1 schreiben.

Da kommt der Topwert rein. Aber nicht in dem diesem Modus. Hier ist der 
Topwert fest 0x3FF. In Modus 14 kannst du das ICR entsprechend nutzen.

mfg.

von Karsten B. (residuen)


Lesenswert?

Hallo Thomas,

klappt auf Anhieb, danke für den schnellen Tip :-)
So sieht nun die Init-Funktion aus:
1
void pwm_Init()
2
{
3
  DDRD |= (1<< PD5); // PWM an PORTD PIN5
4
5
  TCCR1A |= (1<<WGM11);    // Fast PWM Mode 14,  ICR1 Counter-Endwert
6
  TCCR1A |= (1<<COM1A1);    // Bei erreichtem Vergleichswert wird Output Pin OC1 auf 0 gesetzt. 
7
  
8
  TCCR1B |= (1<<WGM12) | (1<<WGM13);  // Fast PWM Mode 14,  ICR1 Counter-Endwert
9
  TCCR1B |= (1<<ICNC1);  // Rauschunterdrueckung
10
  TCCR1B |= (1<<ICES1);  // HIGH-Pegel zur Auswertung
11
  TCCR1B |= (1<<CS11);  //Prescaler 8
12
  
13
  ICR1 = 512;  // Startwert des counters
14
  
15
  OCR1A = 127; // Register mit PWM-Wert. Erlaubter Bereich: 0 bis 1023 da 10 Bit.
16
  
17
  //Die Pulsbreite kann nun über das Register OCR1A vorgegeben werden.
18
}
Besten Dank!!

PS: Wie kann ich einen Beitrag als "gelöst" markieren?

: Bearbeitet durch User
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.