Forum: Mikrocontroller und Digitale Elektronik Fast PWM bei ATMEGA8 will nicht


von Igor M. (bastel-wastel)


Lesenswert?

Guten Abend,
ich habe ein Problem mit dem Fast PWM Modus (Mode 14)
Normalerweise sollte der Counter bis ICR1 zählen und dann wieder von 
null beginnen. Wichtig für mich ist eigentlich nur das Einstellen von 
ICR1 für eine bestimmte Frequenz. Leider zählt der Counter viel weiter 
als er sollte und zählt dann wieder runter. Ich finde leider den Fehler 
nicht. Getestet habe ich das ganze nur als Simulation mit dem aktuellen 
AVR Studio.
Wo könnte der Fehler liegen?
1
/Initialisierung vom PWM Modul
2
  bit_set(TCCR1A,COM1A1);  // OC1A nicht invertierendes PWM
3
4
  DDRB = 255;    // PORTB (PB1,OC1A) als Ausgang
5
6
  ICR1 = 128;
7
8
  bit_clear(TCCR1A,WGM10);
9
  bit_set(TCCR1A,WGM11);  // 8-Bit PWM (Timer1); Fast PWM
10
  bit_set(TCCR1B,WGM12);  // TOP-Wert in ICR1
11
  bit_set(TCCR1B,WGM13);  
12
13
14
  bit_set(TCCR1B,CS10);  // Takt = T_clk / 1
15
16
17
  OCR1AL = 50;

von Mike J. (Gast)


Lesenswert?

@ Igor Metwet

// Fast PWM 8-bit (WGM12,10 = Mode 5)  Clear On Compare match
  TCCR1A  = (1<<COM1A1) | (1<<COM1B1) | (1<<WGM10);
  TCCR1B  = (1<<CS10) | (1<<WGM12); // kein Prescaling + PWM Mode 5

Im Hauptprogramm den Interrupt abfangen.

von Igor M. (bastel-wastel)


Lesenswert?

Versteh ich nicht ganz. Was meinst du mit Interrupt abfangen?
PWM sollte doch ohne weiteren Code alleine laufen. Ist ja Hardware-PWM.

PWM-Mode 5 bringt mir nichts, da ich den TOP-Wert einstellen muss, um 
meine gewünschte Frequenz zu erhalten.

von Benedikt K. (benedikt)


Lesenswert?

Keine Ahnung wiso es immer wieder Leute gibt, die irgendeinen Mist 
erzählen, der garnix mit der Frage zu tun hat. Naja, ist halt so...

@Igor
Abgesehen dass bit_set() etwas unüblich ist, (und ich jetzt mal davon 
ausgehe, dass es das macht was der Name sagt), dann sollte es eigentlich 
funktionieren.

Noch ein Hinweis am Rande:
OCR1AL = 50;
Das ist nicht ganz das was du vermutlich vorhast. OK, in dem Fall schon, 
aber generell kann sowas ein schöner Fehler sein, denn es wird auch das 
Highbyte mitgeschrieben. Und da man selten weiß, mit welchem Wert es 
gerade belegt ist, schreibt man irgendwas mit. In diesem Fall wurde das 
Highbyte aber zuletzt hier beschrieben:
ICR1 = 128;
Da dieser Wert <256 ist, ist es 0. Also macht es das was du vorhast.

von Igor M. (bastel-wastel)


Lesenswert?

Danke dir.
bit_set() passt schon:
1
#define bit_set(var,bitnr)   ((var) |= 1 << (bitnr))    // Einzelnes Bit setzen

Ich habe die Register aber auch im AVR-Studio im Auge behalten.
Dass das High-Byte beschrieben wird, obwohl ich nur das Low-Byte 
beschreibe ist mir jetzt neu. Ist das generell so bei den 16Bit 
Registern? Gibts dann auch ne Möglichkeit, wie ich nur das Low-Byte 
beschreiben kann, ohne das High-Byte anzufassen?

Wenn sonst alles richtig ist, gehe ich mal davon aus, dass AVR-Studio 
hier ein Problem mit der Simulation hat. Muss dann wohl doch einen 
Hardware-Aufbau machen..

von Benedikt K. (benedikt)


Lesenswert?

Igor Metwet wrote:

> Dass das High-Byte beschrieben wird, obwohl ich nur das Low-Byte
> beschreibe ist mir jetzt neu. Ist das generell so bei den 16Bit
> Registern? Gibts dann auch ne Möglichkeit, wie ich nur das Low-Byte
> beschreiben kann, ohne das High-Byte anzufassen?

Nein, es werden beide immer zusammen geschrieben, siehe Datenblatt 
"Accessing 16-bit Registers" (beim mega8 auf Seite 79). Das ganze ist 
halt eine Kompromisslösung um 16bit Register auf einem 8bit CPU einfach 
ansteuern zu können.

von Igor M. (bastel-wastel)


Lesenswert?

Ok, danke für die Infos!!

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.