Hallo zusammen,
ich hangel mich aktuell von Info zu Info, zu einem vermeintlich
einfachen Vorhaben...
Ich möchte mit einem ATtin85 eine simple PWM-Steuerung für einen 4-Pin
PC-Lüfter realisieren. Also ein 5V PWM-Signal @ 20,48KHz, welches ich
über den Duty-Cycle modulieren kann.
Ich wüsste nun gern um eure Meinung zu meinen bisherigen Überlegungen.
Aus dem Datenblatt zum ATtin85 sowie diversen Online-Tutorials habe ich
mir die Grundlagen angelesen und daraus für mich das Folgende
konstruiert.
Als ISP nutze ich den Arduino mit dem ATTiny Core von SpeceKonde.
Die 20,48KHz ergeben sich aus den Specs des Lüfters (18-30KHz) und der
Gleichung (64MHz / 16) / (199 + 1) = 20,48KHz
Ich möchte also den Timer 1 des ATtiny85 nutzen, mit 64MHz, einem
Prescaler von 16 und einem TOP-Wert von 199.
Im PLLCSR Register muss ich keine Bits setzen, da dies bereits durch den
ATTiny Core / Bootloader geschieht. Hier kann ich bereits einen Takt von
64MHz für den Timer 1 vorgeben.
Anderfalls müssten die Einstellungen hier aber wie folgt aussehen:
1
PLLCSR=_BV(PLLE);// PLL Enable
2
3
while(!(PLLCSR&_BV(PLOCK)));// PLL Lock Detector
4
5
PLLCSR=_BV(PCKE);// PCK Enable
Nun im TCCR1 die Bits für PWM1A, COM1A1 und den Prescaler setzen:
1
TCCR1=_BV(PWM1A)|_BV(COM1A1)|_BV(CS12)|_BV(CS10);
Den TOP-Wert auf 199 setzen:
1
OCR1C=199;
Nach meinem Verständnis sollten ich doch nun mit OCR1A den Duty-Cycle
zwischen 0-199 (0-100%) betimmen können, richtig?
1
OCR1A=100;// 50% Duty-Cycle
Ausgabe-Pin wäre PB1 bzw. Pin6 des ATtiny85.
Habe ich in meinen Überlegungen etwas vergessen / übersehen?
Danke für eure Hilfe!
Philipp
Hi
>Die 20,48KHz ergeben sich aus den Specs des Lüfters (18-30KHz) und der>Gleichung (64MHz / 16) / (199 + 1) = 20,48KHz
Da kommen bei mir 20kHz raus.
MfG Spess
H.Joachim S. schrieb:> Erst PLL auf 64MHz und dann wieder mit Vorteiler 16? Wozu?> Nimm doch einfach den 8MHz-Takt.
Hatte ich aus dem Datenblatt.
Aber 8MHz mit Prescaler 2 und TOP=199 im synchronen Modus sollte ebenso
funktionieren :)
> Kommen die übrigen Überlegungen zu den zu setzenden Bits hin?
Probieren geht über studieren. Bedenke, dass dein µC mehrfach
programmierbar ist. Wir sind nicht mehr in den 80er Jahren.
> Kann ich statt OCR1A = 100; auch analogWrite() nehmen
Das würde ich nicht machen. Entweder nimmt man die Mittel des
Frameworks, oder programmiert es selbst. Aber dieser Mix ist sehr
riskant. Vielleicht funktioniert das heute, aber beim nächsten Update
nicht mehr.
Hatten wir das nicht gerade erst vor ein paar Tagen? Ich erlebe gerade
ein Dejavu Gefühl.
> Dürfte doch theoretisch keinen Unterschied machen?!
Das hast du geraten, nicht wahr? Schau doch mal in den Quelltext der
Funktion rein:
1
// Right now, PWM output only works on the pins with
2
// hardware support. These are defined in the appropriate
3
// pins_*.c file. For the rest of the pins, we default
4
// to digital output.
5
voidanalogWrite(uint8_tpin,intval)
6
{
7
// We need to make sure the PWM output is enabled for those pins
8
// that support it, as we turn it off when digitally reading or
9
// writing with them. Also, make sure the pin is in output mode
10
// for consistenty with Wiring, which doesn't require a pinMode
Dieter F. schrieb:> philipp schrieb:>> (0 << REFS1)>> Bewirkt nichts ..
Na klar bewirkt das etwas: Vcc wird als Referenzspannung genutzt.
Du meinst: Er verdient Schelte, nur weil er die Initialisierung
vorbildlich übersichtlich und mit allen beteiligten Bits in den
Registern hingeschrieben hat?
Nein, dem ist nicht so! Das zahlt sich nämlich immer dann aus, wenn
man das Programm mal wiederverwenden will. Dann ist es ein Leichtes,
ohne erst in Unterlagen zu wühlen, eine andere Betriebsart einzustellen.
Dieter F. schrieb:> Nö - ein ODER mit 0 (null) bewirkt rein gar nichts.
Noch mal: Es steht nacher in dem Bit das Gleiche, wie schon vorher
drinstand. Eine Null. Das ist der Initialisierungszustand, wenn man
NICHTS macht. Aber: Da er das betreffende Bit schon in den Quelltext
aufgenommen hat, kann er später für andere Zwecke da eine Eins
reinschieben und blitzschnell die Referenzspannung umstellen.
Herr B. schrieb:> Noch mal: Es steht nacher in dem Bit das Gleiche, wie schon vorher> drinstand.
Ich nehme es zurück - habe übersehen, dass
ADMUX =
ein = ohne ODER (|) da steht.
Der Compiler nimmt die "veroderte" Zuweisung dann als Initialwert
(analog = 0b00100010), OHNE zu "verodern".
Würde ich aber trotzdem nie so machen, weil das impliziert, dass es auch
an anderer Stelle (mit ODER) so funktioniert. Ist aber vermutlich nur
mein Problem.
Wenn überhaupt (und um vollständig zu sein) würde ich
1
ADMUX=
2
(0<<REFS1)|// Sets ref. voltage to VCC, bit 1
3
(0<<REFS0)|// Sets ref. voltage to VCC, bit 0
4
(1<<ADLAR)|// left shift result
5
(0<<REFS2)|// Sets ref. voltage to VCC, bit 2
6
(0<<MUX3)|// use ADC2 for input (PB4), MUX bit 3
7
(0<<MUX2)|// use ADC2 for input (PB4), MUX bit 2
8
(1<<MUX1)|// use ADC2 for input (PB4), MUX bit 1
9
(0<<MUX0);// use ADC2 for input (PB4), MUX bit 0
schreiben, damit alle Bits in der richtigen Reihenfolge (analog
0b00100010) erkennbar sind.