Mi primer programa AVR C: el LED no parpadea

Creé un programa simple para ponerlo en un chip ATMega328P ( Hoja de datos ). Escribí mi primer programa en el estudio ATMEL que quería usar para hacer parpadear un LED a una velocidad de 0,5 Hz con un consumo de energía extremadamente bajo. Aquí está mi código:

/*
 * GccApplication1.c
 *
 * Created: 11/12/2017 8:56:49 PM
 * Author : Brice
 */ 

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

int main(void)
{
    clock_prescale_set(clock_div_128); //set the clock to use the 8MHz internal clock divided by 128 for an internal frequency of 250KHz, consumes 0.4mA while not sleeping.

    while (1) 
    {
        PORTD4 == 1;//Set pin 13 of the micro to high.
        _delay_ms(1000);
        PORTD4 == 0;//Set pin 13 of the micro to low;
        _delay_ms(1000);
    }
}

Lo que espero que este código le haga a este microcontrolador es activar el registro 4 de PORTD durante 1 segundo y luego apagarlo durante un segundo.

Actualmente, el PortD4 no sufrirá ningún cambio de voltaje y permanecerá conectado a tierra mientras el dispositivo esté alimentado.

¡Cualquier explicación de esto sería apreciada!

Para este caso, estoy usando la mini placa Arduino Pro para la creación de prototipos.

El pin 4 del Pro mini está conectado al ánodo común de un LED RGB, y el pin G del LED está conectado desde una resistencia de 510 ohmios a GND. He probado el cableado con un arduino que funciona, y el LED incluso se enciende a 3,3 voltios con bastante intensidad.

ingrese la descripción de la imagen aquí

¿Cómo tienes conectado el LED?
El pin 4 de @RonBeyer del Pro mini está conectado al ánodo común de un LED RGB, y el pin G del LED está conectado desde una resistencia de 510 ohmios a GND. He probado el cableado con un arduino que funciona, y el LED incluso se enciende a 3,3 voltios con bastante intensidad.
PORTD4 == 1; //CHECK IF pin 13 of the micro to high. No establece el pin 13.
¡La hoja de datos a la que se vinculó es para el ATmega32, no para el ATmega328! Estos son procesadores completamente separados. si usa la hoja de datos del 32 como referencia, lo va a tener muy difícil :-) Esta es la correcta: atmel.com/images/…
Debe habilitar las advertencias del compilador. Este código no debería haberse compilado limpiamente en ningún compilador decente.
@Lundin no lo hizo. El compilador se queja de que F_cpu no está definido.
Debería decir algo como "no se usa el cálculo de valor" y señalar los errores.

Respuestas (3)

int main(void)
{
    clock_prescale_set(clock_div_128); //set the clock to use the 8MHz internal clock divided by 128 for an internal frequency of 250KHz, consumes 0.4mA while not sleeping.

    while (1) 
    {
        PORTD4 == 1;//Set pin 13 of the micro to high.
        _delay_ms(1000);
        PORTD4 == 0;//Set pin 13 of the micro to low;
        _delay_ms(1000);
    }
}

El problema es cómo "establece" el puerto, está utilizando, ==que es un operador de comparación, no una asignación. Intente simplemente usar =.

void main()
{
    DDRD = 0xFF;         //PD as output
    PORTD= 0x00;         //keep all LEDs off

    while(1)
    {
        PORTD &= 0b11110111;       //turn LED off
        _delay_ms(500);   //wait for half second
        PORTD |= 0b00001000;       //turn LED on 
        _delay_ms(500);   //wait for half second
    }        
}

Es posible que también deba establecer la dirección del puerto en alguna parte. Haría esto configurando el DDRDto be 0b00001000, que debería configurar el pin 4 del puerto D en una salida.

Vea mi edición, puede escribirme PORTDdirectamente, mostré la forma más fácil, pero también puede hacer un poco de manipulación, comoPORTD &= ~(1 << 4)
No, lo eliminaré, fue solo un error tipográfico que no crea un error de compilación.
¿Qué significa "|="?
@KrishnShweta "O igual", es otra forma de escribir:PORTD = PORTD | 0b00001000;
Entiendo el concepto "==" y "=", pero ¿cuál es la necesidad de escribir &= y |=?
@KrishnShweta Es un método abreviado, similar a +=, ++, -=, --, etc. Es solo abreviatura, se compila de la misma manera. Personalmente me resulta más fácil de leer.
hola, ron. Cambié mi código a lo que está en la pregunta sin éxito. Voy a probar con otra placa a ver si tengo una mala.
@tuskiomi Vea esta pregunta relacionada ya que parece que puede tener un problema similar.
@RonBeyer Descubrí el problema: vea mi respuesta a continuación, pero acepto la suya porque es una solución más convencional.
@Krishn Shweta es uno de los operadores básicos. Necesitas aprender C primero. Sin el conocimiento de C no puedes programar uC
@PeterJ_01 Sé c y estoy aprendiendo c incrustado hoy en día :) En realidad, estaba preguntando cuál es el uso de eso cuando es = en lugar de == ... Mi redacción estaba mal
Hice mis programas de parpadeo de led en c incrustado, allí no usé "& |" así que me preguntaba sobre eso. @PeterJ_01

Tres problemas:

  1. Si eres delay.h, necesitas definir la velocidad de la CPU. #define F_CPU 8000000ULen tu caso.
  2. El puerto D debe configurarse como una salida configurando el bit 4 en el registro DDRD, generalmente antes del superbucle.DDRD = 0b00010000
  3. PORTD4 no es cómo accede a ese pin de puerto. Usaría PORTD, de manera similar a como demostré el registro DDRD anterior. Personalmente, reescribiría tu superloop a:

    while (1) 
    {
        PORTD ^= 0b00010000;
        _delay_ms(1000);
    }
    
^= es el xor op, ¿verdad? Además, la parte que pusiste difiere de la de Ron. Él usa el cuarto de la izquierda, ¿por qué usas el cuarto de la derecha?
@tuskiomi eso es todo
Además, ¿querría cambiar el valor de F_CPU ya que estoy usando un divisor de reloj para ahorrar energía?
@tuskiomi Establezca F_CPU en cualquier frecuencia de reloj en Hz. No me molestaría con el divisor del reloj. Los ahorros de energía a ese nivel son insignificantes.

Al final, lo único que estaba mal con el código eran las correcciones, pero el principal problema canónico de esta situación era una placa arduino defectuosa. un simple reemplazo solucionó el problema.

¿Por qué los votos negativos? Esto es lo que solucionó el problema.
No voté negativo, pero no eres lo suficientemente específico. ¿Cuáles fueron los cambios? esta no es una buena respuesta
@ laptop2d el arduino pro mini fue bloqueado. Usé uno nuevo para solucionar el problema. que no hay que entender?