GPIOCtrl.rarHEW在创建工程的时候会生成一些文件,今天针对通用输入输出进行控制,发现由HEW生成的iodefine.h文件非常好用,先将对通用输入输出(PIO)部分的理解跟大家分享。
在iodefine.h中,通用输入输出的控制定义了两部分结构体:控制寄存器结构体st_pfc和数据寄存器结构体st_pn(n表示端口组A、B、E和F)。
1.控制寄存器结构体st_pfc
a) 结构体变量理解
控制器结构体的定义如下(以Port A为例):
union
{ /* PAIORL */
unsigned short WORD;/* Word Access */
struct {/* Byte Access */
unsigned char H;/* High */
unsigned char L; /* Low */
} BYTE;/* */
struct {/* Bit Access */
unsigned char B15:1;/* Bit 15 */
unsigned char B14:1;/* Bit 14 */
unsigned char B13:1;/* Bit 13 */
unsigned char B12:1; /* Bit 12 */
unsigned char B11:1; /* Bit 11 */
unsigned char B10:1; /* Bit 10 */
unsigned char B9 :1; /* Bit 9 */
unsigned char B8 :1; /* Bit 8 */
unsigned char B7 :1; /* Bit 7 */
unsigned char B6 :1; /* Bit 6 */
unsigned char B5 :1; /* Bit 5 */
unsigned char B4 :1; /* Bit 4 */
unsigned char B3 :1; /* Bit 3 */
unsigned char B2 :1; /* Bit 2 */
unsigned char B1 :1; /* Bit 1 */
unsigned char B0 :1; /* Bit 0 */
} BIT; /* */
} PAIORL; /* */
char wk1[8]; /* */
union { /* PACRL4 */
unsigned short WORD; /* Word Access */
struct {/* Byte Access */
unsigned char H; /* High */
unsigned char L; /* Low */
} BYTE; /* */
struct {/* Bit Access */
unsigned char :1; /* */
unsigned char PA15MD:3; /* PA15MD */
unsigned char :1; /* */
unsigned char PA14MD:3; /* PA14MD */
unsigned char :1; /* */
unsigned char PA13MD:3; /* PA13MD */
unsigned char :1; /* */
unsigned char PA12MD:3; /* PA12MD */
} BIT; /* */
} PACRL4; /* */
union { /* PACRL3 */
unsigned short WORD; /* Word Access */
struct { /* Byte Access */
unsigned char H; /* High */
unsigned char L; /* Low */
} BYTE; /* */
struct { /* Bit Access */
unsigned char :1; /* */
unsigned char PA11MD:3; /* PA11MD */
unsigned char :1; /* */
unsigned char PA10MD:3; /* PA10MD */
unsigned char :1; /* */
unsigned char PA9MD :3; /* PA9MD */
unsigned char :1; /* */
unsigned char PA8MD :3; /* PA8MD */
} BIT; /* */
} PACRL3; /* */
union { /* PACRL2 */
unsigned short WORD; /* Word Access */
struct { /* Byte Access */
unsigned char H; /* High */
unsigned char L; /* Low */
} BYTE; /* */
struct { /* Bit Access */
unsigned char :1; /* */
unsigned char PA7MD:3; /* PA7MD */
unsigned char :1; /* */
unsigned char PA6MD:3; /* PA6MD */
unsigned char :1; /* */
unsigned char PA5MD:3; /* PA5MD */
unsigned char :1; /* */
unsigned char PA4MD:3; /* PA4MD */
} BIT; /* */
} PACRL2; /* */
union {/* PACRL1 */
unsigned short WORD; /* Word Access */
struct { /* Byte Access */
unsigned char H; /* High */
unsigned char L; /* Low */
} BYTE; /* */
struct { /* Bit Access */
unsigned char :1; /* */
unsigned char PA3MD:3; /* PA3MD */
unsigned char :1; /* */
unsigned char PA2MD:3; /* PA2MD */
unsigned char :1; /* */
unsigned char PA1MD:3; /* PA1MD */
unsigned char :1; /* */
unsigned char PA0MD:3; /* PA0MD */
} BIT; /* */
} PACRL1; /* */
Ø PAIORL 输入/输出设定寄存器联合体。 由双字节变量WORD,两个单字节变量组成的结构体变量BYTE,按位定义的结构体变量BIT组成的联合体。此联合体占用16bit的空间。WORD可对Port A中所有的I/O口进行输出/输出的批量设定。BYTE可对Port A中的高8pins和低8 pins进行分开设定。而BIT可对PortA中每个I/O进行单独设定。
Ø PACRLn Port A模式设定寄存器。WORD,BYTE,BIT可对PortA中所有的I/O口进行批量设定,分组设定和单独设定。
Ø Wkl[8] 未使用到的地址空间,可以计算一下,PACRL4的偏移地址(0x110)与PAIORL(0x106)相差4个WORD,也就是8个Bytes。所以定义的wkl[8]可理解为用于计算偏移地址。
b) 用法举例
假定Port A中的第15、7口左右通用输出口。可按下面方式设定:
批量设定: PFC.PAIOL.WORD |= 0x8080://1设定为输出
分组设定:PFC.PAIOL.BYTE.H |=0x80;
PFC.PAIOL.BYTE.L |=0x80;
单独设定:PFC.PAIOL.BIT.B15 =1;
PFC.PAIOL.BIT.B7=1;
2.数据寄存器结构体st_pn
a) 结构体变量理解
控制器结构体的定义如下(以Port A为例):
struct st_pa { /* struct PA */
union { /* PADRL */
unsigned short WORD; /* Word Access */
struct { /* Byte Access */
unsigned char H; /* High */
unsigned char L; /* Low */
} BYTE; /* */
struct { /* Bit Access */
unsigned char B15:1; /* Bit 15 */
unsigned char B14:1; /* Bit 14 */
unsigned char B13:1; /* Bit 13 */
unsigned char B12:1; /* Bit 12 */
unsigned char B11:1; /* Bit 11 */
unsigned char B10:1; /* Bit 10 */
unsigned char B9 :1; /* Bit 9 */
unsigned char B8 :1; /* Bit 8 */
unsigned char B7 :1; /* Bit 7 */
unsigned char B6 :1; /* Bit 6 */
unsigned char B5 :1; /* Bit 5 */
unsigned char B4 :1; /* Bit 4 */
unsigned char B3 :1; /* Bit 3 */
unsigned char B2 :1; /* Bit 2 */
unsigned char B1 :1; /* Bit 1 */
unsigned char B0 :1; /* Bit 0 */
} BIT; /* */
} DRL; //此处省略PRL的定义
}; /* */
Ø 同理,WORD,BYTE和BIT成员变量可分别对Port A的I/O口状态进行批量设定,分组设定和单独设定。
b) 用法
假定要是PortA中的第15口输出1,第7口输出0。可按下列方式实现:
批量处理方式: PA.DRL.WORD |= 0x8000;
PA.DRL.WORD &= 0xFF7F;//不改变其他端口状态
分组设定方式:PA.DRL.BYTE.H |=0x80;
PA.DRL.BYTE.L &= 0x7F;
单独设定方式:PA.DRL.BIT.B15 = 1;
PA.DRL.BIT.B7 =0;
3.地址指向
#define PFC (*(volatile struct st_pfc *)0xFFFFD106)/* PFC Address*/
#define PA (*(volatile struct st_pa *)0xFFFFD102)/* PA Address*/
通过以上宏定义的方式将对应的寄存器基址指向对应的地址。
4.小结
这种实现方式具有以下特定:
Ø 通过结构体打包PIO模块控制和数据寄存器,程序结构严谨。
Ø 直接地址操作,程序效率高。
Ø 多种设定方式,应用灵活。
Ø 单独设定方式使程序可读性强。
此方式可借鉴到其他单片机的C语言中。用于提高程序的执行效率和代码质量。
可访问我的博客查看。http://johnny2009.spaces.eepw.com.cn/articles/article/item/68010
附件是我建立的工程,实现跑马灯。
目前在SH-Stick的小板子上初步确定可实现以下应用:I/O控制,I/O中断,定时器,时钟振荡,A/D,看门狗,串行通信(要RS232转接)。如果有实现,再share出来跟大家分享,希望跟大家共同进步!