wince下操作GPIO口

时间:2022-03-08 18:12:33

唉,在群上问了别人,如何操作GPIO口,都不肯给点回应。

估计是这个东西别人问得多,人家也答得很多,都懒得答。

其实,也是这样,一个问题不同人重复问,也会烦躁的啦。。。。。没事,没事。等人家,不如自己动手慢慢尝试!!

把工具也带上——万用表,evc,sd卡,还有提神的东西……

于是乎进入正题,wince下操作GPE12。

下面这段是我bsp的GPIO口的数据结构,大家去bsp包找一下,就有了

#ifdef __cplusplus
extern "C" {
#endif
 BOOL VirtualCopy(LPVOID, LPVOID,DWORD,DWORD); //Don't care about this func.
#ifdef __cplusplus
}
#endif
#define IDC_WZCQCFG_STATUS_LBL_INF 6056
#define S3C2450_BASE_REG_PA_IOPORT                  0x56000000
typedef struct {
 union {
  UINT32 GPACDL;                  // Port A - offset 0
  UINT32 GPACON;                  // Port A - offset 0
 };
 union {
  UINT32 GPACDH;                  // Data
  UINT32 GPADAT;                  // Data
 };
 
    UINT32 PAD1[2];

    UINT32 GPBCON;                  // Port B - offset 0x10
    UINT32 GPBDAT;                  // Data
    UINT32 GPBUDP;                   // Pull-up disable
    UINT32 PAD2;

    UINT32 GPCCON;                  // Port C - offset 0x20
    UINT32 GPCDAT;                  // Data
    UINT32 GPCUDP;                   // Pull-up disable
    UINT32 PAD3;
   
    UINT32 GPDCON;                  // Port D - offset 0x30
    UINT32 GPDDAT;                  // Data
    UINT32 GPDUDP;                   // Pull-up disable
    UINT32 PAD4;
   
    UINT32 GPECON;                  // Port E - offset 0x40
    UINT32 GPEDAT;                  // Data
    UINT32 GPEUDP;                   // Pull-up disable
    UINT32 PAD5;                
   
    UINT32 GPFCON;                  // Port F - offset 0x50
    UINT32 GPFDAT;
    UINT32 GPFUDP;
    UINT32 PAD6;
   
    UINT32 GPGCON;                  // Port G - offset 0x60
    UINT32 GPGDAT;
    UINT32 GPGUDP;
    UINT32 PAD7;
   
    UINT32 GPHCON;                 // Port H - offset 0x70
    UINT32 GPHDAT;
    UINT32 GPHUDP;
    UINT32 PAD8;

    UINT32 MISCCR;                  // misc control reg - offset 0x80
    UINT32 DCLKCON;                 // DCLK0/1 control reg
   
    UINT32 EXTINT0;                 // external interrupt control reg 0
    UINT32 EXTINT1;                 // external interrupt control reg 1
    UINT32 EXTINT2;                 // external interrupt control reg 2
   
    UINT32 EINTFLT0;                // reserved
    UINT32 EINTFLT1;                // reserved
    UINT32 EINTFLT2;                // external interrupt filter reg 2
    UINT32 EINTFLT3;                // external interrupt filter reg 3

    UINT32 EINTMASK;                // external interrupt mask reg
    UINT32 EINTPEND;                // external interrupt pending reg

    UINT32 GSTATUS0;                // external pin status
    UINT32 GSTATUS1;                // chip ID
    UINT32 GSTATUS2;                // reset status
    UINT32 GSTATUS3;                // inform register
    UINT32 GSTATUS4;                // inform register

 UINT32 DSC0;     // C0 - added by simon
 UINT32 DSC1;
 UINT32 DSC2;
 UINT32 MSLCON;

 UINT32 GPJCON;     // D0
 UINT32 GPJDAT;
 UINT32 GPJUDP;
 UINT32 PDA9;

 UINT32 GPKCON;     // E0
 UINT32 GPKDAT;
 
 union {
 UINT32 DATAPDEN;
 UINT32 GPKUDP;
 };
 
 UINT32 PDA10;
   
 UINT32 GPLCON;     // F0
 UINT32 GPLDAT;
 UINT32 GPLUDP;
 UINT32 PDA11;

 UINT32 GPMCON;     // 100
 UINT32 GPMDAT;
 UINT32 GPMUDP;
 UINT32 PDA12;
} S3C2450_IOPORT_REG, *PS3C2450_IOPORT_REG; 

 

