Forum: Mikrocontroller und Digitale Elektronik PWM Atmega 2560


von Christoph H. (christoph_b)


Lesenswert?

Hallo

Ich wollte die PWM an einem Atmega 2560 verwenden. Leider kommen am 
Ausgang immer nur 5V heraus.

Hier der Code. Seit 3h studiere ich wo der Fehler liegt, bis jetzt ohne 
Erfolg.
1
/*
2
 * PWM.c
3
 *
4
 * 
5
 *  Author: Christoph
6
 */ 
7
8
9
#include <avr/io.h>
10
#include <avr/interrupt.h>
11
#include <avr/delay.h> 
12
#include <stdint.h>
13
#include <avr/delay.h>
14
#include <avr/signal.h>
15
16
17
18
static void PWM(void)
19
{
20
21
DDRB=0xff; 
22
TCCR0A=(1<<WGM01)|(1<<COM0A1) |(1<<WGM00)|(1<<COM0B1);
23
TCCR0B =(1<<WGM02) |(1<<CS00);
24
OCR0A=50;
25
26
}
27
int main(void)
28
{
29
  
30
  PWM();
31
32
  while(1)
33
  {
34
  }
35
  return(0);
36
}

von spess53 (Gast)


Lesenswert?

Hi

Wo ist der Comparewert OCR0B? Damit stellst du dein PWM-Verhältnis ein. 
OCR0A (Top) bestimmt die Frequenz der PWM.

MfG Spess

von Stephan K. (dustpuppy)


Lesenswert?

Hi,
5Volt sind voellig korrekt. Du kannst ein PWM Signal nicht mit einem 
Multimeter messen. Da liegen immer 5Volt an. Ein Multimeter kommt bei 
gepulsten Signalen nicht mit. is dem zu schnell ;-)

So funzt das :
1
    DDRB=0xff;                                  // Port B as output
2
    ICR1 = freq;        // Set top for timer 1
3
    TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
4
    TCCR1B = (1<<WGM13)|(1<<WGM12) | (1<<CS10);
5
    OCR1A = 0;          // PWM on PB11
6
    OCR1B = 0;          // PWM on PB12

Durch veraendern von OCR0A und OCR0B kannste z.b. die Helligkeit einer 
Led einstellen. freq sollte bei Motoren nicht zu hoch sein, weil die 
sonst brummen. Ein Wert von 25-30 ist ok. Bei LEDs ist's egal. Einfach 
mit rumspielen.

Gruesse

Dusty

von Christoph H. (christoph_b)


Lesenswert?

Hallo

Schon klar das ich mit dem Multimeter das nicht messen kann.
Dafür habe ich ein Oszi.

mit
1
    DDRB=0xff;         // Port B as output
2
    ICR1 = 30;        // Set top for timer 1
3
    TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
4
    TCCR1B = (1<<WGM13)|(1<<WGM12) | (1<<CS10);
5
    OCR1A = 100;          // PWM on PB11
6
    OCR1B = 30;          // PWM on PB12

kriege ich am PortB7 0V und an PortB6 5V.
Klappt also noch nicht

Mit einem Atmega 16 habe ich die PWM hinbekommen nur der 2560 ärgert 
mich.

von Christopher G. (cbg)


Lesenswert?

Entscheide dich einmal. Oben verwendest du Timer0, hier nun Timer1.
Du verwendest jetzt am Schluss Timer1 FastPWM mit ICR1 als Top. Der 
gesamte Port B ist auf output. OC1A und OC1B wird nichtinvertierend 
werdendet. Du misst and PB6 und PB7, was OC1B und OC1C entspricht. OC1A 
ist PB5. OCR1B hat genau Top, was bei FastPWM einem konstanten 5 V Pegel 
auf OC1B (PB6) entpricht, so wie im Datenblatt beschrieben. OC1C (PB7) 
ist 0 V, da dieser nicht für PWM verwendet wird und als Defaultwert im 
PORT Register 0 hat. OCR1A ist höher als Top, das sollte also auf OC1A 
(PB5) auch 5 V ergeben, wenn dus mal misst.
So kann das nichts werden.


Den Top Wert legst du schon vor der Konfiguration des Modus fest. Sollte 
zwar nicht stören aber find ich irgendwie unschön. Ich mach das 
normalerweise so. Timer explizit anhalten. Modus setzen (WGMx und COMx 
Bits). Ggf Top Werte und dann Compare Werte setzen. Ggf Pins auf output 
setzen. Timer anwerfen (Prescaler setzen).

von Stephan K. (dustpuppy)


Lesenswert?

upsa....sorry....da sind Kommentare falsch drin in meinem Code. Ich 
benutz ein Arduino und 11 und 12 sind natuerlich nicht PB11 und PB12, 
sondern Digital 11 und Digital 12 vom Arduino Board :-)

OCR1A liegt auf PB 5 und OCR1B auf PB 6.

Das muss so funzen. Ich benutz das fuer die Ansteurung meiner 
Modellbahn.

Gruesse

Dusty

von spess53 (Gast)


Lesenswert?

Hi

>Das muss so funzen.

Wie soll da etwas herauskommem? Du hast PWM-Mode 14 mit ICR als Top 
eingestellt. Mit

>ICR1 = 30;

zählt der Timer bis 30 und fängt dann wieder bei Null an.

>    OCR1A = 100;          // PWM on PB11
>    OCR1B = 30;          // PWM on PB12

OCR1A wird nie erreicht und OCR1B erzeugt maximal kurze Spikes.

MfG Spess

von Martin (Gast)


Lesenswert?

In deiner Entwicklungsumgebung gibt es bestimmt einen Simulator. Warum 
läßt du dein Programm da nicht mal durchlaufen und guckst ihm dabei 
Schritt für Schritt in den relevanten Registern auf die Finger. Dafür 
ist das Ding da.

mfg Martin

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.