Hi, I'm new here. I am having problems reading this code, to understand what each function does as I do not have much experience with this computer programming. I hope to get an idea of this code as a base, to use it as a LED blinker to allow me to show that it can signal time.

The following code is suppose to light an LED after being switched on for 10 seconds. We are using an Atmega88 AVR Chip that will be programed.

// AVR IO memory space
#include <avr/io.h>

// Macro defn to select bit n, assuming 0 <= n <= 7
#define BIT(n) (1 << (n)) [b]//what does this do, I am unfamiliar with this call[/b]

// Delay function
void delay (unsigned char time)
{
	unsigned char t1, t2;
	unsigned int count = 0;
	for (t1 = time; t1 > 0; --t1){ [b]//this will be the timer countdown[/b]
		for (t2 = 255; t2 > 0; --t2){ [b]//why do we count down from 255 here?[/b]
			count += 1;
		}
	}
	return;
}

// Main function
int main (void)
{
	unsigned char LEDbit;
	DDRD = 0xFF; // set all PortD to output [b]I assume this is the output of the AVR port that will be used to light the LED[/b]
	LEDbit = 0;
	
	while(1){ 	// forever looped
		LEDbit += 1;
		if (LEDbit > 7) LEDbit = 0;
		// turn on LED # by writing 0 to its MCU pin
		PORTD = ~BIT(LEDbit); [b]//This is the function that I am getting confused, PORTD is probably an output variable from the io.h, but what does the ~BIT(LEDbit) do, and why the new for the LEDbit counter?[/b]
		// delay by (#) seconds
		delay(10);
	}
	return 0;
}

Thanks for the help, much appreciated

#define BIT(n) (1 << (n)) [b]//what does this do, I am unfamiliar with this call[/b]

Here's a link about bitwise operators

start quote:

// Delay function
for (t1 = time; t1 > 0; --t1){ [b]//this will be the timer countdown[/b]
    for (t2 = 255; t2 > 0; --t2){ [b]//why do we count down from 255 here?[/b]
       count += 1;

end quote.

That's a horrible way to get a delay. It's a nested loop, the outer loop will loop from time-0, the inner will just count down from 255 to 0. So the innerloop will be executed (time)times. Because a uController isn't that fast, this results in a delay.
The author of this code might want to take a look a interrupts.

DDRD = 0xFF; // set all PortD to output [b]I assume this is the output of the AVR port that will be used to light the LED

I also asssume it. Are the leds connected to portD? DDRD = Data Direction Register D , So when you put 0xFF in it, all pins on port D will be output.

start quote:

PORTD = ~BIT(LEDbit); //This is the function that I am getting confused, PORTD is probably an output variable from the io.h, but what does the ~BIT(LEDbit) do, and why the new for the LEDbit counter?

end quote.

Ok. PORTD has 8 pins on it ( 0-7) that is why the ledbit is raised to 7 and then set to 0. The ~ operator means "complement". So if bit(0) was set this will unset it. But if the bit was unset, it will set it.

So what this code will probably do: Set Led 1-7 on with on interval of (delay) then turn them off in the same order.

Next time you post code, please read this about code tags

Edited 3 Years Ago by mike_2000_17: Fixed formatting

Thanks for the help

So if I changed the main to

int main (void)
{
	unsigned char LEDbit;
	DDRD = 0x01; // set all PortDPin0 to output, thus all pins are initially set to 0
	LEDbit = 0;
	// delay by 10 seconds
	delay(10);
	PORTD = ~BIT(LEDbit);
}

This would turn on PortDPin0 LED, would the LED just stay on after the program has ended (And this program would work immediately once it has power)?

If I wanted to use the another PIN of PortD as an input (ie as a switch to initiate the code).

DDRD and PORD are read/write variables and PIND is a readonly variable, how do I read from the PIN of my choice?

Say PIN 2 is input, would the code be like

if (PORTD == BIT (1)) {
         // delay by 10 seconds
	delay(10);
	PORTD = ~BIT(LEDbit);
}

Thanks for the help

// delay by 10 seconds
delay(10);

Maybe 10 seconds, maybe not. It depends on how you've defined delay().

would the LED just stay on after the program has ended

Probably. I don't know this uController, but most controllers would do that.

how do I read from the PIN of my choice?

Just compare the entire port with a hex value:

if (PINB == 0x01) // means: if ONLY pin 1 is set (the rest 0)
if (PINB & 0x01) // means: if pin 1 is set, and don't care about the rest

the & operator:
Say you're port is 0x03 ( 00000011 ) and you want to check pin 2 ( 00000010 )( 0x02).
By using the & operator it comes to this:

00000011
00000010
------------ &
00000010

And we see that pin 2 is set!

Edited 6 Years Ago by Nick Evan: n/a

This article has been dead for over six months. Start a new discussion instead.