Forum: Mikrocontroller und Digitale Elektronik 2 PWM-Grundsignale (Ausgänge) mit ATmega32 (C)


von C_Anfänger (Gast)


Lesenswert?

Morgen zusammen,

ich möchte mit dem Atmel ATmega32 zwei PWM-Grundsignale mit einer 
Frequenz von 25Hz an den Pins PD4 & PD5 (OC1A & OC1B) ausgeben. Hierzu 
möchte ich den internen Timer/Counter1 verwenden, indem ich ICR1 als 
TOP-Wert festlege. Als Vergleichswert stehen die Register OCR1A & OCR1B 
zur Verfügung. Das TCNT1 Register wird meines Erachtens nach nicht für 
die Initialisierung benötigt.

Das Programm funktioniert halbwegs, da mir das PWM-Grundsignal von 25Hz 
nur an einem Ausgang (OC1A / PD5) vorliegt. Meine Wenigkeit hat schon 
alles Mögliche versucht, um diesen Fehler zu beheben, z.B. die 
PWM-Betriebsart geändert, jedoch blieb der Erfolg bislang aus.

Damit ihr mein Problem nachvollziehen könnt, folgt hier jetzt der 
komplette Programmtext:
1
#include  <avr/io.h>
2
#define    F_CPU 16000000UL
3
4
/*  Initialisierung des 16-Bit Timer1
5
  - 9-Bit PWM-Mode
6
  - Fast-PWM
7
  - Vorteiler von 1024 --> 15,625 kHz
8
  - schreibe 625 ins Vergleichsregister --> 25 Hz
9
  - Zählwerte für OCR1A & OCR1B festlegen
10
  - PWM-Art bestimmen
11
  - OC1A & OC1B sind Ausgänge
12
*/
13
  void timer_init (){
14
15
    TCCR1A |= (1<<WGM11)| (0<<WGM10);      // 9-Bit PWM-Betriebsart
16
    TCCR1B |= (1<<WGM13) | (1<<WGM12);      // Fast-PWM    
17
    TCCR1B |= (1<<CS10) | (1<<CS12);      // Vorteiler von 1024 --> 15,625kHz
18
    ICR1 |= 625;                // zähle bis 625 --> 25Hz
19
    OCR1A |= 312;                // PWM an OC1A mit 50% Duty-Cycle
20
    OCR1B |= 156;                // PWM an OC1B mit 25% Duty-Cycle
21
    TCCR1A |= (1<<COM1A1) | (1<<COM1A0);    // Zählbeginn & invertierende PWM
22
    DDRD = (1<<PD5) | (1<<PD4);          // OC1A & OC1B als Ausgänge definieren
23
   }
24
25
  int main (void) {
26
    timer_init ();                // Initialisierung des Timers
27
    while (1);                  // Schleife
28
  }

Könnt ihr vielleicht einen Fehler ausmachen?

Falls es Probleme mit dem Verständnis meines Problems gibt, fragt mich 
einfach.

Ich bin euch für jede Hilfe sehr dankbar.

Gruß
C_Anfänger

von Ich (Gast)


Lesenswert?

C_Anfänger schrieb:
> TCCR1A |= (1<<COM1A1) | (1<<COM1A0);    // Zählbeginn & invertierende
> PWM

Dir fehlen die COM1Bx Bits.

von Ich (Gast)


Lesenswert?

C_Anfänger schrieb:
> TCCR1B |= (1<<CS10) | (1<<CS12);      // Vorteiler von 1024 -->
> 15,625kHz

Das würde ich übrigens ans Ende setzen, weil damit der Zähler losläuft.

von C_Anfänger (Gast)


Lesenswert?

>> TCCR1B |= (1<<CS10) | (1<<CS12);      // Vorteiler von 1024 -->
>> 15,625kHz
> Das würde ich übrigens ans Ende setzen, weil damit der Zähler losläuft.

Ist das so?
Ich habe von einem Freund, der C-Erfahrung hat, gehört, dass der Zähler 
mit dem beschreiben des Registers TCCR1A losläuft.

Die COM1Bx Bits habe ich mit hinzugefügt & den ATmega32 programmiert. 
Ich erhalte jetzt an beiden Ausgängen die gewünschten PWM-Signale.

Vielen Dank dafür
C_Anfänger

von Ich (Gast)


Lesenswert?

C_Anfänger schrieb:
> Ist das so?

Der Zähler fängt mit dem Setzen seines Taktes an zu zählen.
Mit dem COM-Bits schaltest Du nur die Pins dazu.

Die 1. Periode passt dann einfach nicht.
Ein Fehler den man sicher vernachlässigen kann, aber immer noch ein 
Fehler der auftritt.

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.