Search code examples
cledatmegaatmel

LED stays on. Wont' turn on and off


So all I'm trying to do is make a function to turn on and turn off the LED which will be called into the main. The LED turns on but it doesn't turn on and off. What's wrong with my code?

I'm using ATmega328p board and Atmel Studio 6.2

#define F_CPU 16000000UL // 16MHz clock from the debug processor
#include <avr/io.h>
#include <util/delay.h>

dot();

int main()
{
    DDRB |= (1<<DDB5);
    while(1)
    {
    dot();
    }
}

int dot()
{
    PORTB |= (1<<PORTB5); // Set port bit B5 to 1 to turn on the LED
    _delay_ms(200); // delay 200mS
    PORTB |= (0<<PORTB5); // Set port bit B5 to 0 to turn on the LED
    _delay_ms(200); // delay 200mS
}

Solution

  • Read about bit-operators. a |= b sets all bits in a which are set in a or b. So if b == 0, it does not alter a.

    You need the bit-and operator after the first delay. This sets all bits which are set in a and b:

    PORTB &= ~(1U<<PORTB5);
    

    The inversion operator ~ inverts the mask, so it leaves only the relevant bit 0, all other bits are 1. So bit number PORTB5 will be cleared, all other are left unchanged.

    Note using an unsigned constant. This is in general recommended, as bit-operators and shifts are implementation defined for negative values or if the sign changes - at best and undefined behaviour at worst.