PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tiny 2313 wie geht 4 x PWM



vajk
24.02.2007, 14:28
Hallo,
ich grüble überm Datenblatt - da steht der 2313 kann 4 Hardware 8-Bit PWMs ...
aber ich bekomm nicht in meinen Kopp, wie ich die Register setzen muß, und an welchen Ports die dann anliegen ...

Der Tiny hat doch auch nur 1 x 8 Bit - und 1 x 16 Bit - Timer wie komme ich dann auf 4 getrennte PWM-Signale ..

.. und wenn mir das jemand beantworten kann, was ist das schnellste, was dann möglich ist bei Q=20 MHz ?

Würde mich sehr über Infos freuen,
LG
Vajk

Schokohoernl
24.02.2007, 16:09
Tach!

Der Attiny2313 hat zwei Timer mit jeweils zwei "output Compare Units". Zwei mal zwei macht laut Adam Riese und Eva Zwerg 4.
Für Timer0 miss OCR0A und OCR0B geschrieben werden. Und eben TCNT0.

Das PWM Signal liegt dann an den Pins OC0A und PC0B für Timer0 und OC1A und OC1b für Timer1 an. Wo die jetzt genau liegen musste halt im Datenblatt nachlesen, aber ich glaube die liegen alle recht dicht beieinander.

MfG

Schoko

vajk
24.02.2007, 16:49
Hmm, daß es die Pins OC0A OC0B OC1A OC1B sein sollten ist mir nun inzwischen klar,
nur aus dem DB werd ich nicht schlau, wie ich die Register für 4 x PWM setzen muß.
Auch ob Fast PWM oder Phase Correct ...
Sidn die 4 Ports dan unabhängig bis auch die selbe PWM-Frequenz?

Und dann eben, mit welchem Takt ich ohne Vorteiler rechnen kann, daß die Ports geschaltet werden ...

Schokohoernl
24.02.2007, 23:23
Da nimmste dir jetzt mal das Datenblatt vom ATtiny 2313 zur Hand und ließt da zumindest mal die Kapitel zu Timer0 und Timer1 durch. Da ist alles haargenau beschrieben. Was anderes würde ich auch nicht machen.
Wenn du dann noch Fragen hast, kannste ja gezielt fragen, was du nicht verstanden hast.

MfG

Schoko

vajk
24.02.2007, 23:57
RTFM hilft mir nicht - ich habe es gelesen.

Was ich nicht lese ist:
Wie kann ich auf die 4 PWMS zugreifen. Welche Flags muß ich hierfür setzen.
4 PWM = Fast PWM oder PhaseCorrect ...

Es gibt im Netz ein paar Tutorials, alle erklären prima PWM. Aber immer wird nur das englische Handbuch zitiert. Grummel.

Kein einziges erklärt, wie ich einen 8Bit-Timer und den 16Bit-Timer so initialisiere, daß ich jeweils zwei PWM-Signale bekomme. Und eben 4.

Und auch finde ich für diesen Fall, keine Information, wie schnell dies dann abgearbeitet werden kann, wieviel Prozessortaktzyklen dazu benötigt werden.

Schokohoernl
25.02.2007, 12:27
Hallo!

Also, erstmal glaube ich nicht, dass du das 231-Seitige Datenblatt des ATtiny2313 durchgelesen hast.

Dann glaub eich auch nicht, dass du die zwei kapitel über Timer0 und Timer1 durchgelesen hast. Da steht nämlich alles haargenau drin. welches Register wie gesetzt werden muss, wann die Output Compare Unit was macht, wie PWM invertiert wird, welches Register die Pulsweite bestimmt, welches Bit für fast PWM oder Phase Correct PWM zuständig ist, was die maximalen PWM Frequenzen sind.
Woher soll man denn sonst wissen, welche Register für was zuständig sind? Zufall? Göttliche Eingebung? Intuition?? NEIN, aus dem Dateblatt (ist auf Englisch, hat 231 Seiten und ist u.A. bei Atmel als Download erhältlich).

So... danach haste ne gute Grundlage und 90% verstanden. Die Arbeit musste dir halt mal machen. Ohne Fleiß kein Preis.

MfG
Schoko

P.S.: In welcher Sprache programmierst du?

vajk
25.02.2007, 13:10
grummel - bin halt zu doof es zu kapieren
da steht nicht explizit wie es mit 4 PWMs geht
da steht nicht, was fast und nicht fast bedeutet ...

wenn Du es so prima alles verstehst, sei doch so lieb und erklärs mir bitte.

Schokohoernl
25.02.2007, 14:28
So... jetzt mal Schritt für Schritt:


grummel - bin halt zu doof es zu kapieren

Vielleicht nicht zu doof, eher zu faul ;-)



da steht nicht explizit wie es mit 4 PWMs geht

nicht direkt. Aber die verschiedenen Register von Timer0 werden auf Seite 77ff in der "Register Description" beschrieben. Das gleich enochmal auf Seite 108ff für Timer1.


da steht nicht, was fast und nicht fast bedeutet ...

Oh doch!! Sogar mit Schaubild!! Und das sogar zweimal!! Einmal Seite 72ff und einmal Seite 100ff (da sieht man mal wieder, dass nicht die Mühe gemacht wurde, auch nur einen Blick ins Datenblatt zu werfen)



wenn Du es so prima alles verstehst, sei doch so lieb und erklärs mir bitte.

Also das Bisschen is ja nun wirklich nicht schwer.

MfG

Schoko

P.S.: Nochmal die Frage: In welcher Sprache programmierst du?? Zufällig BASIC?

vajk
25.02.2007, 15:45
@Schokohoernl
Oh lieber Lehrer, wir sind da an einer Sackgasse angekommen.
Meine Bitte: behalten Sie Ihre Mutmaßungen bitte für sich.

Sie wollen es nicht erklären und ich verstehe das Datenblatt nicht.

Und nein, ich programmiere nicht in Basic.

ogni42
25.02.2007, 20:09
Vajk, vielleicht hilft Dir ein bisschen Code weiter (ist für den Mega168). Da werden in den einzelnen Routinen jeweils die 8bit (Timer 0 und 2) sowie der 16bit Timer (Timer 1) gesetzt


void pwmInit( void )
{
// enable PWM outputs
DDRD = (1<<6) | (1<<5);

pwmWidth = 0x10;
// initialise time and pwm modes
pwmInit0();
// pwmInit1();
// pwmInit2();
}



void pwmInit0( void )
{
// 8 bit phase correct PWM
TCCR0A = (1<<COM0A1)|(1<<COM0B1)|(1<<WGM00);

// set prescaler for PWM frequency
TCCR0B = (1<<CS01); // This selects prescaler 8. fPWM = F_CPU/(510*Prescaler) = 4.52kHz@18.432MHz

// for fast initialisation (OCRxA/B values are taken on the first TCNTx = TOP)
TCNT0 = 0xfe;

// set initial PWM Width
OCR0A = pwmWidth;
OCR0B = 0x03;
}


void pwmInit1( void )
{
// 16 bit phase correct PWM
TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);

// set prescaler for PWM frequency
TCCR1B = (1<<CS11);

// for fast initialisation (OCRxA/B values are taken on the first TCNTx = TOP)
TCNT1 = 0x00fe;

// set initial PWM Width
OCR1A = (uint16_t)pwmWidth;
OCR1B = (uint16_t)0x03;
}


void pwmInit2( void )
{
// 8 bit phase correct PWM
TCCR2A = (1<<COM2B1)|(1<<WGM20);

// set prescaler for PWM frequency
TCCR2B = (1<<CS21);

// for fast initialisation (OCRxA/B values are taken on the first TCNTx = TOP)
TCNT2 = 0xfe;

// set initial PWM Width
OCR2B = pwmWidth;
}



Durch Umsetzen der entsprechenden OCRxA und OCRxB Register im Programm, kannst Du das Puls-Pausen Verhältnis ändern.

robocat
25.02.2007, 20:16
ich habe leider keinen 2313, deshalb kann ich nur vermutungen anstellen, bzw es so erklären, wie ich denke, dass es ist (so verschieden vom a8/a32 wirds wohl nicht sein, aber testen kann ichs nicht) und deine fragen kurz und klar beantworten wohl leider auch nicht.

soweit ich sehe ist "fast pwm" ein dauerndes hochzählen 8 bit (0-255), danach beginnt es wieder von vorn (single slope genannt). ab einem einstellbaren wert wird der pin low, während er ursprünglich high war, im "inverted mode" dagegen ist er beim zählbeginn low und wird danach ab einem bestimmten wert ("compare match") auf high gesetzt.

die pwm frequenz bestimmt sich hier durch µC-takt und die auflösung (256), ist bei 20MHz also 78,125kHz wenn kein prescaling verwendet wird (prescaler=1).

Phase Correct PWM Mode hat dagegen ein "dual-slope". es wird also bis 255 hochgezählt, danach wieder runter. dadurch wird die pwm frequenz halbiert, man hat aber eine höhere auflösung. beim hochzählen wird also bei einem festgelegtem wert der pin low, beim runterzählen bei diesem wert wieder high. (oder im inverted mode umgekehrt, also ursprünglich high, dann low, beim runterzählen dann wieder high.) maximale frequenz dürfte da dann bei ca 39kHz liegen.

prescaler sollte von der funktion her klar sein, die pwm-frequenz wird dementsprechend niedriger (geteilt durch den prescale faktor).

ok, so weit so schön, was nun aber konkret tun damit die pwms laufen? ab hier wird es recht ungewiss, wie gesagt ich habe noch keine erfahrungen mit dem 2313. ich versuch es mal mit fast-pwm..



; port muss als ausgang gesetzt sein

