ATmega1284 se comporta de forma errática

0

Mi MCU ATmega1284 parece comportarse de forma extraña de varias maneras. Lo sé, estoy loco, pero aquí va ... estoy usando un programador de bolsillo AVR con avrdude en Ubuntu Linux 15.10. Me pregunto si el MCU está fallando.

  • Si trato de usar prototipos de función con una definición de función (la función "test2"), el compilador no se queja pero parece que programa la MCU, y la MCU parece que aplica energía al azar a diferentes pines. En PORTD (por lo que he visto). No estoy siendo específico porque parece ser un problema específico.

  • Por alguna razón, cuando he intentado destellar un LED usando "_delay_ms ();" función con "avr / io.h" incluido, todo parecerá compilarse bien, pero no importa qué valor pase como parámetro, no parece hacer una diferencia en la velocidad de parpadeo del LED, ya sea 500 o 5000000. También intenté cambiar el valor de F_CPU varias veces, pero eso no cambió nada.

  • Ahora, lo que estoy tratando de hacer específicamente para las patadas, es encender un LED en una pantalla LED de 7 segmentos con un solo pin en el puerto D para comenzar, cuando tengo continuidad entre PORTB1 y tierra. Pero, de nuevo, el compilador no se queja y simplemente actúa de forma extraña. Casi no parece compilar la instrucción if a veces, y simplemente parpadeará el led único muy rápidamente, independientemente de la continuidad en PINB1. Lo sé, mi explicación es estúpida y odiaría mi explicación también si fuera tú, pero realmente no sé qué pensar.

Aquí está el código:

    #define F_CPU 6000000UL  // 6 MHz

    #include "avr/io.h"

    void test2(void);

    int main(void) {
        DDRB &= ~(1 << PINB1);
        PORTB |= 1 << PINB1;

        while (1) {
            if(bit_is_clear(PINB, 1)){
                DDRD |= (1 << PIND6);
                PORTD &= ~(1 << PIND6);
            } else {
                DDRD &= ~(1 << PIND6);
                PORTD |= (1 << PIND6);
            }
        }

        return 0;
    }

    void test2(void){
    }

Aquí está todo lo que estoy haciendo para compilar y programar el MCU:

avr-gcc -O -mmcu=atmega1284 -c main.c -o main.o

avr-objcopy -j .text -j .data -O ihex main.o main.hex

sudo avrdude -c usbtiny -p m1284 -U flash:w:main.hex

EDITAR:
Ok, no entendía cómo funcionaba F_CPU ... Gracias ... Traté de consultar la hoja de datos para ver en qué frecuencia funciona la MCU de forma predeterminada y no pude encontrarla, así que solo voy a omitir eso. hasta que lo descubra ... Aquí hay un ejemplo de algo que probé. Acabo de intentar desplegar con este código y el led parpadea rápidamente como se esperaba:

    #include <avr/io.h> // AVR IO library

    //void test(void);

    int main(void) {
        DDRD |= (1 << PIND6); // set D6 (LED) to output
        while (1) {
        PORTD ^= (1 << PIND6); // toggle D6 (LED)
        }
        return 0; // never reached
    }

    //void test(void){
    //}

Luego trato con la función prototipo y la definición sin comentar como se muestra a continuación y se mantiene constante:

    #include <avr/io.h> // AVR IO library

    void test(void);

    int main(void) {
        DDRD |= (1 << PIND6); // set D6 (LED) to output
        while (1) {
        PORTD ^= (1 << PIND6); // toggle D6 (LED)
        }
        return 0; // never reached
    }

    void test(void){
    }

Simplemente no entiendo por qué hay tanta inconsistencia allí ... Me hace pensar que hay un problema con la MCU o el compilador

actualización:
Bueno, acabo de deshacerme del AVR y obtuve un TI MSP430FR6989 y ¡es fantástico! Me encantan los instrumentos de Texas! Buena documentación, ¡todo funciona como se espera!

    
pregunta Jeff Neufeld

1 respuesta

2

Primero que nada, tu declaración

  

También he intentado cambiar el valor de F_CPU varias veces

me hace sospechar que estás malentendiendo F_CPU . Para garantizar un funcionamiento sano, F_CPU debe ser igual a la frecuencia de reloj de su MCU, es decir, no puede decir #define F_CPU 6000000UL para que la MCU funcione a 6MHz, necesita una fuente de reloj de 6MHz. ¿Estás seguro de que tu placa utiliza un reloj de 6MHz? No es la frecuencia de reloj más común (a menos que sea un teclado USB, pero estoy divagando).

Para aislar el problema, reduce un poco tu código. Un programa de parpadeo simple sin entrada sería apropiado. Además, no es necesario cambiar la dirección del puerto constantemente cuando parpadea un LED, simplemente puede configurarlo en salida y dejarlo (de hecho, esto puede estar causando algunas rarezas). Ah, y #include "avr/io.h" no parece del todo correcto, debería estar en los encabezados de la biblioteca estándar. Sugeriría el siguiente código:

#define F_CPU 6000000UL  // 6 MHz (is it really 6MHz)

#include <avr/io.h> // AVR IO library
#include <util/delay.h> // AVR busy wait delay loops

int main(void) {
    DDRD |= (1 << PIND6); // set D6 (LED) to output
    while (1) {
        PORTD ^= (1 << PIND6); // toggle D6 (LED)
        _delay_ms(250); // wait 250ms
    }
    return 0; // never reached
}

Esto es casi el código de "parpadeo" de depuración más simple que puede escribir, sin ensamblar. Trate de que esto funcione correctamente y, a continuación, a partir de ahí.

    
respondido por el uint128_t

Lea otras preguntas en las etiquetas