操作GPIO的方法(在Windows CE下环境下)

时间:2011-09-04
  General Purpose Input Output (通用输入/输出)简称为GPIO,总线扩展器利用工业标准I2C、SMBus?或SPI?接口简化了I/O口的扩展。当微控制器或芯片组没有足够的I/O端口,或当系统需要采用远端串行通信或控制时,GPIO产品能够提供额外的控制和监视功能。GPIO是ARM芯片基本的输入输出通道,在ADS下操作就是一个单片机工作,直接读写其寄存器。在ARM9平台上,Windows CE系统将GPIO的实地址(例如2410的GPIO的基地址为0x56000000)映射到虚拟地址空间(GPIO对应为0xB1600000),这样,通过对这段虚拟地址空间的操作,就能够完成对GPIO或者其他片内资源的控制、输入输出工作。

  GPIO分类:硬件/嵌入开发 驱动开发/开发

  每个GPIO端口可通过软件分别配置成输入或输出。Maxim的GPIO产品线包括8端口至28端口的GPIO,提供推挽式输出或漏极开路输出。提供微型3mm x 3mm QFN封装。
  要操作一个平台的GPIO,在其对应BSP中按照基地址,找到虚拟地址,并且找到方便操作这个地址的数据结构就可以了,关键函数就是 VirtualAlloc和VirtualCopy。并且CE的方便之处就是用户态的应用程序仍然可以使用这两个函数来访问所有这些虚拟空间,对于不太复 杂的程序,甚至可以省略写驱动直接在应用程序中操作,其实在CE6之前,这些驱动也是工作在用户态的。

  GPIO的优点(端口扩展器)

  低功耗:GPIO具有更低的功率损耗(大约1μA,μC的工作电流则为100μA)。
  集成IIC从机接口:GPIO内置IIC从机接口,即使在待机模式下也能够全速工作。
  小封装:GPIO器件提供的封装尺寸 ― 3mm x 3mm QFN!
  低成本:您不用为没有使用的功能买单!
  快速上市:不需要编写额外的代码、文档,不需要任何维护工作!
  灵活的灯光控制:内置多路高分辨率的PWM输出。
  可预先确定响应时间:缩短或确定外部事件与中断之间的响应时间。
  更好的灯光效果:匹配的电流输出确保均匀的显示亮度。
  布线简单:仅需使用2条就可以组成IIC总线或3条组成SPI总线。
  于ARM 的几组GPIO引脚,功能相似,GPxCON 控制引脚功能,GPxDAT用于读写引脚数据。另外,GPxUP用于确定是否使用上拉电阻。 x为A,B,,H/J, 没有上拉电阻。

  操作Samsung S3C2410的GPIO为例,讲述这个步骤:

  1.首先在BSP中的s2410.h文件,找到虚拟地址映射以及操作GPIO的寄存器结构体(这个在自己制作一些特殊设备的BSP时,会依据需要而发生更改)
  //
  // Registers : I/O port
  //#define IOP_BASE      0xB1600000 // 0x56000000
  typedef struct  {
  unsigned int  rGPACON;  // 00
  unsigned int  rGPADAT;
  unsigned int  rPAD1[2];
  unsigned int  rGPBCON;  // 10
  unsigned int  rGPBDAT;
  unsigned int  rGPBUP;
  unsigned int  rPAD2;
  unsigned int  rGPCCON;  // 20
  unsigned int  rGPCDAT;
  unsigned int  rGPCUP;
  unsigned int  rPAD3;
  unsigned int  rGPDCON;  // 30
  unsigned int  rGPDDAT;
  unsigned int  rGPDUP;
  unsigned int  rPAD4;
  unsigned int  rGPECON;  // 40
  unsigned int  rGPEDAT;
  unsigned int  rGPEUP;
  unsigned int  rPAD5;
  unsigned int  rGPFCON;  // 50
  unsigned int  rGPFDAT;
  unsigned int  rGPFUP;
  unsigned int  rPAD6;
  unsigned int  rGPGCON;  // 60
  unsigned int  rGPGDAT;
  unsigned int  rGPGUP;
  unsigned int  rPAD7;
  unsigned int  rGPHCON;  // 70
  unsigned int  rGPHDAT;
  unsigned int  rGPHUP;
  unsigned int  rPAD8;
  unsigned int  rMISCCR;  // 80
  unsigned int  rDCKCON;
  unsigned int  rEXTINT0;
  unsigned int  rEXTINT1;
  unsigned int  rEXTINT2;  // 90
  unsigned int  rEINTFLT0;
  unsigned int  rEINTFLT1;
  unsigned int  rEINTFLT2;
  unsigned int  rEINTFLT3;  // A0
  unsigned int  rEINTMASK;
  unsigned int  rEINTPEND;
  unsigned int  rGSTATUS0;  // AC
  unsigned int  rGSTATUS1;  // B0
  unsigned int  rGSTATUS2;  // B4
  unsigned int  rGSTATUS3;  // B8
  unsigned int  rGSTATUS4;  // BC
  }IOPreg;
  将这些复制备用。
  2.在EVC中建立一个应用程序工程,由于VirtualCopy函数没有在头文件中定义,但是在coredll.lib里面提供了符号连接,所以我们这里直接添加一个函数定义就OK了。
  #ifdef __cplusplus
  extern "C"
  {
  #endif
  BOOL VirtualCopy( LPVOID, LPVOID, DWORD, DWORD );
  #ifdef __cplusplus
  }
  #endif
  同时将步骤1里面的定义复制到这里。
  3.按照驱动程序里面操作的方法在应用程序中写GPIO操作函数
  (1)定义一个寄存器结构体变量
  volatile IOPreg *v_pIOPRegs;
  (2)给这个变量分配空间并且映射到寄存器的空间上
  v_pIOPRegs = (volatile IOPreg*)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
  if (v_pIOPRegs == NULL)
  {
  DEBUGMSG (1,(TEXT("v_pIOPRegs is not allocated ")));
  return TRUE;
  }
  if (!VirtualCopy((PVOID)v_pIOPRegs, (PVOID)IOP_BASE, sizeof(IOPreg), PAGE_READWRITE|PAGE_NOCACHE)) {
  DEBUGMSG (1,(TEXT("v_pIOPRegs is not mapped ")));
  return TRUE;
  }
  DEBUGMSG (1,(TEXT("v_pIOPRegs is mapped to %x "), v_pIOPRegs));
  这3个步骤之后,对v_pIOPRegs的操作将直接和GPIO的寄存器关联
  例如:设置GPB的控制寄存器为全部Output
  v_pIOPRegs->rGPBCON=0x155555;
  设置GPB的数据寄存器输出高电平
  v_pIOPRegs->rGPBDAT=0x3FF;
 

  
上一篇:简介基于Windows CE下的注册表
下一篇:Boot Args与Driver Globals—WinCE EBOOT

免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

相关技术资料