您的位置:首页 > 其它

TCC89x的GPIO使用解说

2010-11-09 12:35 281 查看
//=====================================================================
//TITLE:
// TCC89x的GPIO使用解说
//AUTHOR:
// norains
//DATE:
// Friday 05-November-2010
//Environment:
// Windows CE 6.0
// Telechips TCC8900
//=====================================================================



当接触一款新的CPU之时,如果想了该这款CPU,那么最简单就是从GPIO开始。对于已经并不是新品的TCC89x系列来说,自然也是如此。那么,现在我们就开始,看看如何操作这个GPIO吧。



Telechips为了简化代码,特意定义了一个GPIO的结构体,其定义如下:

typedef struct _GPIO{
 volatile unsigned int GPADAT;     //   0x000  R/W  0x00000000  GPA Data Register 
 volatile unsigned int GPAEN;     //   0x004  R/W  0x00000000  GPA Output Enable Register 
 volatile unsigned int GPASET;     //   0x008  W  -  OR function on GPA Output Data 
 volatile unsigned int GPACLR;     //   0x00C  W  -  BIC function on GPA Output Data 
 volatile unsigned int GPAXOR;     //   0x010  W  -  XOR function on GPA Output Data 
 volatile unsigned int GPACD0;     //   0x014  W  0x55555555  Driver strength Control 0 on GPA Output Data 
 volatile unsigned int GPACD1;     //   0x018  W  0x00000000  Driver strength Control 1 on GPA Output Data 
 volatile unsigned int GPAPD0;     //   0x01C  W  0x55555555  Pull-Up/Down function on GPA Output Data 
 volatile unsigned int GPAPD1;     //   0x020  W  0x00000000  Pull-Up/Down function on GPA Output Data 
 volatile unsigned int GPAFN0;     //   0x024  W  0x00000000  Port Configuration on GPA Output Data 
 volatile unsigned int GPAFN1;     //   0x028  W  0x00000000  Port Configuration on GPA Output Data 
 volatile unsigned int GPAFN2;     //   0x02C  W  0x00000000  Port Configuration on GPA Output Data 
 volatile unsigned int GPAFN3;     //   0x030  W  0x00000000  Port Configuration on GPA Output Data 
 volatile unsigned int NOTDEFINE0[3];   //  0x034-0x03C     Reserved 

 //略 
}GPIO, *PGPIO;




大家都知道,寄存器是32bit,而结构体的每一项恰好也是声明为32bit,这样的好处就是,如果结构体的指针指向GPIO寄存器的初始地址,那么结构体的成员就能够和寄存器一一对应。



现在的问题就是,我们该如何获取GPIO寄存器的初始地址?查看DataSheet,如图:





可以得知GPIO寄存器的初始地址为0xF0102000。但这个地址我们不能直接使用,比如下面这句代码就会出错:

PGPIO g_pGPIO = reinterpret_cast< PGPIO >(0xF0102000);




那么,我们该如何获取这寄存器的地址呢?这时候,就需要借助于Telechips的BSP下面的tcc_allocbaseaddress函数了。该函数传入GPIO的硬件地址,然后返回一个当前进程可使用的已经印射好的虚拟内存地址。使用方式很简单,如:

g_pGPIO = (PGPIO)tcc_allocbaseaddress((unsigned int)&HwGPIO_BASE);




不过这里需要注意的是,tcc_allocbaseaddress只能在驱动函数中使用。如果你不幸地放在了应用程序,那么等待你的依然会是个错误。那么对于应用程序而言,是不是就束手无措,无法操作GPIO了呢?非也,Telechips其实也考虑到了这点。只不过,这时候需要借助于KernelIoControl函数,代码如下所示:

//申请一段虚拟内存
 PVOID pVirtualAddress = ::VirtualAlloc( 0, dwSize, MEM_RESERVE, PAGE_READWRITE);
 
 //初始化传入的形参
 UidMem uidMem;
 uidMem.dwHwBaseAddress = dwPhysicalAddress >> 8;
 uidMem.dwAllocBaseAddress = (DWORD)pVirtualAddress;
 uidMem.dwSize = dwSize;

 //通过KernelIoControl和底层通信,让虚拟内存映射到传入形参中设定的物理地址
 ::KernelIoControl(IOCTL_HAL_VIRTUALCOPY, &uidMem, sizeof(uidMem), NULL, NULL, NULL);

 // GPIO结构指针指向映射完毕的虚拟内存。
 PGPIO g_pGPIO = (PGPIO) pVirtualAddress;





初始地址获取完毕之后,我们就可以对成员变量进行操作了。

//将GPIOD9设为为GPIO功能
BITCLR(g_pGPIO->GPDFN1,Hw4|Hw5|Hw6|Hw7);

 //设置为输出模式
BITSET(g_pGPIO->GPDEN,Hw9);

//输出为HIGH
 BITSET(g_pGPIO->GPDSET,Hw9);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: