Gostaria de aumentar a resolução de bits PWM do Arduino Uno. Neste momento, são 8 bits que considero muito baixos. Isso é possível sem perder a capacidade de interrupções e atrasos?
Koen
EDIT Esta configuração oferece uma resolução 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;
}
}
fonte
ICR1
para0x1fff
, em seguida, sua frequência será 1953 Hz (F_CPU / (TOP + 1)) com um prescaler em 1.ICR1 = 0x03FF
e em 0 estou vendo um pulso minúsculo no osciloscópio o suficiente para acender o led. Alguma ideia?analogWrite16(pin, val)
fornece um ciclo de trabalho de (val + 1) / ICR1. Como solução alternativa, o ArduinoanalogWrite()
fazif (val == 0) digitalWrite(pin, LOW); else if (val == 255) digitalWrite(pin, HIGH);
. Mas então você não pode obter um ciclo de trabalho de 1 / ICR1 ...Com alguma calibração, você pode somar as saídas de dois canais PWM com diferentes resistores de ponderação. No extremo, você pode usar uma saída para fornecer 8 bits de resolução e escalar a outra para 1/25 de nível e adicioná-los para que o segundo canal cubra um bit de alcance e você (novamente) tenha 16 bits de resolução. Sem imenso cuidado e ajuste, tudo o que você conseguiria seria uma bagunça.
No entanto, dividindo o segundo canal por 16 ou 32, você pode adicionar vários bits extras de resolução PWM. Apenas adicionando 2 canais PWM às saídas analógicas filtradas, você adiciona um bit extra (já que o alcance potencial é dobrado para mV / bit inalterado).
Obviamente (novamente) para cada divisão adicional por 2, você obtém um pouco mais de resolução, mas isso só pode ser realizado por talvez 4, 5 ou 6 bits extras, com requisitos de precisão crescente de resistores de escala e calibração e propensão a erros mais difíceis .
Breve exemplo.
Se um PWM for reduzido para dar 0 - 255 mV em uma etapa de 1 mV, a soma de duas PWMs com amplitude igual daria uma faixa de 0 - 510 mV em etapas de 1 mV.
Se um PWM é reduzido por um fator de 32, em vez de adicionar 255 mV ao intervalo inicial de PWMs, ele adicionaria apenas 8 mV ao extremo superior (0,256.32 = 8 mV, mas a resolução seria 0,03125 (1/32) ) etapas de mV.
Embora isso possa ser alcançado puramente com a soma de resistores e a filtragem RC, o uso de um verão de ampères melhoraria bastante os resultados.
Além disso, a ondulação do PWM pode ser filtrada com um filtro RC simples, mas o uso de um opamp como buffer (ou mesmo apenas um único transistor como seguidor de emissor) forneceria a você 3 ou 5 pólos de filtragem passa-baixo e muito mais chances de obter PWM extra resolução. Eu não inspecionei a "coerência de fase" das saídas do PWM, mas espero que elas se movam em relativa trava de modo que você não obtenha a vantagem de suavizar a adição de duas formas de onda não correlacionadas.
Mais comentários podem ser feitos, se necessário. Pergunte se estiver interessado.
fonte