文章目录
MCAL - PORT(NXP - S32K14x)
配置工具:EB Tresos Studio
芯片类型:S32K146
1. 概述
Port模块主要功能在于芯片引脚的配置。
2. API
函数 | 描述 |
---|---|
Port_Init | Port模块初始化 |
Port_SetPinDirection | 设置引脚方向 |
Port_RefreshPortDirection | 刷新引脚方向配置 |
Port_GetVersionInfo | 获取Port模块版本号 |
Port_SetPinMode | 设置引脚模式 |
3. 配置介绍
3.1 配置项
PortPin Mode:引脚模式
PortPin Direction:引脚输入/输出方向
PortPin Level Value:引脚输出电平
PortPin DSE:引脚驱动能力
PortPin PE:上拉/下拉使能
PortPin PS:上拉/下拉
PortPin Pcr:引脚对应寄存器序号
针对不同的芯片,参考手册已经给出了每个端口可用的引脚数。这里要注意的是每个端口都是有32个PCR寄存器,各芯片启用都是不一致的,例如s32k146
的PORT A
只是启用了32个中的25个。各个芯片具体的配置可以在S32K-RM参考手册的附件中找到
。
计算方式:pcr index = 32 * (PORT Index) + Pin
示例:PTE3 = 32 * 4 + 3 = 131
如下图所示,在【S32K-RM.pdf】附件中可以找到对应芯片的引脚功能。
3.2 General
3.2.1 NotUsedPortPin
该部分是为了统一配置未使用的端口。为了降低MCU功耗,可以设置成以下配置:
3.2.2 PortGeneral
该部分是使能Api,根据需求开启或关闭
Port SetPinMode Does Not Touch GPIO Levels:设置引脚模式时不将引脚电平设置为初始值
在Port_Ipw_SetPinMode
函数中可以看到下面这段代码,当引脚配置为输出模式的时候,若Port SetPinMode Does Not Touch GPIO Levels
为false,则会将输出电平配置为PortPin Level Value
设置的状态。
#if (STD_OFF == PORT_SETPINMODE_DOES_NOT_TOUCH_GPIO_LEVEL)
if((PORT_PIN_IN != ePadDirection) && (PORT_PIN_HIGH_Z != ePadDirection))
{
Port_Port_Ci_SetGpioPadOutput(PinIndex, pConfigPtr);
}
#endif /* (STD_OFF == PORT_SETPINMODE_DOES_NOT_TOUCH_GPIO_LEVEL) */
3.3 引脚配置
3.3.1 PortContainer
PortContainer只是一个容器,为了让可以理解为一个目录,为了方便快速找到配置的引脚,对引脚做分类管理。例如我这里建了一个GPIO容器,该容器里面专门配置GPIO模式的引脚,然后建了一个JTAG的容器,该容器里面专门配置JTAG引脚。
配置完引脚后,记得刷新容器中的引脚个数
3.3.2 PortPin
该部分用于引脚配置,在PortPin中可以创建引脚配置,双击序号进入详细配置。
在详细配置界面中配置引脚的PCR序号
、引脚模式
、上拉/下拉
、引脚方向
、引脚输出电平
。
示例:PTE3 输出高电平:
PortPin Direction Changeable:是否能修改引脚方向
(前提是勾选Port Development Error Detect
)
在Port_Port_Ci_SetPinDirection
函数中可以看到如下代码,bDC
就是该配置项配置的值,在设置引脚方向之前会先判断这个值。
#if (STD_ON == PORT_DEV_ERROR_DETECT)
/* Check the Direction changeability option */
/* @violates @ref Port_Port_Ci_C_REF_7 Violates MISRA 2004 Required Rule 17.4 */
if (((boolean)TRUE == pConfigPtr->pUsedPadConfig[PinIndex].bDC) || ((uint16)0 != (u16PinChangeDirFlagWord & (uint16)(1UL<<u8PinDescBitOffset))))
{
#endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */
/* Enter critical region */
SchM_Enter_Port_PORT_EXCLUSIVE_AREA_03();
/* Configures Port Pin as Output */
if (PORT_PIN_OUT == eDirection)
{
/* @violates @ref Port_Port_Ci_C_REF_5 Violates MISRA 2004 Required Rule 11.1, cast from unsigned long to pointer. */
/* @violates @ref Port_Port_Ci_C_REF_10 A cast should not be performed between a pointer type and an integral type. */
REG_BIT_SET32(GPIO_PDDR_ADDR32(GPIO_PORT_U32(Pin)), (uint32)(1UL << GPIO_CHANNEL_U32(Pin)));
}
/* Configures Port Pin as Input or High-Z*/
else if ((PORT_PIN_IN == eDirection) || (PORT_PIN_HIGH_Z == eDirection))
{
/* @violates @ref Port_Port_Ci_C_REF_5 Violates MISRA 2004 Required Rule 11.1, cast from unsigned long to pointer. */
/* @violates @ref Port_Port_Ci_C_REF_10 A cast should not be performed between a pointer type and an integral type. */
REG_BIT_CLEAR32(GPIO_PDDR_ADDR32(GPIO_PORT_U32(Pin)), (uint32)(1UL << GPIO_CHANNEL_U32(Pin)));
/* Check if the pin is HIGH-Z. In this case the driver needs to disable port input in PIDR register of GPIO IP*/
if(PORT_PIN_HIGH_Z == eDirection)
{
/* @violates @ref Port_Port_Ci_C_REF_5 Violates MISRA 2004 Required Rule 11.1, cast from unsigned long to pointer. */
/* @violates @ref Port_Port_Ci_C_REF_10 A cast should not be performed between a pointer type and an integral type. */
REG_BIT_SET32(GPIO_PIDR_ADDR32(GPIO_PORT_U32(Pin)), (uint32)(1UL << GPIO_CHANNEL_U32(Pin)));
}
}
else
{
/* Do nothing */
}
/* Exit critical region */
SchM_Exit_Port_PORT_EXCLUSIVE_AREA_03();
#if (STD_ON == PORT_DEV_ERROR_DETECT)
}
/* Direction changeability is NOT supported */
else
{
PinDirError = (Std_ReturnType)E_NOT_OK;
}
#endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */
PortPin Mode Changeable:是否能修改引脚模式
(前提是勾选Port Development Error Detect
)
在Port_SetPinMode
函数中可以看到如下代码,bMC
就是该配置项配置的值,在设置引脚模式之前会先判断这个值。`
/* Check if port is initialized */
if (NULL_PTR == Port_pConfig)
{
(void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINMODE_ID, (uint8)PORT_E_UNINIT);
}
/* Check port pin validity */
else if (Pin >= (Port_PinType)Port_pConfig->u16NumPins)
{
(void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINMODE_ID, (uint8)PORT_E_PARAM_PIN);
}
/* Check port pin mode Unchangeable */
/** @violates @ref PORT_C_REF_5 Array indexing shall be the only allowed form of pointer arithmetic */
else if((boolean)FALSE == (boolean) Port_pConfig->pUsedPadConfig[Pin].bMC)
{
(void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINMODE_ID, (uint8)PORT_E_MODE_UNCHANGEABLE);
}
else
#endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */
{
/* Sets the port pin direction */
#if (STD_ON == PORT_DEV_ERROR_DETECT)
u8PinModeError = (uint8)Port_Ipw_SetPinMode(Pin, Mode, Port_pConfig);
#else
(void)Port_Ipw_SetPinMode(Pin, Mode, Port_pConfig);
#endif
#if (STD_ON == PORT_DEV_ERROR_DETECT)
if (PORT_E_PARAM_INVALID_MODE == u8PinModeError)
{
(void)Det_ReportError((uint16)PORT_MODULE_ID, (uint8)PORT_INSTANCE_ID, (uint8)PORT_SETPINMODE_ID, (uint8)PORT_E_PARAM_INVALID_MODE);
}
#endif /* (STD_ON == PORT_DEV_ERROR_DETECT) */
}
参考资料:
S32K-RM.pdf - NXP
AUTOSAR_MCAL_PORT_UM[1].pdf - NXP