AVR ATmega32 - C - Se bloquea en la llamada de función

1

He tenido muchos problemas al intentar que funcione una pieza de firmware que funcionó bien anteriormente, y estoy trabajando en una copia de la placa con la que tengo problemas. Me he reducido a lo siguiente (al menos para empezar):

Este fragmento de código funciona:

#define F_CPU 8000000

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{   
   // LEDs - initial setting
   DDRC |= 0x03;                // LEDs on pins PC0 and PC1 
   PORTC &= ~(1<<0);             // LED0 OFF
   PORTC |= (1<<1);             // LED1 ON

   DDRD |= 0x30;    // PD4..5 OUT
   TCCR1A = 0xE2;   //0b11100010 (Set OC1A + Clear OC1B on compare match, )
   TCCR1B = 0x19;   //0b00011001 (WGM13:10 = 0b1110 => Fast PWM Mode, TOP = ICR1, CS12:0 = 001 => Use IO clock, no prescaling)
   OCR1A = 18;
   OCR1B = 18;      //  18 / 8000000 =  2.25 us (Output compare match value (OC1A->HIGH, OC1B->LOW)
   ICR1 = 757;      // 757 / 8000000 = 94.625us (TOP value for timer1)

   // Loop blinks LED0..1 alternately
   while(1)
   {
       PORTC = PORTC ^ 0x03;
       _delay_ms(250);
   }
}

Inicia el temporizador y emite el pulso con el tiempo especificado, y entra en el bucle de LED parpadeante.

Sin embargo, este código falla:

#define F_CPU 8000000

#include <avr/io.h>
#include <util/delay.h>

void pulse_init(void)
{   
   DDRD |= 0x30;    // PD4..5 OUT
   TCCR1A = 0xE2;   //0b11100010 (Set OC1A + Clear OC1B on compare match, )
   TCCR1B = 0x19;   //0b00011001 (WGM13:10 = 0b1110 => Fast PWM Mode, TOP = ICR1, CS12:0 = 001 => Use IO clock, no prescaling)
   OCR1A = 18;
   OCR1B = 18;      //  18 / 8000000 =  2.25 us (Output compare match value (OC1A->HIGH, OC1B->LOW)
   ICR1 = 757;      // 757 / 8000000 = 94.625us (TOP value for timer1)
}


int main(void)
{   
   // LEDs - initial setting
   DDRC |= 0x03;                // LEDs on pins PC0 and PC1 
   PORTC &= ~(1<<0);            // LED0 OFF
   PORTC |= (1<<1);         // LED1 ON

   pulse_init();

   // Loop blinks LED0..1 alternately
   while(1)
   {
       PORTC = PORTC ^ 0x03;
       _delay_ms(250);
   }
}

... son las mismas declaraciones que antes, movidas a la función pulse_init (). Cuando subo este código, el temporizador está configurado correctamente y el pulso de salida está bien, pero el programa nunca comienza a parpadear los LED en PC0.1.1.

¿Alguna idea? No es solo esta función, es parte de un programa más grande con otras funciones de inicialización y parece que cada vez que el programa ingresa a una función separada del bucle principal, no puede regresar a la función principal. No estoy tan familiarizado con C y cómo funciona en el nivel del bloque de funciones. Estoy usando Atmel Studio 7 ahora con las siguientes opciones de compilación:

-x c -funsigned-char -funsigned-bitfields -DDEBUG  -I"C:\Program Files (x86)\Atmel\Studio.0\Packs\atmel\ATmega_DFP.1.130\include"  -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -Wextra -pedantic -mmcu=atmega32 -B "C:\Program Files (x86)\Atmel\Studio.0\Packs\atmel\ATmega_DFP.1.130\gcc\dev\atmega32" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)"

pero tuve los mismos problemas con avrdude. También intenté leer el binario completo del tablero de trabajo y escribirlo en el tablero en el que estoy trabajando. Debe comunicarse con la PC a través de un USB a serie, pero no funciona. Cuando enciendo la placa, arroja unos pocos kilobytes sin sentido a la serie (el mismo sin sentido cada vez) y luego se congela, es decir, no envía el mensaje regular "Esperando comando" o responde a ningún comando.

El chip es Atmega32L8AU, cristal externo de 8MHz, LFUSE=0xFF , HFUSE=0x99 .

¿Alguna idea?

Editar: SOLUCIONADO: el firmware funciona después de cambiar el chip AVR. Resulta ser un área de memoria defectuosa en la SRAM o posiblemente algo malo con el bus SRAM / GPR. Esto fue sugerido en los comentarios a la respuesta de Maximus a continuación.

¡Gracias por toda tu ayuda!

    
pregunta Snorre O.

1 respuesta

1

¿Ha considerado las advertencias en su compilador (si las hay)?

Su problema me parece como si hubiera un problema con la función de decleración. ¿Puedes tratar de declarar la función primero encima de main y poner el cuerpo de la función en la parte inferior de main.c? ¿El problema persiste?

Además, ¿has probado el depurador de atmel studio? Si aún no lo ha hecho, intente ejecutar paso a paso. Observe los registros y vea cómo cambian.

Una pregunta más, ¿puede hacer una simple comprobación / seguimiento de errores? Por ejemplo,

#define F_CPU 8000000

#include <avr/io.h>
#include <util/delay.h>

uint8_t PROG_STATE = 0;
void Send_to_PC(uint8_t DATA);

void pulse_init(void)
{   
   PROG_STATE = 3;
   Send_to_PC(PROG_STATE);
   DDRD |= 0x30;    // PD4..5 OUT
   TCCR1A = 0xE2;   //0b11100010 (Set OC1A + Clear OC1B on compare match, )
   TCCR1B = 0x19;   //0b00011001 (WGM13:10 = 0b1110 => Fast PWM Mode, TOP = ICR1, CS12:0 = 001 => Use IO clock, no prescaling)
   OCR1A = 18;
   OCR1B = 18;      //  18 / 8000000 =  2.25 us (Output compare match value (OC1A->HIGH, OC1B->LOW)
   ICR1 = 757;      // 757 / 8000000 = 94.625us (TOP value for timer1)
}


int main(void)
{   
   PROG_STATE = 1;
   Send_to_PC(PROG_STATE);
   // LEDs - initial setting
   DDRC |= 0x03;                // LEDs on pins PC0 and PC1 
   PORTC &= ~(1<<0);            // LED0 OFF
   PORTC |= (1<<1);         // LED1 ON
   PROG_STATE = 2;
   Send_to_PC(PROG_STATE);
   pulse_init();
   PROG_STATE = 4;
   Send_to_PC(PROG_STATE);
   // Loop blinks LED0..1 alternately
   while(1)
   {
       PROG_STATE = 5;
       Send_to_PC(PROG_STATE);
       PORTC = PORTC ^ 0x03;
       _delay_ms(250);
       PROG_STATE = 6;
       Send_to_PC(PROG_STATE);
   }
}

void Send_to_PC(uint8 DATA){
//RS232 OR I2C etc
}

Tienes la idea. Si haces algo como esto, puedes observar el estado de tu programa en vivo (aparte del depurador).

Editar:

Se agregó el diagrama de bloques interno Atmega32 / 32L

    
respondido por el Maximus

Lea otras preguntas en las etiquetas