Accessing AVR microcontroller ports with WinAVR GCC
2007-01-26 11:20
435 查看
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.
[align=justify] [/align]
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.
[align=justify] [/align]
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.
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:
[align=justify] [/align]
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.
[align=justify] [/align]
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.
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
}
}
}
相关文章推荐
- Advanced PIC Microcontroller Projects in C: From USB to RTOS with the PIC 18F Series
- A PicRS232 control with a PIC microcontroller serial port
- 用AVRstudio+win_gcc生成二进制bin文件的方法
- How to setup Eclipse with WinAVR and the Eclipse plugin AVR-eclipse
- iOS Development: Proper Use of initWithNibName:bundle: Affects UITableViewController
- Multi-tasking RTOS for microprocessors with limited memory by saving only a single return address per task during context switching
- Error creating bean with name 'adminUserController': Injection of autowired dependencies failed;
- 基于GCCAVR的TLC2543读写程序----模拟SPI方式实现
- TLV5614的AVRGCC程序与调试心得
- How to compile C++ with GCC
- error: command 'gcc' failed with exit status 1 的解决办法
- ATmega16L 的中断源及在GCC中的中断名 [AVR]
- Optimizing Code with GCC
- AVR_GCC程序设计基础
- Install GCC-4.2.1 (Apple build 5666.3) with Xcode 4.2 Caius Durling - 2011-10-30 17:36:48 As of Xcode 4.2 Apple have stopped bundling GCC with it, sh
- 又是正版!Win下ffmpeg源码调试分析二(Step into ffmpeg from Opencv for bugs in debug mode with MSVC)
- No Memory Alignment with GCC
- Issue 71 - pymssql - Undefined symbols on Mac, CentOS, Redhat with pre-compiled build - A fast MS SQL Server client library for Python directly using C API instead of ODBC. It is Python DB-API 2.0 compliant. Works on Linux, *BSD, Solaris, Mac OS X and Win
- initWithRootViewController、init…
- [转]Upgrading to Async with Entity Framework, MVC, OData AsyncEntitySetController, Kendo UI, Glimpse & Generic Unit of Work Repository Framework v2.0