原创 基于宏定义的超强avr io口操作(向使用51单片机一样方便操作端口)

2009-5-23 19:01 6163 8 9 分类: MCU/ 嵌入式

本章重点讲述avr单片机的io口操作。很多朋友都是由51单片机走向嵌入式系统,经历了51->430 51->pic 51->avr,这样一些转换,本人粗略学了51,后直接专攻avr,为此有一些心得,和一些雕虫小技的小伎俩,希望能抛砖引玉,引发同行反思,在工作中提供举一反三后的便利。


     想像51一样,在winavr中直接写上sbit KEY1 = p1^1,


然后用下列语句扫描键盘吗??


if(KEY1==0) keyval="1";


请看下面的宏定义,其中位段的手法来源于网络,本人纯属借鉴。之后的##,宏链接符,纯属自创,


各位先行使用以下宏后,有问题直接联系本人qq21332560讨论:注明验证信息:io口


//定义新的数据类型,方便进行IO端口操作。
typedef struct
 {
    unsigned char bit0:1 ;
    unsigned char bit1:1 ;
    unsigned char bit2:1 ;
    unsigned char bit3:1 ;
    unsigned char bit4:1 ;
    unsigned char bit5:1 ;
    unsigned char bit6:1 ;
    unsigned char bit7:1 ;
}bit_field;


#define GET_BIT(adr)   (*(( volatile bit_field * )(&adr)))


////////////////////////////////////////
#define AUTOINIT 1       //自动初始化IO方向寄存器无需在初始化程序中用PORTA=0X..;形式来初始化io控制寄存器,同时也不争的证明了avr单片机的端口输入/出切换功能


#if     AUTOINIT==1


    #define PORT(m,n)   GET_BIT(DDR##m).bit##n=1;\
                       GET_BIT(PORT##m).bit##n
#else


    #define PORT(m,n)  GET_BIT(PORT##m).bit##n


#endif
////////////////////////////////////////


#if AUTOINIT==1


#define PIN(m,n) 


    (!(u08)(GET_BIT(DDR##m).bit##n=0) 


         &&\
     (u08)(GET_BIT(PORT##m).bit##n=1)


         &&\
              GET_BIT(PIN ##m).bit##n )
#else


    #define PIN(m,n)      GET_BIT(PIN##m).bit##n


#endif
 //方便直观操作 自由设定单个io口的方向
#define DRA(n)            GET_BIT(DDRA).bit##n
#define DRB(n)            GET_BIT(DDRB).bit##n
#define DRC(n)            GET_BIT(DDRC).bit##n
#define DRD(n)            GET_BIT(DDRD).bit##n
#define DDR(m,n)        GET_BIT(DDR##m).bit##n


在我们实际项目中,需要用到按键输入,继电器,SPI器件输出,


两者分别为输入,和输出之用,这时候可以方面的在各自c文件对应的.h文件中写下如下语句:


#define KEY1 PIN(C,3)//定义三个按键,使能上拉
#define KEY2 PIN(C,4)
#define KEY3 PIN(C,5)


#define SCLK_SPI  PORT(B,5)//定义spi口的两个控制引脚
#define CS_SPI      PORT(C,0)


上述PIN PORT 自动化定义的方法中,有些不足,如:在DS18B20这样的应用中,需要切换引脚的输入输出,就必须为18B20的引脚安排两套定义,


类似于:#define DS18B20_IN     PIN(A,1)


             #define DS18B20_OUT  PORT(A,1)


此外:PORT和PIN的自动化定义中,含有DDR的操作,凡是用到PIN和PORT定义过的端口的地方都需要重复DDR操作,带来冗余代码。


希望朋友们能够用得上!

文章评论1条评论)

登录后参与讨论

用户401512 2012-11-21 16:27

难道是Shine?
相关推荐阅读
用户6646 2010-06-09 16:44
Linux C中令人讨厌的段错误
作者:孙晓明,华清远见嵌入式学院讲师同学们在做练习的时候,编译完程序,执行的时候,有时会莫名的出现 “Segment fault”,即段错误,段错误是让许多C程序员都头疼的提示,因为对于这种模糊的提示...
用户6646 2010-06-09 13:06
VC6 显示行号 (无限制注册版)
make编译时出现错误, 会提示哪一行。可惜vc中不能显示行号,很是郁闷。这个插件可以显示行号,呵呵,很有用。VC显示行号插件说明-----------------------------------...
用户6646 2010-05-22 10:07
删除 nero search 的有效方法
不知道从什么时候开始,Nero多出来一个绑定的Nero Search,虽然可以不然它显示,可是他仍然会在后台占用资源。可以用以下方法解决:开始->运行,依次输入下列文字回车、确定即可(每次输一行...
用户6646 2010-04-03 08:46
2007年5月22日完成的全电控小电视(版本V2.0)
基础功能部分写了4000多行汇编,加上遥控红外部分达到了6000多行,大体介绍如下:1. 内置开关电源转换,11-37V供电;2. 全轻触操作,无机械可调器件,PWM调节亮度/色彩/背光;3.按钮有:...
用户6646 2010-03-17 09:41
三极管HFE与β的关系
hfe是三极管H参数,全称“共发射极低频小信号输出交流短路电流放大系数”,在等效四端网络中又叫“h21”。β是Ic与Ib函数关系的普遍表达式,尤其特指在晶体管基区中电流的分配关系。无论在教科书还是在应...
用户6646 2010-03-17 09:35
三极管饱和(2)
from:http://blog.ednchina.com/xcbao/10816/category.aspx本图片来自于<模拟集成电路的分析与设计>,用来表现三极管饱和时的carriers的分布。但...
我要评论
1
8
关闭 站长推荐上一条 /2 下一条