原创 S3C2440-GPIO口常用函数总结

2011-6-9 01:32 2809 3 3 分类: MCU/ 嵌入式

1         总的声明

//======================================================================//

//! \总的声明:

//!     通常我们是直接使用寄存器配置GPIO口,这样做的好处是非常的直观,可读性强。

//! 但是本IO.C程序直接用指针修改寄存器,从程序本身并不能看到寄存器的名称,但如果

//! 你熟悉S3C2440的话,你就会知道这样做是对的,而且代码量很小。 

//! 比如GPIOB口,它有4个寄存器:

//!     Register    Address

//!     GPBCON      0x56000010

//!     GPBDAT      0x56000014

//!     GPBUP        0x56000018

//!     Reserved       0x5600001c

//!

//! 同样对于GPIOC口,它也有4个寄存器:   

//!     Register    Address

//!     GPCCON      0x56000020

//!     GPCDAT      0x56000024

//!     GPCUP       0x56000028

//!     Reserved    0x5600002c

//! 如果我们将GPBCONGPCCON中的某一位置1,其实在数学上的处理是一样的,所以我们就

//! 想可否只写一个函数,就可以处理所有的CON寄存器(除了GPIOA以外)

//! 所以我们就想到了直接操作指针,比如:

//! 我们 #define pGPIOB              0x56000010

//! 我们知道0x56000010GPIOB的所有寄存器的起始地址,所以如果我们要操作GPBCON的话,

//! 可以这样做:(*(volatile unsigned *)pGPIOB) = ( ( ~(0x3<<(PIN*2)) ) & (*(volatile unsigned *)pGPIOB) ) | (0x1<<(PIN*2) );//设置GPIOB的第PIN脚为输出管脚

//! 如果我们要操作GPBDAT的话,

//! 可以这样做:(*(volatile unsigned *)(pGPIOB+0x4)) = ( (~(0x1<<PIN) )& (*(volatile unsigned *)(pGPIOB+0x4)) )| (0x1<< PIN);//GPIOB的第PIN脚输出数据1

//!

//! 这里,我们并没有写寄存器的名称,但(*(volatile unsigned *)pGPIOB)代表了寄存器//!GPBCON,(*(volatile unsigned *)(pGPIOB+0x4))代表了GPBDAT

//! 这样做的好处是(重点):

//! 如果我们要将某GPIO口的某PIN配置为OUTPUT管脚,可以这样做;

//!void GPIOPinTypeOut(U32 pPORT, U8 PIN)

//!{

//!      if(pPORT == pGPIOA)

//!           rGPACON  = rGPACON =  ( ~(0x1<<(PIN)) ) & rGPACON ;

//!      else

//!      {

//!          (*(volatile unsigned *)pPORT) = ( ( ~(0x3<<(PIN*2)) ) & (*(volatile unsigned *)pPORT) ) |   (0x1<<(PIN*2) );

//!      }

//!}

//! 用指针的好处是,我们可以只用一个函数,只用一个简单的if语句就可以配置所有的

//! GPIO口为输出口,而不用写复杂的case语句。

//!

//!

//======================================================================//

  以下为一些常用的函数

2         GPIO口常用函数

2.1       设置引脚为输入类型

//******************************************************************

//

//! \Function:

//! Init the IO as input,but you can just init one by one.

//

//******************************************************************

void GPIOPinTypeIn(U32 pPORT, U8 PIN)

{

      if(pPORT == pGPIOA)

             ;

      else

      {

             (*(volatile unsigned *)pPORT) = ( ( ~(0x3<<(PIN*2)) ) & (*(volatile unsigned *)pPORT) );

      }

}

2.2       设置引脚为输出类型

//******************************************************************

//

//! \Function:

//! Init the IO as output ,but you can just init one by one.

//

//******************************************************************

 

void GPIOPinTypeOut(U32 pPORT, U8 PIN)

{

      if(pPORT == pGPIOA)

             rGPACON  = rGPACON =  ( ~(0x1<<(PIN)) ) & rGPACON ;

      else

      {

             (*(volatile unsigned *)pPORT) = ( ( ~(0x3<<(PIN*2)) ) & (*(volatile unsigned *)pPORT) ) | (0x1<<(PIN*2) );

      }

}

 

2.3       设置引脚为外部中断管脚

//******************************************************************

//

//! \Function:

//! Config the IO as Extenal interrupt pin, but you can just config one by one.

//! pGPIOF  pGPIOG

//******************************************************************

void GPIOPinTypeEINT(U32 pPORT, U8 PIN)

{

       (*(volatile unsigned *)pPORT)  = ( ( ~(0x3<<(PIN*2)) ) & (*(volatile unsigned *)pPORT) ) | (0x2<<(PIN*2) );//10

}

2.4       读某管脚上的数据

U8 GPIOPinRead(U32 pPORT, U8 PIN)

{

      U8 u8val;

      u8val = (*(volatile unsigned *)(pPORT+0x4) & (0x1<<PIN));

      return u8val;//return the value of the special pin.

}

 

2.5       向某管脚写数据

void GPIOPinWrite(U32 pPORT, U8 PIN, U8 data)

{

      if(data == 0) 

             (*(volatile unsigned *)(pPORT+0x4)) =( ~(0x1<<PIN) & (*(volatile unsigned *)(pPORT+0x4)) );

      if(data == 1)

          (*(volatile unsigned *)(pPORT+0x4)) = ( (~(0x1<<PIN) )& (*(volatile unsigned *)(pPORT+0x4)) )| (0x1<< PIN);

}

声明:

本文及其他我写的文章,皆是鄙人学习总结笔记。文中内容我会尽最大的努力保证正确,如你发现bug,请一定要通知我,我会按您的指导进行Debug

我相信交流是提高技术最好的方法。

 

文章评论0条评论)

登录后参与讨论
我要评论
0
3
关闭 站长推荐上一条 /2 下一条