AU1200 GPIO的使用

//========================================================================
//TITLE:
//    AU1200 GPIO的使用
//AUTHOR:
//    norains
//DATE:
//    Saturday  10-May-2008
//Environment:
//    VS2005 + MIPS-SDK + DBAU1200 BOARD
//========================================================================
    如果说一款CPU的精髓在于GPIO PIN,其实一点也不为过。一个工程师能否熟练操控CPU的GPIO,几乎决定了一个产品的成败。有太多的芯片,和CPU打交道的唯一方式就是GPIO。
   
    所幸的是,DBAU1200的SDK中包含了完整的GPIO驱动。相对于其它半吊子的驱动来说,不能不让我们略感欣慰。
   
    如果安装了DBAU1200 SDK Packet,那么GPIO驱动将位于:$WINCEROOT$/PLATFORM/Db1200/Drivers/Gpio。
   
    AU1200的GPIO分为两块,分别是Primary GENERAL PURPOSE I/O和Secondary GENERAL PURPOSE I/O。
   
    Secondary GENERAL PURPOSE I/O(以下简称GPIO2)的使用比较简单,无非就是设置PIN的方向(Input/Output),读取PIN的数值(1/0),用来控制那些外围芯片的EN PIN是个非常合适的选择;而Primary GENERAL PURPOSE I/O(以下简称GPIO1)就比较复杂,它是一个多功能复用PIN,具体的功能需要设置相关的寄存器。
   
   
    首先我们先看看最简单的GPIO2。
   
    GPIO2的具体介绍可以参考RMI的AU1200文档Secondary GENERAL PURPOSE I/O一节,在这里只是挑一些重点来说明。
   
    GPIO2一共有16个PIN,它的Physical Base Address为0x0 1170 0000,KSEG1 Base Address为0xB170 0000。
   
    与GPIO2的Control Register有六个,除了一个是保留的以外,真正有作用的是五个。   
   
     Offset (Note1)   Register Name           Description
       0x0000          gpio2_dir           Direction Register       
       0x0004          —                   Reserved       
       0x0008          gpio2_output        Data Output Register       
       0x000C          gpio2_pinstate      Pin State Register       
       0x0010          gpio2_inten         Interrupt Enable Register       
       0x0014          gpio2_enable        Enable Register
   
    因为涉及到寄存器的设置,所以在使用中比较简单。假如我们需要将GPIO2_0的方向设置为ouput,则代码可以如此:
   
    #define KSEG1_GPIO_BASE  0xB1700000
    #define GPIO_OFFSET  0x0000
    *((volatile unsigned long *)(KSEG1_GPIO_BASE + GPIO_OFFSET)) = 0x0001
   
   
    相对GPIO2来说,因为GPIO1是复用多功能pin,在使用中会比GPIO2要略显麻烦。
   
    GPIO1有27个PIN,每个PIN基本上都具有两个功能,而这些功能的选择是通过写入sys_pinfunc寄存器来实现的。sys_pinfunc的地址是相对于sys_base偏移0x002C,而sys_base的Physical Base Address为0x0 1190 0000,KSEG1 Base Address为0xB190 0000。

    因为篇幅关系,在这里就不将每个PIN的复用功能列出来,有兴趣的朋友可以参考RMI关于AU1200文档的Primary General Purpose I/O and Pin Functionality一节。
   
    GPIO的Control Register有七个,分别罗列如下:
   
    Offset     Register Name      Register Description 
    0x0100     sys_trioutrd       Displays the tristate/output state of GPIO[n].             
    0x0100     sys_trioutclr      Set sys_trioutclr[n] to clear and tristate the corre-
                                  sponding bit. All input pins must be tristated.  
    0x0108     sys_outputrd       Displays the output state of GPIO[n].   
    0x0108     sys_outputset      Set sys_outputset[n] to enable a high level output.   
    0x010C     sys_outputclr      Set sys_outputclr[n] to enable a low level output.
                                  Setting an output pin brings the pin out of tristate
                                  mode and enables the output.   
    0x0110     sys_pinstaterd     Displays the state of the pins.  
    0x0110     sys_pininputen     Writing to this register allows the system to use     
                                 GPIO[7:0] as external inputs to wake the processor
                                 from Sleep. This register must be written before any
                                 GPIO[7:0] signal can be used as a Sleep wakeup
                                          input source.
  
    对该Register的读写,可以参照GPIO2寄存器的读写方法。 
   
   
   
    如果在应用程序中操作GPIO,则可以很简单地通过GPIO驱动来实现。
   
    调用GPIO驱动方法大体上有两种,现在分别以这两种方法关闭SD CARD PIN功能。因为SD CARD PIN主要存在于GPIO1,所以下面的代码都是对GPIO1进行的。
   
   
    方法一:流驱动方式 

    
    因为GPIO是流驱动,所以我们可以用通用的方法来进行读写。

     int  WINAPI WinMain(    HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPTSTR    lpCmdLine,
                    
int        nCmdShow)
{

    
// 该类型数值的定义可以在GPIO.C文件中找到。
     enum  {
         IOCTL_GPIO_READSTATE 
=   0x80001000 ,   //  some arbirary base
         IOCTL_GPIO_OUTPUTSTATESET,       //  1
         IOCTL_GPIO_OUTPUTSTATECLEAR,     //  2
         IOCTL_GPIO_SETASOUTPUT,          //  3
         IOCTL_GPIO_SETASINPUT,           //  4
         IOCTL_GPIO_READTRISTATE,         //  5
         IOCTL_GPIO_SETPINFUNC,           //  6
         IOCTL_GPIO_CLEARPINFUNC,         //  7
         IOCTL_GPIO_GETPINFUNC,           //  8
         IOCTL_GPIO_SETFREQCONTROL0,      //  9 
         IOCTL_GPIO_SETFREQCONTROL1,      //  a
         IOCTL_GPIO_SETCLOCKSOURCE,       //  b
         IOCTL_GPIO2_SETDIRECTION,
         IOCTL_GPIO2_GETDIRECTION,
         IOCTL_GPIO2_GETDATAOUTPUT,
         IOCTL_GPIO2_SETDATAOUTPUT,
         IOCTL_GPIO2_GETPINSTATE
         };
    
  
// 打开设备驱动。GPIO的设备驱动为PIO,在DBAU1200 Boar中的序号为1.该设置可参考Gpio.reg文件
  HANDLE hd  =  CreateFile(TEXT( " PIO1: " ),GENERIC_READ  |  GENERIC_WRITE, 0 ,NULL,OPEN_EXISTING, 0 , 0 );
    
if (hd  ==  INVALID_HANDLE_VALUE )
    {        
        
return   0x01 ;
    }

    ULONG ulTmp;
    ULONG ulCmd;

  
// 设置GPIO1的PIN功能。
    ulCmd  =  SYS_PINFUNC_S0C;
    DeviceIoControl(
        hd,
        IOCTL_GPIO_SETPINFUNC,
        
& ulCmd,
        
sizeof (ulCmd),
        NULL,
        
0 ,
        
& ulTmp,
        NULL);


  
// 清除GPIO1的PIN功能
    ulCmd  =  SYS_PINFUNC_S0A | SYS_PINFUNC_S0B;
    DeviceIoControl(
        hd,
        IOCTL_GPIO_CLEARPINFUNC,
        
& ulCmd,
        
sizeof (ulCmd),
        NULL,
        
0 ,
        
& ulTmp,
        NULL);


  
// 关闭设备。
    CloseHandle(hd);

    
return   0 ;
    }

    采用该方法,对设备进行读写的唯一通道就是DeviceIoControl函数,通过设置参数2,可以实现不同的功能。
   

    方法二:直接调用gpio.dll
   
    这种方法比较暴力,也比较直接,但所起到的作用和方法一是一致的。

