Ich möchte die PWM-Bitauflösung des Arduino Uno erhöhen. In diesem Moment ist es 8-Bit, was ich für zu niedrig halte. Ist dies möglich, ohne die Fähigkeit von Interrupts und Verzögerungen zu verlieren?
Koen
BEARBEITEN Dieses Setup liefert ein 16-Bit-Ergebnis
void setupPWM16() {
DDRB |= _BV(PB1) | _BV(PB2); /* set pins as outputs */
TCCR1A = _BV(COM1A1) | _BV(COM1B1) /* non-inverting PWM */
| _BV(WGM11); /* mode 14: fast PWM, TOP=ICR1 */
TCCR1B = _BV(WGM13) | _BV(WGM12)
| _BV(CS11); /* prescaler: clock / 8 */
ICR1 = 0xffff; /* TOP counter value (freeing OCR1A*/
}
/* Comments about the setup
Changing ICR1 will effect the amount of bits of resolution.
ICR1 = 0xffff; (65535) 16-bit resolution
ICR1 = 0x7FFF; (32767) 15-bit resolution
ICR1 = 0x3FFF; (16383) 14-bit resolution etc....
Changing the prescaler will effect the frequency of the PWM signal.
Frequency[Hz}=CPU/(ICR1+1) where in this case CPU=16 MHz
16-bit PWM will be>>> (16000000/8)/(65535+1)=30.5175Hz
*/
/* 16-bit version of analogWrite(). Works only on pins 9 and 10. */
void analogWrite16(uint8_t pin, uint16_t val)
{
switch (pin) {
case 9: OCR1A = val; break;
case 10: OCR1B = val; break;
}
}
quelle
ICR1
zu0x1fff
, dann wird Ihre Frequenz 1953 Hz (F_CPU / (TOP + 1)) mit einem Vorteiler auf 1ICR1 = 0x03FF
und bei 0 sehe ich einen winzigen Impuls auf dem Zielfernrohr, der ausreicht, um die LED zu beleuchten. Irgendwelche Ideen?analogWrite16(pin, val)
ergibt ein Tastverhältnis von (val + 1) / ICR1. Als WorkaroundanalogWrite()
tut Arduino'sif (val == 0) digitalWrite(pin, LOW); else if (val == 255) digitalWrite(pin, HIGH);
. Aber dann können Sie keinen Arbeitszyklus von 1 / ICR1 bekommen ...Mit etwas Kalibrierung können Sie die Ausgänge von zwei PWM-Kanälen mit unterschiedlichen Gewichtungswiderständen summieren. Im Extremfall könnten Sie einen Ausgang verwenden, um 8 Bit Auflösung bereitzustellen, und den anderen auf 1/256 des Pegels skalieren und hinzufügen, sodass der 2. Kanal ein Bit Reichweite abdeckt und Sie (wieder fiktiv) 16 Bit Auflösung erhalten. Ohne immense Sorgfalt und Anpassung wäre alles, was Sie bekommen würden, ein Chaos.
Durch Teilen des 2. Kanals durch 16 oder 32 können Sie jedoch mehrere zusätzliche Bits PWM-Auflösung hinzufügen. Durch Hinzufügen von 2 gefilterten analogen gefilterten PWM-Kanälen fügen Sie ein zusätzliches Bit hinzu (da der Potentialbereich für unveränderte mV / Bit verdoppelt wird).
Normalerweise (wieder) erhalten Sie für jede zusätzliche Division durch 2 eine zusätzliche Auflösung, die jedoch nur für 4, 5 oder 6 zusätzliche Bits ausgeführt werden kann, wobei die Genauigkeitsanforderungen an Skalierungswiderstände steigen und die Kalibrierung und Fehleranfälligkeit schwieriger wird .
Kurzes Beispiel.
Wenn eine PWM verkleinert wird, um beispielsweise 0 bis 255 mV in einem Schritt von 1 mV zu ergeben, würde das Summieren von zwei PWMs mit gleicher Amplitude einen Bereich von 0 bis 510 mV in Schritten von 1 mV ergeben.
Wenn eine PWM um den Faktor 32 verkleinert wird, werden anstelle des Hinzufügens von 255 mV zum anfänglichen PWM-Bereich nur 8 mV zum oberen Ende hinzugefügt (0,256,32 = 8 mV, aber die Auflösung liegt bei 0,03125 (1/32) ) mV Schritte.
Während dies möglicherweise nur durch Widerstandssummierung und RC-Filterung erreicht werden könnte, würde die Verwendung eines Operationsverstärkersommers die Ergebnisse erheblich verbessern.
Auch die PWM-Welligkeit könnte mit einem einfachen RC-Filter gefiltert werden, aber die Verwendung eines Operationsverstärkers als Puffer (oder sogar nur eines einzelnen Transistors als Emitterfolger) würde Ihnen 3 oder 5 Pole Tiefpassfilterung und eine viel bessere Chance geben, zusätzliche PWM zu erzielen Auflösung. Ich habe die "Phasenkohärenz" der PWM-Ausgänge nicht untersucht, erwarte jedoch, dass sie sich im relativen Gleichschritt bewegen, sodass Sie nicht den Glättungsvorteil erhalten, zwei unkorrelierte Wellenformen hinzuzufügen.
Bei Bedarf können weitere Kommentare abgegeben werden. Fragen Sie bei Interesse.
quelle