Descubrí un error en mi código que solo se activa si se utiliza la optimización avr-gcc.
¿Alguien puede explicar cuál es el problema aquí?
Soy consciente de que hay varias formas inteligentes de lograr algunos PWM, pero ese no es el punto aquí.
Información de fondo
Juego con un LED y lo atenúo con PWM. Para hacer una corrección gamma simple, utilizo una matriz predefinida con los valores correctos.
Código
Este es el código que uso, Main contiene solo el inicio de interrupción y un bucle while (1) vacío:
volatile size_t fade;
volatile uint16_t counter = 0;
const uint16_t PROGMEM pwmtable_10[64] = {
0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10,
11, 12, 13, 15, 17, 19, 21, 23, 26, 29, 32, 36, 40, 44, 49, 55,
61, 68, 76, 85, 94, 105, 117, 131, 146, 162, 181, 202, 225, 250,
279, 311, 346, 386, 430, 479, 534, 595, 663, 739, 824, 918, 1023
};
ISR(TIMER0_OVF_vect) {
// fade is set in the main loop or somewhere else
if(counter < pwmtable_10[fade]) {
counter=counter+1;
PORTB = 0;
} else {
counter=0;
PORTB |= RED;
}
}
Un valor de 1 da una luz muy brillante, un valor de 1023 da una luz muy tenue. El valor 1023 es accesible a través del índice de matriz 63.
El problema
No importa a qué valor establezca fade, el LED siempre está brillante, si compilo mi código con avr-gcc -Os
.
Al utilizar avr-gcc -O0
, el código funciona.
El cambio de código no funciona incluso al configurar fade a 63 dentro de la interrupción:
ISR(TIMER0_OVF_vect) {
fade=63;
if(counter < pwmtable_10[fade]) {
//[..]
Esto es lo que funciona:
- Reemplazando
pwmtable_10[fade]
con 1023. - Reemplazando
pwmtable_10[fade]
conpwmtable_10[63]
- Reemplazando
fade
con una nueva variable declarada directamente antes de la comparación
Información adicional
Plataforma: Atmega 168
% avr-gcc --version
avr-gcc (GCC) 4.8.2
Comandos para construir y flashear el código:
avr-gcc -Wall -Wextra -Os -mmcu=atmega168 -DF_CPU=16000000 -o moody.elf moody.c
avr-objcopy -j .text -j .data -O ihex moody.elf moody.hex
avrdude -b4 -c usbasp -v -p m168 -P usb -U flash:w:moody.hex