Phase Correct PWM auf AtMega Familie

Gast #3412394
Lesenswert?

Hallo,

ich finde den Fehler nicht bei der Initialisierung meines PWM-Signals 
als Phase-Correct (nicht FAST) Mode auf OC1A / PD5 eines AtMega16.
- Es kommt kein Signal -

1
DDRD= (1<<PIND5); // PWM Lock-In-Signal (Output)
2

3
//Initialize Lock-In-PWM-Signal
4
TCCR1A |= (1<<COM1A0) | (1<<WGM10);  // COM1A1:0 = 01, WGM12:10 = 101 Phase Correct PWM Mode
5
TCCR1B |= (1<<WGM12) | (1<<CS11);  // CS02:00 = 010 clk prescaler 1/8
6
  OCR1A = 200;

habe ich irgendetwas nicht verstanden? Oo
Gast #3412416
Lesenswert?

Stefan Ernst schrieb:
> Du hast gar kein Phase-Correct-Modus ausgewählt, sondern 8-Bit-Fast-PWM.

Woran erkennst du das?
Laut Datenblatt ist der Fast PWM mode aktiv bei WGM02:0 = 3 oder 7, bei 
mir ist WGM02:0 = 5.

Aber: Auch der F PWM mode sollte ja am oszi was zeigen...


Ich habe ehrlich gesagt noch nie einen anderen PWM channel als den OC0A 
benutzt, daher die vorsichtshalber nachfrage: alle register, die gesetzt 
werden heißen dann für OC1A eben z.b. nicht TCCR0A sondern TCCR1A und 
die bits eben COM1A0 statt COM0A0 richtig?
#3412429
Lesenswert?

>  daher die vorsichtshalber nachfrage: alle register, die gesetzt werden heißen 
dann für OC1A eben z.b. nicht TCCR0A sondern TCCR1A und die bits eben COM1A0 statt 
COM0A0 richtig?

Richtig.,
Aber nur weil beim Timer 0 das Bit XYZ im Register ABC0 ist, bedeutet 
das nicht, dass beim Timer 1 das ganz genauso ist, und Register ABC1 
richtig wäre.

D.h. durch die Mühle durch und alle Bits kontrollieren.
#3412440
Lesenswert?

Da haben wirs schon.
Ist der Timer auf Fast-Pwm, dann ist für die Bedeutung der COM Bits die 
Tabelle 45 auf Seite 111 zuständig "Table 45. Compare Output Mode, Fast 
PWM"
1
COM1A1/COM1B1 COM1A0/COM1B0 Description
2

3
     0            0         Normal port operation, OC1A/OC1B disconnected.
4

5
     0            1         WGM13:0 = 15: Toggle OC1A on Compare
6
                            Match, OC1B disconnected (normal port
7
                            operation).
8
                            For all other WGM13:0 settings, normal port
9
                            operation, OCnA/OCnB disconnected.
10

11
     1            0         Clear OC1A/OC1B on compare match, set
12
                            OC1A/OC1B at BOTTOM,
13
                            (non-inverting mode)
14

15
     1            1         Set OC1A/OC1B on compare match, clear
16
                            OC1A/OC1B at BOTTOM,
17
                           (inverting mode)


Du hast
1
TCCR1A |= (1<<COM1A0) | (1<<WGM10)
also nur COM1A0 gesetzt. Dein Modus ist auch nicht 15. Damit gilt:
1
For all other WGM13:0 settings, normal port
2
operation, OCnA/OCnB disconnected.


Du musst jedes Bit mit dem Datenblatt kontrollieren! Nur weil beim Timer 
0 etwas so funktioniert hat, bedeutet das nicht, dass das bei einem 
anderen Timer ganz genau so ist.

Atmel hat in den Datenblättern schöne Tabellen drinnen. Die sind dein 
erster Anlaufpunkt, wenn du etwas einstellen willst.
Gast #3412448
Lesenswert?

Sorry das war mein Fehler, dass ich den µC nicht genau genug 
spezifiziert habe, es ist ein 164. So schnell kanns gehen. Im dortigen 
Datenblatt stimmt meine Registerbelegung leider (glaube ich).

Wo wird denn bestimmt welcher Timer für den PWM channel genutzt wird? 
der 164 hat ja 6 PWM channel OC0, OC1, OC3 jeweils A/B
- bedeutet das automatisch dass der Timer0 auch die PWM0 channel 
steuert?
Ich frage, denn:

Der Timer1 ist ja ein 16 bit timer, mir reichen aber 8 Bit. Nur war eben 
tatsache kein anderer PWM Pin frei als der PD5
Gast #3412509
Lesenswert?

Und immernoch mag er nicht.

Aktueller Stand: Mega164A(sorry nochmal),
habe einen freien PWM pin - OC2A / PD7 - vom Timer2 gefunden also nun: 
Timer 2, 8Bit, OCR2A wird gefüllt:

Egal ob Phase Correct
1
//Initialize Lock-In-PWM-Signal
2
PRR0 &= ~(1<<PRTIM2);// Power Reduction Register: Timer2 Enable
3
TCCR2A |= (1<<COM2A0) | (1<<WGM20);  // COM2A1:0 = 01, WGM22:10 = 101 Phase Correct PWM Mode, Toggle on compare match 
4
TCCR2B |= (1<<CS21) | (1<<WGM22);   // CS22:20 = 010 clk prescaler 1/8
5
OCR2A = 200;

oder Fast PWM
1
PRR0 &= ~(1<<PRTIM2);
2
TCCR2A=(1<<COM2A0) | (1<<COM2A1) | (1<< WGM20 ) | (1<< WGM21 );
3
TCCR2B=(1<<CS20) ; // no prescaling,
4
OCR2A = 200;

Ich bekomme nur 2mV rauschen am Pin. Habe ich IRGENDWAS vergessen oder 
sollte das so eigentlich klappen?
Der Pin wird nicht low gezogen/ ist nicht kurz - mit einfachem pintoggle 
im code habe ichs schon probiert, den sieht man auch.
#3412515
Lesenswert?

Kannbst du dich bitte irgendwann mal mit dir selber auf einen Timer 
und/oder Kanal und/oder PWM Modus einigen?

Ich wär dir da sehr verbunden, denn schön langsam hab ich keine Lust 
mehr, alle 10 Minuten erneut das Datenblatt zu durchsieben, ob die Bits 
auch wirklich alle in den von dior verwendeten Registern sind und ob sie 
auch wirklich die Bedeutung haben, die du annimmst.

Danke.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren