Forum: Mikrocontroller und Digitale Elektronik Phase Correct PWM Mode 5 mit ATtiny13


von Holger K. (Gast)


Lesenswert?

Hallo allerseits,
mit einem Attiny13 möchte ich ein 25kHz-PWM-Signal erzeugen. Dazu habe 
ich folgendes Assembler-Programm geschrieben und mit AVR Studio 5 
simuliert:
1
; attiny13-Header-Datei einbinden
2
.nolist
3
.include "tn13def.inc"
4
.list
5
6
; r16 als temporäre Variable definieren
7
.def rTemp = R16
8
9
; Konfiguration Phase Correct PWM
10
; Compare Output Mode: COM0B1=1; COM0B0=1 -> OC0B=1 bei Count up; OC0B=0 bei Count down
11
; Waveform Generation Mode: WGM02=1; WGM00=1 -> Mode 5 (Phase Correct PWM; TOP in OCRA)
12
; Clock Select: CS00=1 -> clk i/o; prescale = 1 
13
.equ vConfTCCR0A = (1<<COM0B1)|(1<<COM0B0)|(1<<WGM00)
14
.equ vConfTCCR0B = (1<<WGM02)|(1<<CS00)
15
.equ vMAX = 200 ; Maximaler Zählwert für PWM (f=10MHz/1*2*OCR0A = 25kHz -> T = 1/f = 40µs)
16
.equ vTi = 100 ; Impulsdauer voreingestellt auf 255 / 25kHz *100 = 15µs
17
18
; Flash RAM auf Adresse 0 einstellen
19
.org 0
20
21
ldi rTemp,RAMEND ; Stack Pointer initialisieren
22
out SPL, rTemp
23
24
sbi DDRB,PB1 ; PB1 als Ausgabeport definieren, nicht PB0, da MAX=OCR0A!
25
26
ldi rTemp, vMAX ; Wert für MAX laden
27
out OCR0A, rTemp ; und in Output Control Register A laden
28
29
ldi rTemp, vTi ; Wert für Ti laden
30
out OCR0B, rTemp ; und in Output Control Register B laden
31
32
ldi rTemp, vConfTCCR0A ; Einstellungen für den PWM-Modus laden
33
out TCCR0A, rTemp ; und ins Timer/Counter Control Register 0A übertragen
34
35
ldi rTemp, vConfTCCR0B ; Einstellungen für den PWM-Modus laden
36
out TCCR0B, rTemp ; und ins Timer/Counter Control Register 0B übertragen
37
38
Warte:
39
rjmp Warte ; Endlosschleife

Soweit ich es mit Hilfe der Simulation beurteilen kann, funktioniert die 
Phase Correct PWM. Bei erreichen des Vergleichswertes in OCR0B wird 
jedoch nicht wie erwartet das Bit PB1 in PortB gesetzt,sondern lediglich 
das Bit1 im PinB-Register. Liegt das eventuel an dem AVR-Simulator oder 
ist da noch ein Fehler im Programm?
Über hilfreiche Tipps würde ich mich sehr freuen.

Danke und Gruß
     Holger

von Roman W. (rom4o)


Angehängte Dateien:

Lesenswert?

Hallo Leute,
ich möchte mit dem ATtiny13 zwei Hardware-PWM Signale mit
Totzeit erzeugen.
Mit CTC oder Fast-PWM Modus ist das nicht möglich.
Ich vermute, dass man den "PWM (Phase Correct)-Modus" verwenden muss.
Nur weiss ich leider nicht wie man diesen richtig einstellt.
Ich habe auf folgender Grafik einmal illustriert wie meine PWM z.B. 
aussehen soll. -> Siehe Anhang

Im folgenden ist mein aktueller Code. Leider kommt momentan garkein 
Signal zu Stande.

Wie definiere ich die Ober- und Untergrenzen für die beiden Signale??

Vielen Dank im Voraus für eure Hilfe.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#ifndef F_CPU
4
#include <math.h>
5
#include <stdint.h>
6
#include <stdlib.h>
7
8
int main (void)
9
  {
10
  uint8_t duty=128-1;
11
  // R E G I S T E R  Definiton
12
// Bit:    7    6    5    4    3    2    1    0
13
// TCCR0A:  COM0A1  COM0A0  COM0B1  COM0B0  -    -    WGM01  WGM00
14
// TCCR0B:  FOC0A  COC0B  -    -    WGM02  CS02  CS01  CS00
15
16
//  WGM-Mode:5  (page 72)
17
    TCCR0A = 0b10100010;    // Erste beide Bits page 70
18
    TCCR0B = 0b00001001;
19
// OCR0A(the COM0B0, COM0B1 control OCR0B)
20
        OCR0A = (121-1);    // entspricht dem TOP-Wert
21
      OCR0B = (121-1);      //Seite 70 & 74
22
TIMSK0=0b00001110;
23
//TIMSK0 |= (1 << TOIE0);
24
TIFR0 =0b00000010;
25
//TIFR0 =  (1<<TOV0); 
26
27
  TCNT0 = 0;
28
  sei();
29
30
      while(1)             // Endlosschleife
31
      {
32
    //refresh PWM value
33
        //  PWM-Duty-Cycle an Ausgang PB0
34
              //  OCR0A = (255) == 100% Duty
35
              //  OCR0A = (128-1) == 50% Duty
36
          //  OCR0A = (0) == 0% Duty
37
      }
38
  return 0;
39
}

von Roman W. (rom4o)


Lesenswert?

???

von Der Unwissende (Gast)


Lesenswert?

Hallo,
löse dich von deinem zusammengeschobenen PWM Bild.
Initalisiere jede PWM für sich.

Du mußt COM0A1 = 1 & COM0A0 = 0
und COM0B1 = 1 & COM0B0 = 1
Am besten selbst im Datenblatt einmal nachvollziehen, hatte gerade 
ATtiny4,5,9,10 Datenblatt hier, hoffe das stimmt mit dem 13 er soweit 
überein.

Damit erreichst du das die signale ersteinmal invertiert sind, jetzt 
mußt du nur noch OCRnA und OCRnB passend setzen. Würde dann auch Phase 
and frequency correct nehmen, weiß gerade nicht ob man Fast PWM 
invertiert machen kann, aber wenn ja wäre das wohl sogar das einfachste.

Wenn du werte raushaust, kann ich es dir vielleicht gleich noch 
exemplarisch berechnen wie die Werte zu setzen sind.

Gruß

von spess53 (Gast)


Lesenswert?

Hi

>ich möchte mit dem ATtiny13 zwei Hardware-PWM Signale mit
>Totzeit erzeugen.

Dann nimm einen passenden AVR: ATTiny26/261/461/861.

MfG Spess

von Der Unwissende (Gast)


Lesenswert?

Hallo,
da hat spess53 wohl recht, da Problem ist das du bei dem 13er immer 
beide gleich setzt, da COM01 und COM00 für beide also Kanal A und B 
bestimmen wann geschaltet wird.

Damit kannst du nur eine Verzögerung zwischen dem schalten erzielen A 
halt an und B ein bischen später an.

Wenn du bei dem 13er bleiben willst, mußt du entweder doch softwaremäßig 
nachhelfen, indem du einen PIN manuell schaltest oder an PIN etwas baust 
das dein Signal inveriert.

Finde das ganze etwas unsinnig gemacht, mir fallen mehr Anwendungen ein 
bei welcher PWM1 zu PWM2 invertiert gebraucht werden kann, als das beide 
gleich bei MAX setzen oder löschen.

von Roman W. (rom4o)


Angehängte Dateien:

Lesenswert?

Hallo,
ja ich will damit eine Halbbrücke ansteuern und brauche die Totzeit. Man 
kann es wie du sagst für Vieles weiteres verwenden.

Ich habe eine PWM wie in "PrintSCR01.PNG "  zusehen ist erzeugt.
1
..
2
TCCR0A = 0b10110011;
3
TCCR0B|=(1<<CS00);
4
duty=127;
5
OCR0A=duty-10;        // blaues Signal
6
OCR0B=255-duty+10;    // gelbes Signal
7
..

Aber leider haben beide den geleichn Startwert.
Wie kann ich die Untergrenze, wie im Datenblattangegeben ist, 
definieren.
Siehe "Obergrenze-Untergrenze.PNG"
Wenn man das für beide PWM´s definieren kann, dann müsste es doch mit 
der Totzeit doch gehen. Oder habe ich da was falsch verstanden????

@ "Spess"
Ja ich habe mir das Datenblatt vom Tiny26 Seite74 angesehen. Das ist 
natürlich eine Lösung für mein Problem. Damit kann man sogar 2 
Halbbrücken ansteuern. Aber der Tiny26 hat 20Pins und ist echt klumpig. 
Ich wollte es eigentlich mit dem Tiny13 machen weil er mit 8Pins die 
Größe der Platine drastisch verkleinert. (bezogen auf die DIP-Bauformen, 
wegen Punkt- bzw. Streifenrasterplatinen)

@ "Der Unwissende": per Software könnte ich natürlich die PWMs erzeugen 
und auch die Totzeit aber dann hab ich nicht mehr die Möglichkeit 
Frequenz oder Duty über bspw. Potis zu verändern da dann im 
Programmablauf Verzögerungen entstehen.

Vielen Dank und beste Grüße

von Der Unwissende (Gast)


Lesenswert?

Das problem ist, dass was du da als Ober und Untergrenze siehst sind 
nach meiner Ansicht nur ein wechsel der Werte für OCR0X Registern. Also 
nicht die beiden markierten gehören zusammen sondern der linke mit dem 
links auf gleicher Höhe und der rechte mit dem rechts auf gleicher Höhe.

Würde für softwareseitig eine kurze Timer Interrupt routine schreiben, 
aber unschön. Am besten wäre es wenn du mit einem Transistor oder OPAMP 
einfach den A oder B Channel invertierst.

Wenn ein anderer Tiny in Frage kommt, so kann man auch einen 5er oder 
10er nehmen, wenn keine DEBUG Schnitstelle erforderlich ist.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Der Unwissende schrieb:
> Hallo,
> da hat spess53 wohl recht, da Problem ist das du bei dem 13er immer
> beide gleich setzt, da COM01 und COM00 für beide also Kanal A und B
> bestimmen wann geschaltet wird.
> (...)
> Wenn du bei dem 13er bleiben willst, mußt du entweder doch softwaremäßig
> nachhelfen, indem du einen PIN manuell schaltest oder an PIN etwas baust
> das dein Signal inveriert.

Ich würd den ATtiny85 nehmen, der ist genauso groß wie der ATtiny13, 
kann aber einiges mehr, und hat die für diesen Fall benötigten 
getrennten Register.

von Der Unwissende (Gast)


Lesenswert?

Warte, war unwissend. Gleich gibt es eine bessere Antwort.

von spess53 (Gast)


Lesenswert?

Hi

>Ich würd den ATtiny85 nehmen, der ist genauso groß wie der ATtiny13,
>kann aber einiges mehr, und hat die für diesen Fall benötigten
>getrennten Register.

Stimmt ATTiny25/45/85 haben auch einen Dead Time Generator.

MfG Spess

von Roman W. (rom4o)


Lesenswert?

@ "Markus W."
Du meinst den asynchronen Modus?
Und wie programmiere ich das. Ich habe damit keine Erfahrung.

@ "Der Unwissende"
Wenn ich nur einen Kanal nehme und den folglich invertiere habe ich doch 
wieder keine Totzeit.
Und ich möchte ja gerade vermeiden noch extra externe Bauelemente 
verwenden zu müssen um die PWM zu erzeugen. Eine analoge Lösung habe ich 
bereits die ist aber vergleichsweise aufwendig.

beste Grüße

von Der Unwissende (Gast)


Lesenswert?

Hallo,
änder nur einmal in deinem Programm:

TCCR0A = 0b10110011;

in

TCCR0A = 0b1011001;

Dann nochmal kurze Rückmeldung.

von Roman W. (rom4o)


Lesenswert?

Ah okey ich habe es gefunden Seite 88 im Datenblatt ATtiny25...
Super dann werde ich mir den besorgen und es probieren.

Kann mir noch jemand erklären wie ich
TIMSK0 – Timer/Counter Interrupt Mask Register
und
TIFR0 – Timer/Counter 0 Interrupt Flag Register  (Seite 74&75-ATtiny13)

bezüglich meiner PWM benutzen kann?

@ "Der Unwissende"
Da fehlt doch nur das letzte Bit. ?!

von spess53 (Gast)


Lesenswert?

Hi

>Kann mir noch jemand erklären wie ich
>TIMSK0 – Timer/Counter Interrupt Mask Register
>und
>TIFR0 – Timer/Counter 0 Interrupt Flag Register  (Seite 74&75-ATtiny13)

>bezüglich meiner PWM benutzen kann?

Wozu? Die PWM läuft auch ohne Interrupts.

MfG Spess

von Der Unwissende (Gast)


Lesenswert?

UPPS,

meine natürlich:

TCCR0A = 0b10110001;

sorry

von Roman W. (rom4o)


Angehängte Dateien:

Lesenswert?

@ Der Unwissende
SUPER. Das läuft! Schau mal den PrintScreen an.
1
  TCCR0A = 0b10110001;  //PWM-Modus 1
2
  TCCR0B|=(1<<CS00);
3
  duty=127;
4
  OCR0A=duty-10;
5
  OCR0B=255-duty+10;
Das ist der PWM-Modus 1. Komisch, mit Modus 5 kommt nichts.
So kann ich die Halbbrücke schon mal ansteuern.
Das Problem ist nun leider, dass ich mit ca. 60kHz takten möchte aber in 
dem Modus ist die maximale Frequenz 19.12Khz. Hmmm.

@ spess53
Ja ich weiss aber wie kann ich so ein Interrupt bspw. nutzen?
Und wie würde ich das programmieren.

Danke sehr und beste Grüße

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Roman W. schrieb:
> Ah okey ich habe es gefunden Seite 88 im Datenblatt ATtiny25...
> Super dann werde ich mir den besorgen und es probieren.

Schau nicht nur nach dem ATtiny25, oft ist der ATtiny45 oder ATtiny85 
billiger.

von Roman W. (rom4o)


Lesenswert?

Bei Reichelt

ATTINY 25-20 PU :: Atmel AVR-RISC-Controller, DIP-8   = 1,15 EUR
ATTINY 25V-10 PU :: Atmel AVR-RISC-Controller, DIP-8  = 1,90 EUR
ATTINY 45-20PU :: Atmel AVR-RISC-Controller           = 1,60 EUR
ATTINY 85-20 PU :: Atmel AVR-RISC-Controller          = 1,85 EUR

Stimmt nicht ganz, aber was ist so toll an dem "ATTINY 25V-10 PU"
der ist teurer und kann nur mit 10MHz betrieben werden?

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Roman W. schrieb:
> Bei Reichelt
>
> ATTINY 25-20 PU :: Atmel AVR-RISC-Controller, DIP-8   = 1,15 EUR
> ATTINY 25V-10 PU :: Atmel AVR-RISC-Controller, DIP-8  = 1,90 EUR
> ATTINY 45-20PU :: Atmel AVR-RISC-Controller           = 1,60 EUR
> ATTINY 85-20 PU :: Atmel AVR-RISC-Controller          = 1,85 EUR
>
> Stimmt nicht ganz, aber was ist so toll an dem "ATTINY 25V-10 PU"
> der ist teurer und kann nur mit 10MHz betrieben werden?

Ich hab jetzt nicht ins Datenblatt geschaut, aber ich meine mich zu 
erinnern, dass die Version mit dem V schon ab 1,8 Volt läuft und nicht 
erst ab 2,7 Volt wie die "normalen" Typen.

Google liefert dir günstigere Preise:
1
ATtiny25 0,95 Euro,
2
ATtiny85 0,90 Euro.
Aber wenn du sowieso bei Reichelt bestellst, weil du auch andere Teile 
brauchst, dann würd ich an deiner Stelle auch den ATtiny dort 
mitbestellen.

von Roman W. (rom4o)


Lesenswert?

Genau das habe ich vor. Bestelle sowieso nächste Woche bei Reichelt.
Also mit einem 20MHz Quarz komme ich mit meiner PWM auf 40kHz im 
PWM-Modus 1.
Damit kann man ja erstmal arbeiten.

Na bestens wieder ein Problem gelöst. Besten Dank an Euch.

Eventuelle Erfahrungen mit dem Tiny25 werde ich mitteilen.

Beste Grüße

von spess53 (Gast)


Lesenswert?

Hi