接下来就读取GPE口的部分代码

wince下面不能够直接操作GPIO口,必须经过虚—物映射,才行,我们应用程序就是操作虚拟地址的。

为什么这样,都是微软的错。其实,也不能乖微软,都是为了安全性着想啦。。。。

至于如何去映射物理地址,这东西我不知道如何讲,但网上很多代码,大家可以学gm一下去goole一下嘛

代码:

 volatile S3C2450_IOPORT_REG *v_pIOPRegs;
 //虚拟地址空间中申请

 v_pIOPRegs=(volatile S3C2450_IOPORT_REG*)VirtualAlloc(0,sizeof(S3C2450_IOPORT_REG),
  MEM_RESERVE,PAGE_NOACCESS);     
 if(!v_pIOPRegs){
  MessageBox(NULL,TEXT("虚拟地址空间中申请失败!"),TEXT("小蓝提示"),MB_OK);
 }
 else{
    //虚拟空间到物理的内存映射
  if(!VirtualCopy((PVOID)v_pIOPRegs,(PVOID)(S3C2450_BASE_REG_PA_IOPORT >> 8),
   sizeof(S3C2450_IOPORT_REG),PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)){
   MessageBox(NULL,TEXT("虚拟空间到物理的内存映射失败!"),TEXT("小蓝提示"),MB_OK);
  }
 }


 v_pIOPRegs->GPECON &=~(0X03<<24);//根据datasheet对GPECON的设置,将GPE12设置成input

                                                                 // 我这里是24,25都为1(即,11)的时候为input状态

 

 DWORD Gpe12;                                      //这个变量是用来存放GPEDAT的值的,原因后面讲
 //v_pIOPRegs->GPECON |= 0X01<<24;
 Sleep(2000);
 Gpe12=v_pIOPRegs->GPEDAT;// &=(0x01<<12);       

    if(((Gpe12>>12)&0x01)==0)                //读取GPE12的值,如果为0,值弹出对话框,问是否关机,否就什么都不做
 {
 if(MessageBox(NULL,L"您是否要关机?",L"关机提示",MB_YESNO|MB_ICONQUESTION)==IDYES)
 GwesPowerOffSystem();
 }
 else
 {
 MessageBox(NULL,L"高电平",L"关机提示",MB_OK); 
 }

 

 if(v_pIOPRegs){                                         //释放虚拟内存,有借有还,才有品嘛~~嘿嘿
  VirtualFree((PVOID)v_pIOPRegs,0,MEM_RELEASE);
 }
 v_pIOPRegs=NULL;

 

 

操作GPIO就这样代码就而已啦。

当然高手不愿意讲也是,这么小段东西自己弄弄就清楚啦。

但是,我觉得虽然同一个问题,但是由于每个人的基础水平都不一样,问的问题也会有差异。。。。。

希望高手,能够搭救我们这些小鸟啦!!

 

还有刚才的原因还没有讲。。。

为什么要用一个Gpe12变量呢?

其实我也不知道为什么,若我直接去操作GPEDAT移位的话,结果是无法读取我们想要的GPE12这个位的值的。

所以我将GPEDAT的值付给一个变量。我们对变量的操作是非常熟悉的,想怎么搞就怎么搞。。

 

说就说这么多啦。

欢迎大家指正一下错误,还有指导!!