本帖最后由 CC2530 于 2011-3-18 17:28 编辑
主要思想是:
利用宏定义一些GPIO基本操作函数模板,
然后用模板去声明一个IO或者连续的IO区域,
那么对这个IO或者IO区域就可以使用模板内的所有函数.
且IO操作函数都是内联的,效率也非常高.
还有,没有使用的函数,也不会生成任何代码.
#ifndef __IO_AVR_ASSIGN_H__
#define __IO_AVR_ASSIGN_H__
#include "uni_int.h"
#include "iar_macro.h"
#define AVR_GPIO_ASSIGN(A, B, C) \
__always_inline__ static void GPIO_##A##_MakeOut(uint8 x) {(x)?(PORT##B |= _BV(C)):(PORT##B &= ~_BV(C)); DDR##B |= _BV(C);}\
__always_inline__ static void GPIO_##A##_MakeHighImpedance(void) {DDR##B &= ~_BV(C); PORT##B &= ~_BV(C);}\
__always_inline__ static void GPIO_##A##_MakePullup(void) {DDR##B &= ~_BV(C); PORT##B |= _BV(C);}\
__always_inline__ static void GPIO_##A##_Set(void) {PORT##B |= _BV(C);}\
__always_inline__ static void GPIO_##A##_Clr(void) {PORT##B &= ~_BV(C);}\
__always_inline__ static void GPIO_##A##_Toggle(void) {PORT##B ^= _BV(C);}\
__always_inline__ static uint8 GPIO_##A##_Read(void) {return ((PIN##B & _BV(C)) != 0);}\
__always_inline__ static uint8 GPIO_##A##_DdrRead(void) {return ((DDR##B & _BV(C)) != 0);}
#define AVR_GPIOS_ASSIGN(A, B, C, D) \
__always_inline__ static void GPIOS_##A##_MakeOut(uint8 x) {PORT##B &= ~_BVF_DATA(~x,C,D);PORT##B |= _BVF_DATA(x,C,D); DDR##B |= _BVF( C,D);}\
__always_inline__ static void GPIOS_##A##_MakeHighImpedance(void) {DDR##B &= ~_BVF( C,D);PORT##B &= ~_BVF(C,D);}\
__always_inline__ static void GPIOS_##A##_MakePullup(void) {DDR##B &= ~_BVF( C,D);PORT##B |= _BVF(C,D);}\
__always_inline__ static void GPIOS_##A##_Out(uint8 x) {PORT##B &= ~_BVF_DATA(~x,C,D);PORT##B |= _BVF_DATA(x,C,D);}\
__always_inline__ static void GPIOS_##A##_Toggle(void) {PORT##B ^= _BVF( C,D);}\
__always_inline__ static uint8 GPIOS_##A##_Read(void) {return (PIN##B & _BVF( C,D))>>C;}\
__always_inline__ static uint8 GPIOS_##A##_DdrRead(void) {return (DDR##B & _BV( C))>>C ;}
#endif
一个例子:
AVR_GPIO_ASSIGN(LED_0,B,1); //LED_0 : PB1
AVR_GPIO_ASSIGN(LED_1,B,2); //LED_1 : PB2
AVR_GPIO_ASSIGN(LED_2,B,3); //LED_2 : PB3
AVR_GPIO_ASSIGN(LED_3,B,4); //LED_3 : PB4
AVR_GPIOS_ASSIGN(LED,B,1,4); //LED,PB1到PB4(括号里最后的的4表示总共4个位)
volatile uint8 x;
int main()
{
//LED单独位初始化
GPIO_LED_0_MakeOut(0); //LED_0设置为输出,初始输出低
GPIO_LED_1_MakeOut(1); //LED_1设置为输出,初始输出高
GPIO_LED_2_MakeOut(0); //LED_2设置为输出,初始输出低
GPIO_LED_3_MakeOut(1); //LED_3设置为输出,初始输出高
//LED单独位输出
GPIO_LED_0_Set(); //LED_0输出高
GPIO_LED_0_Clr(); //LED_0输出低
GPIO_LED_0_Toggle(); //LED_0翻转
//LED单独位读取
x=GPIO_LED_0_Read(); //读取LED_0
x=GPIO_LED_0_DdrRead(); //读取LED_0方向
//LED整体初始化
GPIOS_LED_MakeOut((1<<1)|(1<<3));
//LED0,LED1,LED2,LED3设置为输出
//初始LEDLED_1,LED_3输出高,LED_0,LED_2输出低
//LED整体输出
GPIOS_LED_Out(3); //四位LED整体输出,LED0,LED1输出高,LED2,LED3输出低
GPIOS_LED_Out(12); //四位LED整体输出,LED2,LED3输出高,LED0,LED1输出低
GPIOS_LED_Toggle(); //四位LED整体翻转
//LED整体读取
x=GPIOS_LED_Read(); //读取四位LED
x=GPIOS_LED_DdrRead(); //读取四位LED方向
while(1);
} |