?? gpio.c
字號:
/******************** (C) COPYRIGHT 2010 Embest Info&Tech Co.,LTD. ************
* 文件名: gpio.c
* 作者 : Wuhan R&D Center, Embest
* 日期 : 01/18/2010
* 描述 : NXP LPC11xx 系列處理器 GPIO API 文件
*******************************************************************************
*******************************************************************************
* 歷史:
* 01/18/2010 : V1.0 初始版本
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include "LPC11xx.h" /* LPC11xx 外設寄存器 */
#include "gpio.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
volatile uint32_t gpio0_counter = 0;
volatile uint32_t gpio1_counter = 0;
volatile uint32_t gpio2_counter = 0;
volatile uint32_t gpio3_counter = 0;
volatile uint32_t p0_1_counter = 0;
volatile uint32_t p1_1_counter = 0;
volatile uint32_t p2_1_counter = 0;
volatile uint32_t p3_1_counter = 0;
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @函數(shù)名:PIOINT0_IRQHandler
* @描述:使用GPIO一個管腳(端口0的管腳1)作為中斷源
* @參數(shù): 無
* @返回值:無
*/
/*
void PIOINT0_IRQHandler(void)
{
uint32_t regVal;
gpio0_counter++;
regVal = GPIOIntStatus( PORT0, 1 );
if ( regVal )
{
p0_1_counter++;
GPIOSetDir( 1, 8, 1 );
GPIOIntClear( PORT0, 1 );
}
printf("\n\r PIOINT0_IRQHandler! \n\r");
return;
}
*
* @函數(shù)名:PIOINT1_IRQHandler
* @描述:使用GPIO一個管腳(端口1的管腳1)作為中斷源
* @參數(shù):無
* @返回值:無
void PIOINT1_IRQHandler(void)
{
uint32_t regVal;
gpio1_counter++;
regVal = GPIOIntStatus( PORT1, 1 );
if ( regVal )
{
GPIOSetValue(PORT1,8,1);
GPIOIntClear( PORT1, 0);
}
return;
}
*/
/**
* @函數(shù)名:PIOINT2_IRQHandler
* @描述:使用GPIO一個管腳(端口2的管腳1)作為中斷源 interrupt source
* @參數(shù):無
* @返回值:無
void PIOINT2_IRQHandler(void)
{
uint32_t regVal;
gpio2_counter++;
regVal = GPIOIntStatus( PORT1, 0 );
if ( regVal )
{
GPIOSetValue(PORT1,8,1);
GPIOIntClear( PORT1, 0);
}
return;
}
*/
/**
* @函數(shù)名:PIOINT3_IRQHandler
* @描述:使用GPIO一個管腳(端口3的管腳1)作為中斷源 interrupt source
* @參數(shù): 無
* @返回值:無
void PIOINT3_IRQHandler(void)
{
uint32_t regVal;
gpio3_counter++;
regVal = GPIOIntStatus( PORT3, 1 );
if ( regVal )
{
p3_1_counter++;
GPIOIntClear( PORT3, 1 );
}
return;
}
*/
/**
* @函數(shù)名:GPIOInit
* @描述:初始化GPIO,設置GPIO的中斷例程
* @參數(shù): 無
* @返回值:真或假,如果VIC表已滿并且GPIO中斷例程已經(jīng)設置了則返回假。
*/
void GPIOInit( void )
{
/* 使能AHB時鐘到GPIO域。*/
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
#ifdef __JTAG_DISABLED
LPC_IOCON->JTAG_TDO_PIO1_1 &= ~0x07;
LPC_IOCON->JTAG_TDO_PIO1_1 |= 0x01;
#endif
/* 當I/O管腳被配置為外部中斷時,建立NVIC。*/
NVIC_EnableIRQ(EINT0_IRQn);
NVIC_EnableIRQ(EINT1_IRQn);
NVIC_EnableIRQ(EINT2_IRQn);
NVIC_EnableIRQ(EINT3_IRQn);
return;
}
/**
* @函數(shù)名:GPIOSetDir
* @描述:設置GPIO端口方向
* @參數(shù):端口號,管腳位置,方向(1為輸出,0為輸入)
* @返回值:無
*/
void GPIOSetDir( uint32_t portNum, uint32_t bitPosi, uint32_t dir )
{
/* 如果方向是輸出(1),但是GPIOx_DIR的方向沒有設置,設置方向為輸出(1);
如果方向是輸入(0),但是GPIOx_DIR已經(jīng)設置了,清方向后在設置為輸入(0)。
其他條件都忽略。在端口3上(只有0至3位),如果位值超出了范圍,沒有錯誤保護 。 */
switch ( portNum )
{
case PORT0:
if ( !(LPC_GPIO0->DIR & (0x1<<bitPosi)) && (dir == 1) )
{
LPC_GPIO0->DIR |= (0x1<<bitPosi);
}
else if ( (LPC_GPIO0->DIR & (0x1<<bitPosi)) && (dir == 0) )
{
LPC_GPIO0->DIR &= ~(0x1<<bitPosi);
}
break;
case PORT1:
if ( !(LPC_GPIO1->DIR & (0x1<<bitPosi)) && (dir == 1) )
{
LPC_GPIO1->DIR |= (0x1<<bitPosi);
}
else if ( (LPC_GPIO1->DIR & (0x1<<bitPosi)) && (dir == 0) )
{
LPC_GPIO1->DIR &= ~(0x1<<bitPosi);
}
break;
case PORT2:
if ( !(LPC_GPIO2->DIR & (0x1<<bitPosi)) && (dir == 1) )
{
LPC_GPIO2->DIR |= (0x1<<bitPosi);
}
else if ( (LPC_GPIO2->DIR & (0x1<<bitPosi)) && (dir == 0) )
{
LPC_GPIO2->DIR &= ~(0x1<<bitPosi);
}
break;
case PORT3:
if ( !(LPC_GPIO3->DIR & (0x1<<bitPosi)) && (dir == 1) )
{
LPC_GPIO3->DIR |= (0x1<<bitPosi);
}
else if ( (LPC_GPIO3->DIR & (0x1<<bitPosi)) && (dir == 0) )
{
LPC_GPIO3->DIR &= ~(0x1<<bitPosi);
}
break;
default:
break;
}
}
/*
uint32_t GPIOGetbit(uint32_t portNum,uint32_t bitPosi)
{
uint32_t bitVal;
switch(portNum)
{
case PORT0:
bitVal=(LPC_GPIO0->DATA>>bitPosi)&0x01;
return bitVal;
break;
case PORT1:
bitVal=(LPC_GPIO1->DATA>>bitPosi)&0x01;
return bitVal;
break;
case PORT2:
bitVal=(LPC_GPIO2->DATA>>bitPosi)&0x01;
return bitVal;
break;
case PORT3:
bitVal=(LPC_GPIO3->DATA>>bitPosi)&0x01;
return bitVal;
break;
}
} */
/**
* @函數(shù)名:GPIOSetValue
* @描述:設置/清除一個在GPIO端口X(X是端口號)上的一些特定管腳上的位值。
* @參數(shù):端口號,位地址,位值
* @返回值:無
*/
void GPIOSetValue( uint32_t portNum, uint32_t bitPosi, uint32_t bitVal )
{
/* 如果值是,但是 GPIOx_DAT 沒有設置,設置 DATA
為 1; 如果值是 0,但是 GPIOx_DAT 已經(jīng)設置了, 清除
DATA 為 0。其他條件都忽略。在端口3上(只有0至3位),如果位值超出了范圍,沒有錯誤保護 。 */
switch ( portNum )
{
case PORT0:
if ( !(LPC_GPIO0->DATA & (0x1<<bitPosi)) && (bitVal == 1) )
{
LPC_GPIO0->DATA |= (0x1<<bitPosi);
}
else if ( (LPC_GPIO0->DATA & (0x1<<bitPosi)) && (bitVal == 0) )
{
LPC_GPIO0->DATA &= ~(0x1<<bitPosi);
}
break;
case PORT1:
if ( !(LPC_GPIO1->DATA & (0x1<<bitPosi)) && (bitVal == 1) )
{
LPC_GPIO1->DATA |= (0x1<<bitPosi);
}
else if ( (LPC_GPIO1->DATA & (0x1<<bitPosi)) && (bitVal == 0) )
{
LPC_GPIO1->DATA &= ~(0x1<<bitPosi);
}
break;
case PORT2:
if ( !(LPC_GPIO2->DATA & (0x1<<bitPosi)) && (bitVal == 1) )
{
LPC_GPIO2->DATA |= (0x1<<bitPosi);
}
else if ( (LPC_GPIO2->DATA & (0x1<<bitPosi)) && (bitVal == 0) )
{
LPC_GPIO2->DATA &= ~(0x1<<bitPosi);
}
break;
case PORT3:
if ( !(LPC_GPIO3->DATA & (0x1<<bitPosi)) && (bitVal == 1) )
{
LPC_GPIO3->DATA |= (0x1<<bitPosi);
}
else if ( (LPC_GPIO3->DATA & (0x1<<bitPosi)) && (bitVal == 0) )
{
LPC_GPIO3->DATA &= ~(0x1<<bitPosi);
}
break;
default:
break;
}
}
/**
* @函數(shù)名:GPIOSetInterrupt
* @描述:設置中斷偵測,事件等。邊沿或?qū)哟危?為邊沿,1為層次
* 單邊沿或雙邊沿,0為單邊沿,1為雙邊沿高或低有效等。
* @參數(shù):端口號, 位地址, sense, single/doube, polarity
* @返回值:無
*/
void GPIOSetInterrupt( uint32_t portNum, uint32_t bitPosi, uint32_t sense,
uint32_t single, uint32_t event )
{
switch ( portNum )
{
case PORT0:
if ( sense == 0 )
{
LPC_GPIO0->IS &= ~(0x1<<bitPosi);
/* single or double only applies when sense is 0(邊沿觸發(fā)) */
if ( single == 0 )
LPC_GPIO0->IBE &= ~(0x1<<bitPosi);
else
LPC_GPIO0->IBE |= (0x1<<bitPosi);
}
else
LPC_GPIO0->IS |= (0x1<<bitPosi);
if ( event == 0 )
LPC_GPIO0->IEV &= ~(0x1<<bitPosi);
else
LPC_GPIO0->IEV |= (0x1<<bitPosi);
break;
case PORT1:
if ( sense == 0 )
{
LPC_GPIO1->IS &= ~(0x1<<bitPosi);
/* single or double only applies when sense is 0(edge trigger). */
if ( single == 0 )
LPC_GPIO1->IBE &= ~(0x1<<bitPosi);
else
LPC_GPIO1->IBE |= (0x1<<bitPosi);
}
else
LPC_GPIO1->IS |= (0x1<<bitPosi);
if ( event == 0 )
LPC_GPIO1->IEV &= ~(0x1<<bitPosi);
else
LPC_GPIO1->IEV |= (0x1<<bitPosi);
break;
case PORT2:
if ( sense == 0 )
{
LPC_GPIO2->IS &= ~(0x1<<bitPosi);
/* single 或 double 只在 sense 為 0 時應用(edge trigger). */
if ( single == 0 )
LPC_GPIO2->IBE &= ~(0x1<<bitPosi);
else
LPC_GPIO2->IBE |= (0x1<<bitPosi);
}
else
LPC_GPIO2->IS |= (0x1<<bitPosi);
if ( event == 0 )
LPC_GPIO2->IEV &= ~(0x1<<bitPosi);
else
LPC_GPIO2->IEV |= (0x1<<bitPosi);
break;
case PORT3:
if ( sense == 0 )
{
LPC_GPIO3->IS &= ~(0x1<<bitPosi);
/* single 或 double 只在 sense 為 0 時應用(edge trigger). */
if ( single == 0 )
LPC_GPIO3->IBE &= ~(0x1<<bitPosi);
else
LPC_GPIO3->IBE |= (0x1<<bitPosi);
}
else
LPC_GPIO3->IS |= (0x1<<bitPosi);
if ( event == 0 )
LPC_GPIO3->IEV &= ~(0x1<<bitPosi);
else
LPC_GPIO3->IEV |= (0x1<<bitPosi);
break;
default:
break;
}
return;
}
/**
* @函數(shù)名:GPIOIntEnable
* @描述:使能相關(guān)端口管腳中斷
* @參數(shù):端口號, 位地址
* @返回值:無
*/
void GPIOIntEnable( uint32_t portNum, uint32_t bitPosi )
{
switch ( portNum )
{
case PORT0:
LPC_GPIO0->IE |= (0x1<<bitPosi);
break;
case PORT1:
LPC_GPIO1->IE |= (0x1<<bitPosi);
break;
case PORT2:
LPC_GPIO2->IE |= (0x1<<bitPosi);
break;
case PORT3:
LPC_GPIO3->IE |= (0x1<<bitPosi);
break;
default:
break;
}
return;
}
/**
* @函數(shù)名: GPIOIntDisable
* @描述: 屏蔽相關(guān)端口管腳的中斷
* @參數(shù): 端口號, 位地址
* @返回值: 無
*/
void GPIOIntDisable( uint32_t portNum, uint32_t bitPosi )
{
switch ( portNum )
{
case PORT0:
LPC_GPIO0->IE &= ~(0x1<<bitPosi);
break;
case PORT1:
LPC_GPIO1->IE &= ~(0x1<<bitPosi);
break;
case PORT2:
LPC_GPIO2->IE &= ~(0x1<<bitPosi);
break;
case PORT3:
LPC_GPIO3->IE &= ~(0x1<<bitPosi);
break;
default:
break;
}
return;
}
/**
* @函數(shù)名:GPIOIntStatus
* @描述:獲得端口管腳的中斷狀態(tài)。
* @參數(shù):端口號, 位地址
* @返回值:無
*/
uint32_t GPIOIntStatus( uint32_t portNum, uint32_t bitPosi )
{
uint32_t regVal = 0;
switch ( portNum )
{
case PORT0:
if ( LPC_GPIO0->MIS & (0x1<<bitPosi) )
regVal = 1;
break;
case PORT1:
if ( LPC_GPIO1->MIS & (0x1<<bitPosi) )
regVal = 1;
break;
case PORT2:
if ( LPC_GPIO2->MIS & (0x1<<bitPosi) )
regVal = 1;
break;
case PORT3:
if ( LPC_GPIO3->MIS & (0x1<<bitPosi) )
regVal = 1;
break;
default:
break;
}
return ( regVal );
}
/**
* @函數(shù)名: GPIOIntClear
* @描述: 清除端口管腳的中斷。
* @參數(shù): 端口號, 位地址
* @返回值: 無
*/
void GPIOIntClear( uint32_t portNum, uint32_t bitPosi )
{
switch ( portNum )
{
case PORT0:
LPC_GPIO0->IC |= (0x1<<bitPosi);
break;
case PORT1:
LPC_GPIO1->IC |= (0x1<<bitPosi);
break;
case PORT2:
LPC_GPIO2->IC |= (0x1<<bitPosi);
break;
case PORT3:
LPC_GPIO3->IC |= (0x1<<bitPosi);
break;
default:
break;
}
return;
}
/**
* @}
*/
/**
* @}
*/
/************* (C) COPYRIGHT 2010 Wuhan R&D Center, Embest *****文件結(jié)束*******/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -