Forum: Mikrocontroller und Digitale Elektronik ATmega PWM aktualisiert nicht


von sur3 (Gast)


Lesenswert?

Hallo, ich habe eine Problem mein ATmega644P ignoriert leider meine 
PWM-Befehle (OCR0A = x;), wenn sie in einer while-Schleife stehen, wie 
kann das sein? o.O
Hier mein Programmcode es ist eine Abwandlung eines Tutorials..
1
// this code sets up counter0 for an 8kHz Fast PWM wave @ 16Mhz Clock
2
3
4
#include <avr/io.h>
5
6
7
int main(void)
8
{
9
    DDRB |= (1 << DDB3);
10
    // PB3 is now an output
11
12
    OCR0A = 0;
13
    // set PWM to LOW for testing
14
15
16
    TCCR0A |= (1 << COM0A1);
17
    // set none-inverting mode
18
19
    TCCR0A |= (1 << WGM01) | (1 << WGM00);
20
    // set fast PWM Mode
21
22
    TCCR0B |= (1 << CS01);
23
    // set prescaler to 8 and starts PWM
24
25
   OCR0A = 255; //funzt! :-)
26
27
    while (1);
28
    {
29
  OCR0A = 0; //tut nix! :-/
30
  _delay_ms( 1 );
31
    }
32
}

: Bearbeitet durch User
von Jon D. (shee2e)


Lesenswert?

Hallo,
erstmal bitte den Code in eine code Umgebung packen.
dann bist du dir sicher, dass es ein Fehler ist? Wie sieht ein PWM mit 0 
bzw 255 aus (mit was mist du?)?
Zu _delay_ms richtige Optimierung gesetzt?
Dazu noch Fuses gesetzt, hast bestimmt schon ne LED Blinken lassen, 
wegen taktrate ermitteln.
wie soll die 255 Funktionieren wenn du in einer sehr kuzren Zeit das 
OCR0A Register auf 0 seltzt.
Ich nehme an dein PWM sieht so aus
            ____________________________________________________
Reset: ____/                                                       t_inf
             _______________
PWM  : ______|               |_________________________________

Oder?

MfG
shee2e

von Max H. (hartl192)


Lesenswert?

Nach dem while(1) ist ein Strichpunkt tu viel.

von sur3 (Gast)


Lesenswert?

> erstmal bitte den Code in eine code Umgebung packen.
wie geht das hier, mit spitzen oder eckigen klammern?

> Zu _delay_ms richtige Optimierung gesetzt?
Hab einfach verschiedene Delays probiert, kann man da was optimieren? 
o.O

> Ich nehme an dein PWM sieht so aus
>             ___________________________________________________
> Reset: ____/                                                       t_inf
>              _______________
> PWM  : ______|               |_________________________________
>
> Oder?

Nope, sah so aus:
             __________________________________________________
 Reset: ____/ 
t_inf
              _________________________________________________
 PWM  : ______|


Max H. schrieb:
> Nach dem while(1) ist ein Strichpunkt tu viel.
Autsch, das war der Fehler, danke, wie dumm von mir, das Semikolon war 
auch unsinnigerweise im Tutorial, hatte das blind kopiert.. 
https://sites.google.com/site/qeewiki/books/avr-guide/pwm-on-the-atmega328

Jetzt funktioniert es soweit, nur glimmt die LED immernoch, wenn ich auf 
0 setze, ich habe gesehen jemand anders hat das problem mit phase 
correctep pwm gelößt, aber ich verstehe nicht ganz den unterschied 
zwischen phase und frequenz-corrected, was ich brauche ist eingentlich 
ein Signal mit mindestens 1 kHz bei dem high genauso lang ist wie low, 
also OCR0A=128 das man ausschalten kann, schafft phasenkorrigiertes PWM 
solche Frequenzen noch? - mein Oszi ist leider grad kaputt..
Und kann man das auf ausschalten/auf null stezen irgendwie timen, damit 
es immer passiert wenn die Flanke ohnehin grade auf null geht und nicht 
mitten in einer high phase?
Außerdem brauche ich einen zweiten invertierten Ausgang, ich vermute 
OCR0B ist automatisch synchronisiert, die beiden verwenden doch den 
selben Timer oder wird der intern nochmal gesplittet wodurch eine 
phasenverschiebung entstehen kann?

Besten Dank
Sur3

von Karl H. (kbuchegg)


Lesenswert?

sur3 schrieb:

> Jetzt funktioniert es soweit, nur glimmt die LED immernoch,

Ja. Das ist normal und der Art und Weise geschuldet, wie die PWM in 
Hardware implementiert ist.
Wenn du eine PWM von 0 haben willst, dann schalte die PWM einfach 
komplett ab.

> wenn ich auf
> 0 setze, ich habe gesehen jemand anders hat das problem mit phase
> correctep pwm gelößt, aber ich verstehe nicht ganz den unterschied
> zwischen phase und frequenz-corrected, was ich brauche ist eingentlich
> ein Signal mit mindestens 1 kHz bei dem high genauso lang ist wie low,
> also OCR0A=128 das man ausschalten kann,

Dann mach genau das.
1kHz ist überhaupt kein Problem.

Schalte die PWM ab, indem du das COM Bit löscht. Damit gibt der Timer 
die Kontrolle über den Pin wieder ab und du kannst ihn mit einem PORT 
Befehl auf 0 setzen.

> Außerdem brauche ich einen zweiten invertierten Ausgang, ich vermute
> OCR0B ist automatisch synchronisiert

richtig.

> die beiden verwenden doch den
> selben Timer oder wird der intern nochmal gesplittet wodurch eine
> phasenverschiebung entstehen kann?

Nein. Der Gedankengang ist schon richtig.


PS: Das was du willst kann man auch so erreichen, dass der Pin bei einem 
Compare Match einfach nur getoggelt wird. Das kann man in Hardware 
machen, man könnte es aber auch in Software machen. Das sollte bei 
deinen Frequenzen noch kein Problem sein. In Software hast du den 
Vorteil, dass du dann die volle Kontrolle über den Pin hast und ihn auch 
gezielt und sauber ein / aus schalten kannst.

: 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.