Je voudrais augmenter la résolution bit PWM de l'Arduino Uno. En ce moment, c'est 8 bits que je considère comme trop bas. Est-ce possible sans perdre la possibilité d'interruptions et de retards?
Koen
EDIT Cette configuration fournit une résultance de 16 bits
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;
}
}
la source
ICR1
sur0x1fff
, alors votre fréquence sera 1953 Hz (F_CPU / (TOP + 1)) avec un pré-échelle à 1.ICR1 = 0x03FF
et à 0 je vois une petite impulsion sur la lunette suffisamment pour allumer la led. Des idées?analogWrite16(pin, val)
donne un rapport cyclique de (val + 1) / ICR1. Comme solution de contournement, Arduino leanalogWrite()
faitif (val == 0) digitalWrite(pin, LOW); else if (val == 255) digitalWrite(pin, HIGH);
. Mais alors vous ne pouvez pas obtenir un cycle d'utilisation de 1 / ICR1 ...Avec un certain étalonnage, vous pouvez additionner les sorties de deux canaux PWM avec des résistances de pondération différentes. À l'extrême, vous pouvez théoriquement utiliser une sortie pour fournir 8 bits de résolution et mettre à l'échelle l'autre au 1 / 256ème du niveau et les ajouter de sorte que le 2ème canal couvre un bit de plage et vous (encore une fois théoriquement) obtenez 16 bits de résolution. Sans grand soin et ajustement, tout ce que vous obtiendriez serait un gâchis.
Cependant, en divisant le 2e canal par 16 ou 32, vous pouvez ajouter plusieurs bits supplémentaires de résolution PWM. En ajoutant simplement 2 sorties PWM filtrées analogiques, vous ajoutez un bit supplémentaire (car la plage de potentiel est doublée pour un mV / bit inchangé).
Théoriquement (à nouveau) pour chaque division supplémentaire par 2, vous obtenez un bit de résolution supplémentaire, mais cela ne peut être effectué que pour peut-être 4 ou 5 ou 6 bits supplémentaires, avec des exigences de précision croissantes des résistances de mise à l'échelle et un étalonnage et une propension aux erreurs plus difficiles .
Bref exemple.
Si un PWM est réduit pour donner par exemple 0 - 255 mV par pas de 1 mV, la somme de deux PWM avec une amplitude égale donnerait une plage de 0 - 510 mV par pas de 1 mV.
Si un PWM est réduit d'un facteur 32, au lieu d'ajouter 255 mV à la plage PWM initiale, il n'ajouterait que 8 mV à l'extrémité supérieure (0,256,32 = 8 mV, mais la résolution serait de 0,03125 (1/32 e). ) Pas en mV.
Bien que cela puisse peut-être être réalisé uniquement avec la sommation des résistances et le filtrage RC, l'utilisation d'un ampli op été améliorerait considérablement les résultats.
De plus, l'ondulation PWM pourrait être filtrée avec un simple filtre RC, mais l'utilisation d'un ampli op comme tampon (ou même juste un seul transistor comme suiveur d'émetteur) vous donnerait 3 ou 5 pôles de filtrage passe-bas et de bien meilleures chances d'obtenir un PWM supplémentaire résolution. Je n'ai pas inspecté la "cohérence de phase" des sorties PWM mais je m'attends à ce qu'elles se déplacent en cadence relative afin que vous n'obteniez pas l'avantage de lissage d'ajouter deux formes d'onde non corrélées.
Plus de commentaires peuvent être faits si nécessaire. Demandez si vous êtes intéressé.
la source