;COM0A1 und COM0B1 gesetzt, bei fast pwm bedeutet das, dass beide dazugehörigen ports beim hochzählen irgendwann auf low gehen. (tabelle 35 und 38, seite 77ff)
;WGM0 und WGM1 gesetzt für fast pwm (mode 3, tabelle 40 auf seite 79)
ldi temp, (1<<COM0A1)|(1<<COM0B1)|(1<<WGM0)|(1<<WGM1)
out TCCR0A, temp

;prescaler auf 1 (tabelle 41 seite 81)
ldi temp, (1<<CS00)
out TCCR0B, temp

;damit sollten diese beiden pwms laufen, fehlen noch werte fürs output compare match (also dem pwm wert)

ldi temp, 63 ; hier 25% pwm
out OCR0A, temp

ldi temp, 31 ; hier 12,5% pwm
out OCR0B, temp


insofern ist das recht ähnlich zu dem code in https://www.roboternetz.de/phpBB2/viewtopic.php?t=27217, nur heisst das register hier TCCR0A/B.

ich würde erstmal versuchen, diese beiden PWMs zu starten. ich kann nämlich nicht versprechen, dass das so stimmt.

timer1 ist nun ein 16bit timer, zählt also bis max. 65535. wenn das nachfolgende klappt, wird er aber hier nur im 8-bit-mode betrieben.



; port muss als ausgang gesetzt sein

;COM1A1 und COM1B1 gesetzt, bei fast pwm bedeutet das, dass beide dazugehörigen ports beim hochzählen irgendwann auf low gehen. (tabelle 44, seite 108)
;WGM10 und WGM12 gesetzt für fast pwm (mode 5, tabelle 46 auf seite 110)
ldi temp, (1<<COM1A1)|(1<<COM1B1)|(1<<WGM0)|(1<<WGM1)
out TCCR0A, temp

;prescaler auf 1 (tabelle 47 seite 111)
ldi temp, (1<<CS10)
out TCCR1B, temp

;damit sollten diese beiden pwms laufen, fehlen noch werte fürs output compare match (also dem pwm wert)

ldi temp, 127 ; hier 50% pwm
out OCR1AL, temp

ldi temp, 255 ; hier 100% pwm (quasi immer high)
out OCR1BL, temp


ob das nun so klappt? hm, kA, ehrlichgesagt. ;)
vor allem bei dem 16 bit counter bin ich nicht sicher, ob ich nicht was übersehen habe. sind halt doch verdammt viele buchstaben...

aber sobald man quasi "nen fuss in der tür hat", erschliesst sich einem das datenblatt immer leichter. man bekommt quasi bissl nen blick dafür, was wichtig ist, und wird nicht mehr so sehr von den unmengen einstellungen und ausnahmen erschlagen.

ich habe jetzt hier nur den fast pwm mode versucht umzusetzen. CTC, phase-correct etc. sind aber dann nur noch paar handgriffe.

ich finde die tabellen mit den bedeutungen der bits am wichtigsten, obwohl natürlich alles gelesen und verstanden werden sollte. aber anfangs ist man (war ich) damit schon einigermassen überfordert.

versuch es mal wie beschrieben, wenn was nicht klappt frag nochmal, vielleicht findet sich ja eine lösung. leds dranklemmen und den pwm-duty-cycle von 0-100% fahren. pins variieren je nach bauform.

vielleicht hats ja bissl weitergeholfen?

gruesse von der katze

vajk
27.02.2007, 20:13
Danke für Deinen Beitrag .. der war in jedem Fall viel hilfreicher als Dein Vorredner hier. DANKE !!!!

E-Fan
07.03.2007, 11:09
öhm vajk:

Mit Bascom (zumindest bei meiner Version) ist es überhaupt nicht möglich auf alle vier PWM-Kanäle zurückzugreifen.
Man kann aber trotzdem alles einstellen in dem die entsprechenden Werte dirkt in die Register schreibt. (zum Beispiel TCNT0 = &BMSB......LSB)
Und das steht alles im Datenblatt. Man muss halt nur nachlesen und ausprobieren. Wenn Du erwartest das man Dir all das erklärt was im Datenblatt steht bist Du zumindest aus meiner Sicht etwas auf dem Holzweg. Eine Suche im Forum hätte Dir auch geholfen weil Du mit Deinem Problem nicht der erste bist.

vajk
07.03.2007, 16:10
@e-fan ... schön wenn Du auch so fit bist, das alles aus dem Datenblatt zu entnehmen und zu verstehen. Gratulliere. Und ich habe auch im Forum gesucht und auf das 4er PWM keine Antworten gefunden! Nur das Datenblatt für eine Antwort zu zitieren ist öde.

Danke an robocat - Deine Antwort war hilfreich - Das Gute von der Katze
Die Antworten von e-fan und Schokohoernl nicht - also für die Katze
Sorry, das Wortspiel konnte ich mir grad nicht verkneifen.