Vamos a ver cómo modificar la frecuencia a la que trabaja el PWM de Arduino UNO. Para esto es necesario cambiar la frecuencia de uno de los tres timers que posee. Cada uno de ellos controla la frecuencia de dos pines PWM y cumple una función distinta:
Timer | Pines PWM | Registro | Funciones |
Timer 0 | D5, D6 | TCCR0B | micros(), milis() y delay() |
Timer 1 | D9, D10 | TCCR1B | Servo |
Timer 2 | D3, D11 | TCCR2B | tone() |
En la columna «registro» se indica el registro cuyos tres últimos bits controlan el «prescaler» da cada timer. Sin entrar en detalle de como funciona, este prescaler nos permite ajustar la frecuencia de la señal PWM actuando como un divisor de la misma. En las siguientes tablas podemos ver los valores correspondientes. Recordar que los bits CS*2, CS*1, CS*0 corresponden a los tres bits de menor peso del registro de 8 bits.
Timer 0 – TCCR0B
CS02 | CS01 | CS00 | Divisor | Frecuencia |
0 | 0 | 0 | Parado | |
0 | 0 | 1 | 1 | 62500 Hz |
0 | 1 | 0 | 8 | 7812.50 Hz |
0 | 1 | 1 | 64 | 976.56 Hz |
1 | 0 | 0 | 256 | 244.14 Hz |
1 | 0 | 1 | 1024 | 61.04 Hz |
Timer 1 – TCCR1B
CS12 | CS11 | CS10 | Divisor | Frecuencia |
0 | 0 | 0 | Parado | |
0 | 0 | 1 | 1 | 31372,55 Hz |
0 | 1 | 0 | 8 | 3921,16 Hz |
0 | 1 | 1 | 64 | 490,20 Hz |
1 | 0 | 0 | 256 | 122,55 Hz |
1 | 0 | 1 | 1024 | 30,64 Hz |
Timer 2 – TCCR2B
CS22 | CS21 | CS20 | Divisor | Frecuencia |
0 | 0 | 0 | Parado | |
0 | 0 | 1 | 1 | 31372,55 Hz |
0 | 1 | 0 | 8 | 3921,16 Hz |
0 | 1 | 1 | 32 | 980,39 Hz |
1 | 0 | 0 | 64 | 490,20 Hz |
1 | 0 | 1 | 128 | 245,10 Hz |
1 | 1 | 0 | 256 | 122,55 Hz |
1 | 1 | 1 | 1024 | 30,64 Hz |
Ejemplo
En nuestro ejemplo nos vamos a centrar en los pines D3 y D11. ¿Por qué estos dos? Para evitar problemas innecesarios, ambos usan el timer 2 que va asociado únicamente a la función tone(). Además es el timer que más nos permite jugar con sus frecuencias.
El prescaler lo ajustaremos con la siguiente instrucción:
TCCR2B = (TCCR2B & 0b11111000) | PRESCALER2;
Donde PRESCALER2 indicara la configuración de los bits CS22, CS21 y CS20. Veamos el código del ejemplo:
const byte PRESCALER2 = 0b001;
void setup() {
TCCR2B = (TCCR2B & 0b11111000) | PRESCALER2;
pinMode(3, OUTPUT);
}
void loop() {
analogWrite(3, 128);
delay(1000);
}
Si quieres profundizar más en este tema y saber más sobre Arduino puedes echar un vistazo a mi libro.
Si quiere ver el ejemplo funcionando puedes mirar este vídeo de mi canal de Youtube:
Pingback: Arduino convertir PWM a analógico por un módico precio. | Construyendo a Chispas