Descubrí un error en mi código que solo aparece si se usa la optimización avr-gcc.
¿Alguien puede explicar cuál es el problema aquí?
Soy consciente de que hay varias formas inteligentes de lograr algo de PWM, pero ese no es el punto aquí.
Juego con un LED y lo atenúo con PWM. Para hacer una corrección de gamma simple, uso una matriz predefinida con los valores correctos.
Este es el código que uso, Main contiene solo el inicio de interrupción y un ciclo 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. Se puede acceder al valor 1023 a través del índice de matriz 63.
No importa en qué valor establezca el desvanecimiento, el LED siempre está brillante, si compilo mi código con avr-gcc -Os
. Al usar avr-gcc -O0
el código funciona.
Cambiar al código no funciona incluso configurando el desvanecimiento a 63 dentro de la interrupción:
ISR(TIMER0_OVF_vect) {
fade=63;
if(counter < pwmtable_10[fade]) {
//[..]
Esto es lo que funciona:
pwmtable_10[fade]
con 1023.pwmtable_10[fade]
conpwmtable_10[63]
fade
con una nueva variable declarada directamente antes de la comparaciónPlataforma: 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
Creo que el problema está en el atributo PROGMEM que guarda la matriz const en la memoria flash. Para obtener valores, necesita un memcpy_P() más o menos. Para acceso directo intente evitar el atributo PROGMEM. pwmtable_10[fade] obtiene un valor de RAM aleatorio.
Consulte http://www.nongnu.org/avr-libc/user-manual/pgmspace.html
tom l
echox
david tweed
fade
volátiles? (@TomL. está en el camino correcto, variable incorrecta)scott seidman
echox
scott seidman
echox
scott seidman