Main Menu
Home
AVR News
Atmel AVR
AVR Development Tools
Valuable Tools
WinAVR toolset
Makefile for WinAVR
AVR Virtual Simulators
Hardware for prototyping
GCC and AVR-GCC
Short introduction to C
AVR-GCC Tutorial
Example AVR Projects
AVR-GCC articles
WinAVR Site Map
ScienceProg BLOG
Disclaimer
WinARM Tutorial
Latest comments
Measuring motor speed and...
Dear Administrator The code above...
More...

Programming AVR ADC module...
hi please send me example usart with...
More...

Measuring motor speed and...
main.c: In function...
More...

Running TX433 and RX433 RF...
(Hopefully this is not a re-post). I am...
More...

Running TX433 and RX433 RF...
I just bnought a pair of the RX/TX 433...
More...

Friendly sites

Related Items:

Recommended sites


Accessing AVR microcontroller ports with WinAVR GCC PDF Print E-mail
Written by Administrator   
Wednesday, 06 September 2006
Last Updated ( Wednesday, 06 September 2006 )

All AVR ports have Read-modify-write functionality when used as genera I/O ports. Direction of separate port pin can be changed. Each pin buffer has symmetric capability to drive and sink source. Pin driver is strong enough to drive LED directly , but it is not recommended. All port pins have selectable pull-up resistors. All pins have protection diodes to both VCC and GND.

Each port consists of three registers DDRx, PORTx and PINx (where x means port letter). DDRx register selects direction of port pins. If logic one is written to DDRx then port is configured to be as output. Zero means that port is configured as input. If DDRx is written zero and PORTx is written logic “1” then port is configured as input with internal pull-up resistor. Otherwise if PORTx is written to zero, then port is configured as input but pins are set to tri-state and you might need to connect external pull-up resistors.

If PORTx is written to logic “1” and DDRx is set to “1”, then port pin is driven high. And if PORTx=0, then port is driven low.

Accessing AVR microcontroller ports with WinAVR GCC

Lets move to C. How we can control AVR port pins? When using WinAVR GCC first we need to set up proper library where PORT register names have their addresses defined. Main library where general purpose registers are defined is io.h located in avr directory of WINAVR installation location.


#include <avr/io.h>


Now we can use port names instead of their addresses. For instance if we want to set all pins of PORTD as output we simply write:


DDRD=0xFF; //set port D pins as outputs


Now we can output a number to port D:


PORTD=0x0F; //port pins will be set to 00001111


if we have 8 bit variable i we can assign this variable to port register like this:


uint8_t i=0x54;

PORTD=i;


Lets read port D pins:


DDRD=0; //set all port D pins as input

i=PIND; //read all 8 pin bits of port Dand store to variable i


There is ability to access separate port pins. So all eight port pins can be used for multiple purposes.

Some of the pins may be configured as outputs and some as inputs and performs different functions.

Lets say we need 0,2,4,6 pins to be as input and 1,3,5,7 as output. Then we do like this:


DDRD=0; //reset all bits to zero

DDRD |=(1<<1)|(1<<3)|(1<<5)|(1<<7); //using bit shift “<<”operation and logical OR to set bits 1,3,5,7 to “1”


So we can output values to 1,3,5 and 7 pins


PORTD |=(1<<1)|(1<<3)|(1<<5)|(1<<7);


Or clear them


PORTD &=~((1<<1)|(1<<3)|(1<<5)|(1<<7));


Reading of port pins is easy. Set any pin(s) for input like this:


DDRD &=~((1<<1)|(1<<3)); //This clears bits 1 and 3 of port direction register

i=PIND; //reads all 8 pins of port D


You can read 1 and 3 bits by using masks or simply shift i value by 1 ar 3 positions to compare LSB with 1. Of course there are some functions in sfr_defs.h library like bit_is_set() or bit_is_clear() to check particular bits and make these tasks little easier.

Following example should clarify some issues:


#include "avr\io.h"
#include "avr\iom8.h"
int main(void) {
  DDRD&=~_BV(0);//set PORTD pin0 to zero as input
  PORTD|=_BV(0);//Enable pull up
  PORTD|=_BV(1);//led OFF
  DDRD|=_BV(1);//set PORTD pin1 to one as output
  while(1) {
   if (bit_is_clear(PIND, 0))//if button is pressed
		{
			PORTD&=~_BV(1);//led ON
			loop_until_bit_is_set(PIND, 0);//LED ON while Button is pressd
			PORTD|=_BV(1);//led OFF
		}
 	}
}

 


Related Items:

   

Users' Comments  
 

Average user rating

 

Display 2 of 2 comments

Bit assigns

By: mrx23 on 29-03-2008 22:06

Hello! 
 
How can I do this with GCC?: (unsigned char) Temp.3 = PORTD.5 
Thank you!

 

» Report this comment to administrator

» Reply to this comment...

Re:Bit assigns

By: admin on 31-03-2008 23:44

You need to read PORTD 5th bit and place it as 3rd bit of variable Temp so all is about shifting. 
solution is simple: 
 
Temp=(PORTD>>2);

 

» Report this comment to administrator

» Reply to this comment...

Display 2 of 2 comments



Add your comment
Only registered users can comment an article. Please login or register.


mXcomment 1.0.6 © 2007-2010 - visualclinic.fr
License Creative Commons - Some rights reserved
< Prev

© 2010 WinAVR AVR-GCC Tutorial
Joomla! is Free Software released under the GNU/GPL License.