int  WINAPI WinMain(    HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPTSTR    lpCmdLine,
                    
int        nCmdShow)
{
     
//  TODO: Place code here.

    
// Initialize the function

    
    typedef HANDLE (WINAPI 
* GPIO_INIT)( void );
    GPIO_INIT GPIO_Init;

    typedef 
void  (WINAPI  * GPIO_ClOSE)(HANDLE);
    GPIO_ClOSE GPIO_Close;

    typedef BOOL (WINAPI 
* GPIO_SETPINFUNCTION)(HANDLE,ULONG);
    GPIO_SETPINFUNCTION GPIO_SetPinFunction;

    typedef BOOL (WINAPI 
* GPIO_CLEARPINFUNCTION)(HANDLE,ULONG);
    GPIO_CLEARPINFUNCTION GPIO_ClearPinFunction;

    HINSTANCE hInstDll 
=  LoadLibrary(TEXT( " GPIO.dll " ));
    
if (hInstDll  !=  NULL)
    {

    GPIO_Init 
=  (GPIO_INIT) GetProcAddress(hInstDll,TEXT( " GPIO_Init " ));   
        GPIO_Close 
=  (GPIO_ClOSE) GetProcAddress(hInstDll,TEXT( " GPIO_Close " ));
        GPIO_SetPinFunction 
=  (GPIO_SETPINFUNCTION) GetProcAddress(hInstDll,TEXT( " GPIO_SetPinFunction " ));
        GPIO_ClearPinFunction 
=  (GPIO_CLEARPINFUNCTION) GetProcAddress(hInstDll,TEXT( " GPIO_ClearPinFunction " ));

        
if ( ! GPIO_Init  ||   ! GPIO_Close  ||   ! GPIO_SetPinFunction  ||   ! GPIO_ClearPinFunction)
        {
            MessageBox(NULL,TEXT(
" The function is NULL! " ),TEXT( "" ),MB_OK);
        }
    }
    
else
    {
        MessageBox(NULL,TEXT(
" The instance of the Dll is NULL! " ),TEXT( "" ),MB_OK);
        
return   0x03 ;
    }

    HANDLE hGPIO 
=  GPIO_Init();
    
if ( ! hGPIO)
    {
        MessageBox(NULL,TEXT(
" Failed in GPIO init! " ),TEXT( "" ),MB_OK);

        
return   0x04 ;
    }

    GPIO_SetPinFunction(hGPIO,SYS_PINFUNC_S0C);
    GPIO_ClearPinFunction(hGPIO,SYS_PINFUNC_S0A
| SYS_PINFUNC_S0B);
    

    GPIO_Close(hGPIO);


    
// 释放资源
    FreeLibrary(hInstDll);

    MessageBox(NULL,TEXT(
" Succeed ! " ),TEXT( "" ),MB_OK);

    
return   0 ;
    }


 采用方法二有如下函数可以使用:
 
    PIO_Init
    PIO_Deinit
    PIO_Open
    PIO_Close
    PIO_Read
    PIO_Write
    PIO_Seek
    PIO_IOControl
    PIO_PowerDown
    PIO_PowerUp
    GPIO_SetPinOutputState
    GPIO_ClearPinOutputState
    GPIO_GetState
    GPIO_SetAsOutput
    GPIO_SetAsInput
    GPIO_GetTristate
    GPIO_ClearPinFunction
    GPIO_SetPinFunction
    GPIO_GetPinFunction
    GPIO_SetClockSourceControl
    GPIO_SetFrequencyControl0
    GPIO_SetFrequencyControl1
    GPIO_Init
    GPIO2_SetDirection
    GPIO2_GetDirection
    GPIO2_SetDataOutput
    GPIO2_GetDatatOutput
    GPIO2_GetPinState
    GPIO_Close
 
    因为GPIO1的每个PIN的功能都不相同,设置sys_pinfunc寄存器其实已经包含设置相对应PIN的意味。在au1x00.h文件中已经将这些功能用宏定义给出:
       
    #define SYS_PINFUNC_DMA  (1<<31)
    #define SYS_PINFUNC_S0A  (1<<30)
    #define SYS_PINFUNC_S1A  (1<<29)
    #define SYS_PINFUNC_LP0  (1<<28)
    #define SYS_PINFUNC_LP1  (1<<27)
    #define SYS_PINFUNC_LD16 (1<<26)
    #define SYS_PINFUNC_LD8  (1<<25)
    #define SYS_PINFUNC_LD1  (1<<24)
    #define SYS_PINFUNC_LD0  (1<<23)
    #define SYS_PINFUNC_P1A  (3<<21)
    #define SYS_PINFUNC_P1B  (1<<20)
    #define SYS_PINFUNC_FS3  (1<<19)
    #define SYS_PINFUNC_P0A  (3<<17)
    #define SYS_PINFUNC_CS  (1<<16)
    #define SYS_PINFUNC_CIM  (1<<15)
    #define SYS_PINFUNC_P1C  (1<<14)
    #define SYS_PINFUNC_U1T  (1<<12)
    #define SYS_PINFUNC_U1R  (1<<11)
    #define SYS_PINFUNC_EX1  (1<<10)
    #define SYS_PINFUNC_EX0  (1<<9)
    #define SYS_PINFUNC_U0R  (1<<8)
    #define SYS_PINFUNC_MC  (1<<7)
    #define SYS_PINFUNC_S0B  (1<<6)
    #define SYS_PINFUNC_S0C  (1<<5)
    #define SYS_PINFUNC_P0B  (1<<4)
    #define SYS_PINFUNC_U0T  (1<<3)
    #define SYS_PINFUNC_S1B  (1<<2)
   
   
    和GPIO1不同,每个GPIO2的功能都是相同或类似的,因此如果具体到设置每个PIN,则需要明确指出该PIN的序号:
   
    GPIO2_SetDataOutput(hd,0x0001); //设置GPIO2_0输出为1
   
   
    之前的代码都是在应用程序中调用,如果需要在驱动中使用则更方便,只需要在驱动中包含gpio.h文件即可。在该文件中,声明了如下函数原型:

    extern HANDLE
    GPIO_Init(
        VOID);
   
    extern VOID
    GPIO_Close(
        HANDLE);
   
    extern BOOL
    GPIO_GetPinFunction(
        HANDLE Handle,
        PULONG PinFunc);
   
    extern BOOL
    GPIO_ClearPinFunction(
        HANDLE Handle,
        ULONG PinStates);
   
    extern BOOL
    GPIO_SetPinFunction(
        HANDLE Handle,
        ULONG PinFunc);
   
    extern BOOL
    GPIO_GetTristate(
        HANDLE Handle,
        PULONG PinTristates);
   
    extern BOOL
    GPIO_SetAsOutput(
        HANDLE Handle,
        ULONG PinsToSet);
   
    extern BOOL
    GPIO_SetAsInput(
        HANDLE Handle,
        ULONG PinsToSet);
   
    extern BOOL
    GPIO_ClearPinOutputState(
        HANDLE Handle,
        ULONG PinsToClear);
   
    extern BOOL
    GPIO_SetPinOutputState(
        HANDLE Handle,
        ULONG PinsToSet);
   
    extern BOOL
    GPIO_GetState(
        HANDLE Handle,
        PULONG PinStates);
   
    extern BOOL
    GPIO_SetClockSourceControl(
        HANDLE Handle,
        ULONG   AndMask,
        ULONG   OrMask);
   
    extern BOOL
    GPIO_SetFrequencyControl1(
        HANDLE Handle,
        ULONG   AndMask,
        ULONG   OrMask);
    extern BOOL
    GPIO_SetFrequencyControl0(
        HANDLE Handle,
        ULONG   AndMask,
        ULONG   OrMask);
   
   
    extern BOOL
    GPIO2_GetPinState(
        HANDLE Handle,
        PULONG PinState
     );
   
    extern BOOL
    GPIO2_GetDirection(
        HANDLE Handle,
        PULONG Direction
     );
   
    extern BOOL
    GPIO2_SetDirection(
        HANDLE Handle,
        ULONG   AndMask,
        ULONG   OrMask
    );
   
    extern BOOL
    GPIO2_GetDatatOutput(
        HANDLE Handle,
        PULONG DataOutput
    );
   
   
    extern BOOL
    GPIO2_SetDataOutput(
        HANDLE Handle,
        ULONG  State
    );

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值