//======================================================================//
//! \总的声明:
//! 通常我们是直接使用寄存器配置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
//! 如果我们将GPBCON或GPCCON中的某一位置1,其实在数学上的处理是一样的,所以我们就
//! 想可否只写一个函数,就可以处理所有的CON寄存器(除了GPIOA以外)。
//! 所以我们就想到了直接操作指针,比如:
//! 我们 #define pGPIOB 0x56000010,
//! 我们知道0x56000010是GPIOB的所有寄存器的起始地址,所以如果我们要操作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语句。
//!
//!
//======================================================================//
以下为一些常用的函数
//******************************************************************
//
//! \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) );
}
}
//******************************************************************
//
//! \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) );
}
}
//******************************************************************
//
//! \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
}
U8 GPIOPinRead(U32 pPORT, U8 PIN)
{
U8 u8val;
u8val = (*(volatile unsigned *)(pPORT+0x4) & (0x1<<PIN));
return u8val;//return the value of the special pin.
}
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条评论)
登录后参与讨论