AVR Tutorial 2

I have been trying to get confident with input/output code writing, but have a problem.
Here is a code snippet that works, modified from LV168Demo1.c

#include <pololu/3pi.h>
#include </usr/avr/include/avr/io.h>

void initialize()

{
	pololu_3pi_init(2000);
}
 
int main()
{
	initialize();		
	
	DDRD &= ~(1 << PD0);
	PORTD |= (1 << PD0);
	
	while(1)
	{	 
		if(PIND & (1 << PD0)) {
			left_led(0);
			set_motors(50,50);
			}			
		else			
			left_led(1);
			set_motors(0,0);		 
	}	

And here is a snippet from the AVR Tutorial which does not work.

http://elecrom.wordpress.com/2008/02/12/avr-tutorial-2-avr-input-output/

#include <mega16.h>
#include <delay.h>                       
//declare global arrays for two patterns
unsigned char p1[4] = { 0b10000001,
                        0b01000010,
                        0b00100100,
                        0b00011000 };

unsigned char p2[4] = { 0b11111111,
                        0b01111110,
                        0b00111100,
                        0b00011000 };
void main()
{
unsigned char i;                //loop counter

    DDRB = 0xFF;                //PB as output
    PORTB= 0x00;                //keep all LEDs off

    DDRC = 0x00;                //PC as input
    PORTC.0 = 1;                //enable pull ups for
    PORTC.1 = 1;                //only first two pins

    while(1)
    {
        //# if SW0 is pressed show pattern 1
        if(PINC.0==0)
        {
            for(i=0;i<3;i++)
            {
                PORTB=p1[i];    //output data
                delay_ms(300);  //wait for some time
            }
            PORTB=0;            //turn off all LEDs
        }

        //# if SW1 is pressed show pattern 2
        if(PINC.1==0)
        {
            for(i=0;i<3;i++)
            {
                PORTB=p2[i];    //output data
                delay_ms(300);  //wait for some time
            }
            PORTB=0;            //turn off all LEDs
        }

    }
}

Why can’t I use the above nomenclature in a 3pi environment, like DDRB =0x00, etc ? To me, it seems easier to use than DDRD &= ~(1 << PD0);, which I don’t fully understand.
Maybe a good tutorial on this nomenclature would be very helpful to C newbies like me.

Thanks…donde

There’s nothing wrong with the statement “DDRB=0x00” except that it sets all of the bits of DDRB to zero. In general, it’s good practice to only change the bits of a register that you really intend to, and leave the other bits alone, which might have some other important function. Even if they’re not doing anything now, you might copy-paste a bit of code into a new program later, and those sorts of bugs can be really hard to track down.

The part of your code that’s confusing to me are the lines like “PORTC.0=1”. PORTC is essentially just an eight-bit number, not a code object with attributes that are addressable like that (unless you’re using a compiler I’m unfamiliar with that supports this). There’s a discussion on how to use the various bitwise logic operators (|,&,~) to set and clear individual bits of registers without interfering with the rest of them here.

-Adam

Thanks Adam,

The link “here” helped me quite a bit to understand bitwise masking. I can now see this method is more accurate in not doing unintentional things to other bits. I think I’ll write it down in a way I can remember, till it sinks in. This is still a tough area of programming to grasp, but very powerful.

Thanks, donde

The code which had been taken from elecrom.wordpress.com blog, is written for CodeVisionAVR C Compiler. It used cutomized extension to standard ANSI C language which facilitates direct access to indivisual register bits. e.g. : PORTC.1 = 1;

This code will not work on WinAVR compiler.