>Genau das habe ich vor. Bestelle sowieso nächste Woche bei Reichelt.
>Also mit einem 20MHz Quarz komme ich mit meiner PWM auf 40kHz im
>PWM-Modus 1.

Und mit dem internen RC-Oszillator+PLL auf 250kHz.

MfG Spess

von Der Unwissende (Gast)


Lesenswert?

Also, ich frage mich jetzt wieso 60 kHz (Motoransteuerung?), ich habe 
gelernt für minimale Verluste, also maximalen Wirkungsgrad meine ich 
nach möglichkeit möglichst knapp nur über die 16 kHz (Hörschwelle 
Mensch) zu gehen, wenn es keine Menschen in der Umgebeung gibt die das 
Pfeifgeräusch bei niedrigerer Frequenz stört auch noch bis glaube ich 
niedrige 1X kHz werte runter.


Zu vorherigem:
Also, wäre auch schneller drauf gekommen, wenn im Datasheet nicht ein 
Fehler gewesen wäre :(.

Da steht bei mir nämlich bei den Channel B oben groß die A Bits, während 
in der Tabellenüberschrift die B drin stehen. Ist mir erst aufgefallen, 
als ich das ganze Register mal angeschaut habe.

Ist halt nicht so flexibel wie Mode 5, der geht aber ja nicht, da bei 
OCR0A der Timer auch die Zählrichtung wechselt.

Ich entwickle gerade ein low-cost Consumer Gerät im Praxissemester und 
verwende zum ersten mal einen ATtiny, der ATtiny4 ist ja schon sehr 
günstig wenn man sich im 3-4 stelligen Mengenbereich bewegt, gerade mal 
noch 33-36 Cent bei digikey.
Zumindest aus der sicht eines unerfahrenen, der vorher versucht hat die 
Funktion über Logikbausteine zu implementieren.

von Roman W. (rom4o)


Lesenswert?

Hallo,
also wann habe ich denn gesagt, dass ich damit einen Motor ansteuern 
möchte?
Ich will eine Halbbrücke ansteuern die Bestandteil eines Schaltnetzteils 
ist.
Daher auch die hohen Schaltfrequenzen.

Der Fehler im Datenblatt ist mir auch aufgefallen, hat mich auch 
mehrmals verwirrt.

>Ist halt nicht so flexibel wie Mode 5, der geht aber ja nicht, da bei
>OCR0A der Timer auch die Zählrichtung wechselt.

Verstehe...gut erklärt, aber warum taktet er bei mir in dem Modus 
garnicht?
Ich habe jetzt gerade einen 16MHz Quarz drin nun läuft die PWM mit 
31.38kHz.

>Zumindest aus der sicht eines unerfahrenen, der vorher versucht hat die
>Funktion über Logikbausteine zu implementieren.
habe ich früher auch gemacht bis ich µC kennengerlernt habe. Mit denen 
geht es einfach viel besser schneller und platz- und energiesparender.
Aber kann ja nicht schaden wenn man beides beherrscht. :-)

grüße

von Der Unwissende (Gast)


Lesenswert?

Ah ok, ich bin von einem Motor ausgegangen, für ein Schhaltnetzteil ist 
natürlich klar Frequenz ordentlich rauf, bis die EMV dann irgendwann mal 
Probleme macht.

Nochmal warum der 5er Modus gar nichts gemacht hat:
Der Zählt rauf bis OCR0A schaltet dann um und zählt runter da dein 
OCR0B>OCR0A war, passiert gar nichts da der Wert von OCR0B nie erreicht 
wird. Bei OCR0A TOP wird der auch nicht gesschaltet.

Hoffe das war besser erklärt ;)
die ATMEL Datasheets habe ich zum Glück nicht verfasst ... aber kann ja 
mal passieren.

Zu der Logik, ich kannte aus dem Studium viel eher die µC Schiene, hat 
sich zum Controller dann auch vor allem durch doch andere Gegebenheiten 
entwickelt, als der Kunde erst verlauten lassen hat ;), aber die µC 
Variante wäre im nachhinein auch bei alten Bedingungen günstiger 
gewesen.

*Ironie an
Also, diese Kunden die mag ich an dem Job bis jetzt wirklich am meisten!
*Ironie aus

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.