Windows CE下操作GPIO

GPIOARM芯片的通用IO口,在不存在操作系统的情况下,可以通过C语言程序,直接读写其寄存器进行控制,这就是以前的单片机编程。在基于ARM9Windows CE系统平台下,将GPIO的实地址(例如2410GPIO的基地址为0x56000000)映射到虚拟地址空间(GPIO对应为0xB1600000),这样,通过对这段虚拟地址空间的操作,就能够完成对GPIO或者其他片内资源的控制、输入输出工作。
   
要操作一个平台的GPIO,在其对应的BSP中按照基地址,找到虚拟地址,并且找到方便操作这个地址的数据结构就可以了,关键函数就是VirtualAllocVirtualCopy。并且CE的方便之处就是用户态的应用程序仍然可以使用这两个函数来访问所有这些虚拟空间,对于不太复杂的程序,甚至可以省略写驱动直接在应用程序中操作,其实在CE6之 前,这些驱动也是工作在用户态的。

下面是S3C2410GPIO操作步骤:

1> 首先在BSP包中找到s2410.h文件,找到虚拟地址映射以及操作GPIO的寄存器结构体(这个在自己制作一些特殊设备的BSP时,会依据需要而发生更改)

——————————————————————————————————

#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> 建立一个VC的应用程序,由于VirtualCopy函数没有在头文件中定义,但是在coredll.lib里面提供了符号连接,所以我们需要在头文件里添加一个函数定义。

——————————————————————————————————

#ifdef __cplusplus

extern "C"

{

#endif

BOOL VirtualCopy( LPVOID, LPVOID, DWORD, DWORD );

#ifdef __cplusplus

}

#endif

——————————————————————————————————

    同时将第1步中的结构体定义也复制到这里。

    3> 定义一个寄存器结构体变量。

volatile IOPreg *v_pIOPRegs;

    4> 使用的时候,给这个变量分配空间并且映射到寄存器的地址上,使用完毕后相应的也要取消映射。我们这里是操作一个蜂鸣器,点击button,蜂鸣器蜂鸣一声。也就是将GPB0置高,延时,然后再将GPB0置低。

——————————————————————————————————

     v_pIOPRegs = (volatile IOPreg*)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);

     if (v_pIOPRegs == NULL)

     {

      DEBUGMSG (1,(TEXT("v_pIOPRegs is not allocated/n/r")));

      MessageBox(_T("关联失败"),NULL);

      return;

     }

     if (!VirtualCopy((PVOID)v_pIOPRegs, (PVOID)IOP_BASE, sizeof(IOPreg), PAGE_READWRITE|PAGE_NOCACHE)) {

      DEBUGMSG (1,(TEXT("v_pIOPRegs is not mapped/n/r")));

      MessageBox(_T("映射失败"),NULL);

      return;

     }

 

    v_pIOPRegs->rGPBCON &=~(0x03);

    v_pIOPRegs->rGPBCON |=0x01;

    Sleep(500);

    v_pIOPRegs->rGPBDAT |=0x01;

 

    Sleep(500);

    //v_pIOPRegs->rGPBDAT &= 0x3fe;

    v_pIOPRegs->rGPBDAT &=~ 0x01;

    if(v_pIOPRegs){                                        

    VirtualFree((PVOID)v_pIOPRegs,0,MEM_RELEASE);

    }

    v_pIOPRegs=NULL;

——————————————————————————————————



你可能感兴趣的:(数据结构,windows,工作,struct,null,button)