Forum: Mikrocontroller und Digitale Elektronik PWM Invertieren


von Reality (Gast)


Lesenswert?

Hallo Zusammen,

ich möchte mit einem ATmega328 ein PWM Signal am OC1A erzeugen.
Ich brauche das gleiche Signal aber auch nocheinmal invertiert.
Bin in sachen AVR Programmierung noch recht unehrfahren.
Ist es möglich das ich über den OC1B Ausgang das gleiche Signal wie
an OC1A ausgebe nur eben invertiert?

Bei Invertiert meine ich 5 V auf 0 V und umgekehrt.

Danke schonmal für die Hilfe!

von Falk B. (falk)


Lesenswert?

@  Reality (Gast)

>Ist es möglich das ich über den OC1B Ausgang das gleiche Signal wie
>an OC1A ausgebe nur eben invertiert?

Ja.

MfG
Falk

von Reality (Gast)


Lesenswert?

Danke für die schnelle antwort. wollte mich jetzt nur nicht ewig 
aufhalten damit um am ende festzustellen es geht nicht. Lese jetzt das 
Datenblatt und werd bestimmt bald mit neuen fragen dazu kommen ;)

von Reality (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen,

bin jetzt endlich dazu  gekommen an meinem Problem weiter zu arbeiten.
Hab mich jetzt schon viel mit dem Datenblatt und dem Tutorium hier 
beschäftig und hab jetzt doch noch einige fragen.
Ich möchte mit angehängtem Code eine PWM erzeugen und eine ADC Messung 
dadurch anstoßen.

Die PWM soll eine Frequenz von 500 Hz haben und alle 200 ms für 
insgesamt 40 ms an sein.
Dabei sollen nach der Hälfte der 40 ms eine zweite mittlere Spannungen 
entstehen.
U_Mittel_1 = 3.8V
U_Mittel_2 = 2.2V

Ich habe jetzt das Problem wenn ich z.B. in OCR1B  denn Wert so 
einstelle das ich 3.8 V habe weiß ich nicht wie ich dem Controller sagen 
kann, das er nach 20 ms auf die 2.2V umschalten soll.

Des Weiteren hab ich das Problem das ich nicht weiß, wie ich die 
Periodizität einstellen kann also das alle 200 ms für 40 ms an ist. Die 
PWM Frequenz hab ich eingestellt.

Mein (bis jetzt) letztes Problem ist, dass ich durch den ADC-Autotrigger 
eine Messung bei jedem Compare Match erzeugen will. Die entsprechenden 
Register habe ich gesetzt aber wie verwende ich das jetzt im Code?

Vielen Dank schon mal für die Hilfe(n)!

von Falk B. (falk)


Lesenswert?

@  Reality (Gast)

>    * Code.txt (2,5 KB, 0 Downloads)

Wenn du deinen Code als *.c Datei anhängst, wird er direkt als C-Code 
mit Farben dargestellt (Syntax Highlighting), siehe Netiquette.

>Die PWM soll eine Frequenz von 500 Hz haben und alle 200 ms für
>insgesamt 40 ms an sein.
>Dabei sollen nach der Hälfte der 40 ms eine zweite mittlere Spannungen
>entstehen.
>U_Mittel_1 = 3.8V
>U_Mittel_2 = 2.2V

>Ich habe jetzt das Problem wenn ich z.B. in OCR1B  denn Wert so
>einstelle das ich 3.8 V habe weiß ich nicht wie ich dem Controller sagen
>kann, das er nach 20 ms auf die 2.2V umschalten soll.

Ganz einfach. Im Timer Overflow Interrupt, welcher auch gleichzeitg 
deine PWM erzeugt, musst du mitzählen.
Bei 500Hz sind das 2ms/Überlauf. Macht 20 Überläufe für 40ms. Danach 
musst du den Wert im OC1A Register ändern, um das Tastverhältnis zu 
ändern.

>Des Weiteren hab ich das Problem das ich nicht weiß, wie ich die
>Periodizität einstellen kann also das alle 200 ms für 40 ms an ist. Die
>PWM Frequenz hab ich eingestellt.

Genau so. Der Timer läuft weiter, aber man kann die PWM-Ausgabe im 
Entprechenden Timerregister ausschalten.

>Mein (bis jetzt) letztes Problem ist, dass ich durch den ADC-Autotrigger
>eine Messung bei jedem Compare Match erzeugen will. Die entsprechenden
>Register habe ich gesetzt aber wie verwende ich das jetzt im Code?

Was willst du damit machen?

MfG
Falk

von Reality (Gast)


Angehängte Dateien:

Lesenswert?

Danke für die schnelle Antwort!!

Falk Brunner schrieb:
> Wenn du deinen Code als *.c Datei anhängst, wird er direkt als C-Code
>
> mit Farben dargestellt (Syntax Highlighting), siehe Netiquette.

ok habs nochmal als .c dran.

> Ganz einfach. Im Timer Overflow Interrupt, welcher auch gleichzeitg
>
> deine PWM erzeugt, musst du mitzählen.
>
> Bei 500Hz sind das 2ms/Überlauf. Macht 20 Überläufe für 40ms. Danach
>
> musst du den Wert im OC1A Register ändern, um das Tastverhältnis zu
>
> ändern.

ist klar, also müsste ich mitzählen und nach 10 Überläufen den Register 
Wert OC1B ändern um die mittlere Spannung runter zu setzten.



> Genau so. Der Timer läuft weiter, aber man kann die PWM-Ausgabe im
>
> Entprechenden Timerregister ausschalten.
>

also dann quasi nach 20 überläufen abschalten.
Kann ich dazu einfach in den non PWM mode schalten?


>>Mein (bis jetzt) letztes Problem ist, dass ich durch den ADC-Autotrigger
>
>>eine Messung bei jedem Compare Match erzeugen will. Die entsprechenden
>
>>Register habe ich gesetzt aber wie verwende ich das jetzt im Code?
>
>
>
> Was willst du damit machen?

Ich will bei jedem Compare Match den Wert am ADC einlesen um daraus
einen Strom Messen.

Gruß

von Falk B. (falk)


Lesenswert?

@  Reality (Gast)

>ist klar, also müsste ich mitzählen und nach 10 Überläufen den Register
>Wert OC1B ändern um die mittlere Spannung runter zu setzten.

Ja.

>also dann quasi nach 20 überläufen abschalten.
>Kann ich dazu einfach in den non PWM mode schalten?

Wozu? Lass den Modus wie er ist und schalte nur das OCx Pin ab, siehe 
Register TCCR1A und die bits COM1A1/COM1B1 COM1A0/COM1B0.

>Ich will bei jedem Compare Match den Wert am ADC einlesen um daraus
>einen Strom Messen.

Dann tu das doch einfach.

MFG
Falk

von Reality (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

wollte jetzt an einem kleinen Testaufbau
nur die PWM mir am Osszi anschauen.

Jedoch kann ich nichts richtiges Messen. Ich habe den PB1
mit einem 10k an Masse. Das Flashen (Dragon) des Controller
funktioniert konnte Testweise auch einen Port schon Toggeln lassen.
Jedoch funktioniert die PWM nicht, denke der Fehler liegt
im Code.

Danke schonmal für die hilfe!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Was sollte das Programm denn überhaupt machen?

Die Routine
> void PWM_init (void)
wird genau 1 mal aufgerufen. Das heißt, das
> if (T_overflow == 10)
und seine Nachfolger werden niemals wahr werden können, weil T_overflow 
nur den Wert 0 oder 1 annehmen kann... :-o

von Hc Z. (mizch)


Lesenswert?

> FAST PWM  mit TOP durch ICR1 und Compare durch OC1B
und dann...
1
OCR1A = 0x138;  //Initialisierung mit Tastgrad 50 %

Wenn Du Kanal B willst, musst Du schon OCR1B nehmen.

Was das ergeben soll ...
1
if (TOV1 == 1)
(und das Nachfolgende) erschließt sich mit nicht.  TOV1 ist eine 
Bitnummer (in TIFR) und immer 0 (beim 328).  Abfragen tust Du das Bit 
so nicht.

von Reality (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

das Programm soll ein PWM Signal mit 500 Hz erzeugen.
Insgesamt soll es 40 ms lang die PWM an sein und wärend
dessen 20 ms mit Tastgrad 50% und dann 20 ms mit Tastgrad 25%.

Diese 40 ms sollen sich alle 200 ms wiederholen
Das wollte ich mit diesesm Programm machen.
Bin wie gesagt ein anfänger daher passieren so dumme Fehler
wie die falsche Bit abfrage oder dem flasch gewählten PWM Ausgang.

Bei TOV1 dachte ich das dieses FLag jedes mal bei einem Zähler overflow
gesetzt wir?
DB:
The setting of this flag is dependent of the WGM13:0 bits setting. In 
Normal and CTC modes, the TOV1 Flag is set when the timer overflows. 
Refer to Table 15-4 on page 137 for the TOV1
Flag behavior when using another WGM13:0 bit setting.

Ich wollte jedes mal bei diesem Flag mitzählen und so die ganzen Daten 
zur PWM einstellen.

Muss ich damit die PWM dauerhaft läuft diese in die while Schleife 
packen?

Andere Frage: Was passiert eigentlich wenn ich einem Register wie OCR1A
einen float Wert schreibe? Rundet der sich Automatisch oder entsteht 
dadurch ein fehler?

Danke für die hilfen.

von Karl H. (kbuchegg)


Lesenswert?

Reality schrieb:

> das Programm soll ein PWM Signal mit 500 Hz erzeugen.
> Insgesamt soll es 40 ms lang die PWM an sein und wärend
> dessen 20 ms mit Tastgrad 50% und dann 20 ms mit Tastgrad 25%.


Fang erst mal damit an, eine PWM zu erzeugen.
Nicht alles auf einmal, eins nach dem anderen.
Erst mal musst du eine PWM auf dem Ausgang sehen.


> Bei TOV1 dachte ich das dieses FLag jedes mal bei einem Zähler overflow
> gesetzt wir?

TOV1 ist überhaupt kein Flag. TOV1 ist nur eine Makro, welches zu einer 
fixen Zahl expandiert. In dem Fall glaub ich, ist es 1. Spielt aber im 
Grunde keine Rolle. Faktum ist: Das fragt kein Bit in einem Register ab, 
sondern testet einfach nur eine Zahl.


> Muss ich damit die PWM dauerhaft läuft diese in die while Schleife
> packen?

Nein.
Du musst dich an den Interrupt hängen, der beim Overflow des Timers 
ausgelöst werden kann.

> Andere Frage: Was passiert eigentlich wenn ich einem Register wie OCR1A
> einen float Wert schreibe? Rundet der sich Automatisch oder entsteht
> dadurch ein fehler?

Da wird nichts gerundet.
Aus Sicht des C Compilers ist das eine Zuweisung eines float Wertes an 
eine Integer Variable und daher kommen auch die dort anzuwendenden 
Regeln zur Geltung: Nachkommastellen werden einfach abgeschnitten.


Du scheinst ziemliche Schwierigkeiten bei ziemlich einfachen Dingen zu 
haben. Da keimt in mir der Gedanke hoch, dass du ein paar ziemlich 
grundlegende erste Schritte übersprungen hast und jetzt fehlt dir dieses 
Grundwissen, wie zb: wie fragt man ein Bit in einem Register ab.

von Reality (Gast)


Angehängte Dateien:

Lesenswert?

Karl heinz Buchegger schrieb:
> Fang erst mal damit an, eine PWM zu erzeugen.
>
> Nicht alles auf einmal, eins nach dem anderen.
>
> Erst mal musst du eine PWM auf dem Ausgang sehen.

Gute Idee ;)
Also ich möchte mit angehängten Programm einfach eine
PWM mit 500 Hz und Tastgrad 25% erzeugen. Geht aber leider nicht...


> TOV1 ist überhaupt kein Flag. TOV1 ist nur eine Makro, welches zu einer
> fixen Zahl expandiert. In dem Fall glaub ich, ist es 1. Spielt aber im
> Grunde keine Rolle. Faktum ist: Das fragt kein Bit in einem Register ab,
> sondern testet einfach nur eine Zahl.

Aber in dem Buch Mikrocomputertechnik mit Controllern der Atmel 
AVR-Risc-Familie (S.309)steht auch z.B das TOV1 bei einem überlauf 
gesetzt wird.
Das ist doch dann ein Flag oder?

> Du musst dich an den Interrupt hängen, der beim Overflow des Timers
> ausgelöst werden kann.

Ich denke da liegt mein Fehler im Programm. Das wäre dann TIMSK1
und OCIE1A wo ich in dessen ISR(TIMER1 COMPA) die PWM Werte einstellen
müsste oder?


> Du scheinst ziemliche Schwierigkeiten bei ziemlich einfachen Dingen zu
> haben. Da keimt in mir der Gedanke hoch, dass du ein paar ziemlich
> grundlegende erste Schritte übersprungen hast und jetzt fehlt dir dieses
> Grundwissen, wie zb: wie fragt man ein Bit in einem Register ab

Ja sagen wir so meine C Kentnisse vorallem im Bezug auf Mikrocontroller 
sind schon ein paar jahre nicht benutzt wurden, was ich jetzt wieder 
aufbessern will.

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.