📄 gpio.c
字号:
/*******************************************************************************************
函数名称: GPIO_ClrPin
描 述: 设置某个引脚输出低电平
输入参数: DWORD dwIoControlCode : I/O control code, 指出操作的GPIO组, 如GPA, GPB
BYTE PinNum : 引脚编号, 如 GPB1, 则值为 1
输出参数:
返 回: TRUE: 操作成功 FALSE: 操作失败
*******************************************************************************************/
BOOL GPIO_ClrPin(DWORD dwIoControlCode, BYTE PinNum)
{
DWORD GPx;
volatile DWORD *pRegDAT; // GPxDAT's address
GPx = dwIoControlCode & IOCTL_GPX_MASK;
if (PinNum >= PinNumTbl[GPx]) return FALSE;
pRegDAT = ((DWORD *)v_pIOPregs + GPx * ADDRESS_INTERVAL_GPIO + 1); // 1 is a DWORD pointer
*pRegDAT &= ~(0x01 << PinNum);
return TRUE;
}
/*******************************************************************************************
函数名称: GPIO_ClrAllPin
描 述: 设置多个引脚输出低电平
输入参数: DWORD dwIoControlCode : I/O control code, 指出操作的GPIO组, 如GPA, GPB
BYTE PinNum : 引脚编号掩码, 如操作 GPB1,GPB3, 则值为: (0x01 << 1) + (0x01 << 3)
输出参数:
返 回: TRUE: 操作成功 FALSE: 操作失败
*******************************************************************************************/
BOOL GPIO_ClrAllPin(DWORD dwIoControlCode, DWORD PinMask)
{
DWORD GPx, i;
volatile DWORD *pRegDAT; // GPxDAT's address
GPx = dwIoControlCode & IOCTL_GPX_MASK;
pRegDAT = (DWORD *)v_pIOPregs + GPx * ADDRESS_INTERVAL_GPIO + 1;
for (i = 0; i < PinNumTbl[GPx]; i++)
{
if (PinMask & (0x01 << i))
*pRegDAT &= ~(0x01 << i);
}
return TRUE;
}
/*******************************************************************************************
函数名称: GPIO_ReadPin
描 述: 读取某个引脚的电平状态
输入参数: DWORD dwIoControlCode : I/O control code, 指出操作的GPIO组, 如GPA, GPB
BYTE PinNum : 引脚编号, 如 GPB1, 则值为 1
输出参数: YTE *pValue : 1: 引脚电平为高; 0: 引脚电平为低
返 回: TRUE: 操作成功 FALSE: 操作失败
*******************************************************************************************/
BOOL GPIO_ReadPin(DWORD dwIoControlCode, BYTE PinNum, BYTE *pValue)
{
DWORD GPx;
volatile DWORD *pRegDAT; // GPxDAT's address
if (pValue == NULL) return FALSE;
GPx = dwIoControlCode & IOCTL_GPX_MASK;
if (GPx == GPx_GPA) return FALSE; // GPA output only
pRegDAT = ((DWORD *)v_pIOPregs + GPx * ADDRESS_INTERVAL_GPIO + 1); // 1 is a DWORD pointer
if (*pRegDAT & (0x01 << PinNum))
*pValue = 1;
else
*pValue = 0;
return TRUE;
}
/*******************************************************************************************
函数名称: GPIO_ReadAllPin
描 述: 读出一组引脚的状态
输入参数: DWORD dwIoControlCode : I/O control code, 指出操作的GPIO组, 如GPA, GPB
DWORD nOutBufSize : pOutBuf 大小, 取值为1, 因为 GPA 不可读, 其它组最多超不过16个引脚
输出参数: ushort *pOutBuf : 整组引脚电平状态
返 回: TRUE: 操作成功 FALSE: 操作失败
*******************************************************************************************/
BOOL GPIO_ReadAllPin(DWORD dwIoControlCode, ushort *pOutBuf, DWORD nOutBufSize)
{
DWORD GPx;
volatile DWORD *pRegDAT; // GPxDAT's address
GPx = dwIoControlCode & IOCTL_GPX_MASK;
if (nOutBufSize < 1) return FALSE;
if (GPx == GPx_GPA) return FALSE; // GPA output only
pRegDAT = (DWORD *)v_pIOPregs + GPx * ADDRESS_INTERVAL_GPIO + 1;
*pOutBuf = (ushort)*pRegDAT;
return TRUE;
}
/*******************************************************************************************
函数名称: GPIO_ConfigPullUp
描 述: 设置某个引脚是否内部上拉
输入参数: DWORD dwIoControlCode : I/O control code, 指出操作的GPIO组, 如GPA, GPB
BYTE PinNum : 引脚编号, 如 GPB1, 则值为 1
BOOL bPullup : 是否上拉, TRUE: 上拉; FALSE: 不上拉.
输出参数:
返 回: TRUE: 操作成功 FALSE: 操作失败
*******************************************************************************************/
BOOL GPIO_ConfigPullUp(DWORD dwIoControlCode, BYTE PinNum, BOOL bPullup)
{
DWORD GPx;
volatile DWORD *pRegUp; // GPxUP's address
GPx = dwIoControlCode & IOCTL_GPX_MASK;
if (GPx == GPx_GPA) return FALSE; // GPA output only
pRegUp = ((DWORD *)v_pIOPregs + GPx * ADDRESS_INTERVAL_GPIO + 2); // 2 is a DWORD pointer
if (bPullup)
*pRegUp &= ~(0x01 << PinNum); // Pull up is enable
else
*pRegUp |= (0x01 << PinNum); // Pull up is disable
return TRUE;
}
/*******************************************************************************************
函数名称: GPIO_ConfigMultiPinPullup
描 述: 设置多个引脚是否内部上拉
输入参数: DWORD dwIoControlCode : I/O control code, 指出操作的GPIO组, 如GPA, GPB
BYTE PinNum : 引脚编号掩码, 如操作 GPB1,GPB3, 则值为: (0x01 << 1) + (0x01 << 3)
BOOL bPullup : 是否上拉, TRUE: 上拉; FALSE: 不上拉.
输出参数:
返 回: TRUE: 操作成功 FALSE: 操作失败
*******************************************************************************************/
BOOL GPIO_ConfigMultiPinPullup(DWORD dwIoControlCode, DWORD PinMask, BOOL bPullup)
{
DWORD GPx;
volatile DWORD *pRegUp; // GPxUP's address
GPx = dwIoControlCode & IOCTL_GPX_MASK;
if (GPx == GPx_GPA) return FALSE; // GPA output only
pRegUp = ((DWORD *)v_pIOPregs + GPx * ADDRESS_INTERVAL_GPIO + 2); // 2 is a DWORD pointer
if (bPullup)
*pRegUp &= ~(PinMask); // Pull up is enable
else
*pRegUp |= (PinMask); // Pull up is disable
return TRUE;
}
/*******************************************************************************************
函数名称: PIO_IOControl
描 述: 驱动程序 I/O 请求
输入参数: DWORD dwIoControlCode: 见本文件的头文件
输出参数:
返 回: TRUE: 操作成功 FALSE: 操作失败
*******************************************************************************************/
BOOL
PIO_IOControl(
DWORD Handle,
DWORD dwIoControlCode,
PBYTE pInBuf,
DWORD nInBufSize,
PBYTE pOutBuf,
DWORD nOutBufSize,
PDWORD pBytesReturned
)
{
BOOL bErr = FALSE;
switch(dwIoControlCode & IOCTL_GPIO_FUN_MASK)
{
/*
* 设置引脚为输出
*/
case IOCTL_GPIO_SET_PIN_OUT:
if (nInBufSize > 0)
bErr = GPIO_SetPinOut(dwIoControlCode, *pInBuf);
break;
case IOCTL_GPIO_SET_MULTI_PIN_OUT: /* pInBuf 必须为4字节 */
if (nInBufSize > 0)
bErr = GPIO_SetMultiPinOut(dwIoControlCode, *(DWORD *)pInBuf);
//RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x).\r\n"), *(DWORD *)pInBuf));
break;
/*
* 设置引脚为输入
*/
case IOCTL_GPIO_SET_PIN_IN:
if (nInBufSize > 0)
bErr = GPIO_SetPinIn(dwIoControlCode, *pInBuf);
break;
case IOCTL_GPIO_SET_MULTI_PIN_IN: /* pInBuf 必须为4字节 */
if (nInBufSize > 0)
bErr = GPIO_SetMultiPinIn(dwIoControlCode, *(DWORD *)pInBuf);
//RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x).\r\n"), *(DWORD *)pInBuf));
break;
/*
* 设置引脚输出高电平
*/
case IOCTL_GPIO_SET_PIN:
if (nInBufSize > 0)
bErr = GPIO_SetPin(dwIoControlCode, *pInBuf);
break;
case IOCTL_GPIO_SET_MULTI_PIN: /* pInBuf 必须为4字节 */
if (nInBufSize >= 0)
bErr = GPIO_SetAllPin(dwIoControlCode, *(DWORD *)pInBuf);
//RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x).\r\n"), *(DWORD *)pInBuf));
break;
/*
* 设置引脚输出低电平
*/
case IOCTL_GPIO_CLR_PIN:
if (nInBufSize > 0)
bErr = GPIO_ClrPin(dwIoControlCode, *pInBuf);
break;
case IOCTL_GPIO_CLR_MULTI_PIN: /* pInBuf 必须为4字节 */
if (nInBufSize > 0)
bErr = GPIO_ClrAllPin(dwIoControlCode, *(DWORD *)pInBuf);
//RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x).\r\n"), *(DWORD *)pInBuf));
break;
/*
* 读取引脚电平状态
*/
case IOCTL_GPIO_READ_PIN:
if ((nOutBufSize > 0) && (nInBufSize > 0))
{
bErr = GPIO_ReadPin(dwIoControlCode, *pInBuf, pOutBuf);
*pBytesReturned = 1;
}
break;
case IOCTL_GPIO_READ_ALL_PIN: /* pOutBuf 必须为2字节 */
if (nOutBufSize > 0)
{
bErr = GPIO_ReadAllPin(dwIoControlCode, (ushort *)pOutBuf, 1);
*pBytesReturned = 1;
}
break;
/*
* 使能引脚内部上拉
*/
case IOCTL_GPIO_EN_PULLUP: /* *pInBuf 为1字节 */
if (nInBufSize > 0)
bErr = GPIO_ConfigPullUp(dwIoControlCode, *pInBuf, TRUE);
break;
case IOCTL_GPIO_EN_MULTI_PIN_PULLUP: /* pInBuf 必须为4字节 */
if (nInBufSize > 0)
bErr = GPIO_ConfigMultiPinPullup(dwIoControlCode, *(DWORD *)pInBuf, TRUE);
break;
/*
* 禁止引脚内部上拉
*/
case IOCTL_GPIO_DIS_PULLUP:
if (nInBufSize > 0) /* *pInBuf 为1字节 */
bErr = GPIO_ConfigPullUp(dwIoControlCode, *pInBuf, FALSE);
break;
case IOCTL_GPIO_DIS_MULTI_PIN_PULLUP: /* pInBuf 必须为4字节 */
if (nInBufSize > 0)
bErr = GPIO_ConfigMultiPinPullup(dwIoControlCode, *(DWORD *)pInBuf, FALSE);
break;
default:
break;
}
return bErr;
} // PIO_IOControl
/*******************************************************************************************
函数名称: PIO_Read
描 述: 读取按键状态
输入参数: DWORD Handle : 驱动程序引用事例句柄
LPVOID pBuffer : 接收缓冲区
DWORD dwNumBytes: 要读的字节数
输出参数: 无
返 回: 实际读到字节数
*******************************************************************************************/
DWORD PIO_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
return 0;
}
/*******************************************************************************************
函数名称: PIO_Write
描 述: 写函数,本驱动不支持
输入参数:
输出参数:
返 回:
*******************************************************************************************/
DWORD PIO_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
return 0;
}
/*******************************************************************************************
函数名称: PIO_Seek
描 述: 对设备的数据指针进行操作,本驱动不支持该函数
输入参数:
输出参数:
返 回:
*******************************************************************************************/
DWORD PIO_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)
{
return 0;
}
/*******************************************************************************************
函数名称: PIO_PowerUp
描 述: 电源上电驱动处理函数
输入参数:
输出参数:
返 回: 无
*******************************************************************************************/
void PIO_PowerUp(void)
{
return;
}
/*******************************************************************************************
函数名称: PIO_PowerDown
描 述: 电源下电驱动处理函数
输入参数:
输出参数:
返 回: 无
*******************************************************************************************/
void PIO_PowerDown(void)
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -