4. PORT与DIO驱动开发
在S32K1xx系列MCU中,GPIO功能被拆分为两个协同工作的模块:PORT模块负责引脚级的复用选择与电气属性配置,DIO模块负责引脚级的电平读写与方向控制。理解这两个模块的分工,是写好AUTOSAR Dio驱动和Port驱动的基础。本节以S32K144为例,从寄存器层面展开,并落到按键输入与LED输出的完整实战。
一、PORT与DIO的职责边界
PORT模块(Port Control and Interrupts)管理每个引脚的“物理属性”:引脚复用功能(MUX)、上拉/下拉、驱动强度、压摆率、无源滤波、中断触发方式等。DIO模块(Digital Input/Output)管理每个引脚的“逻辑行为”:方向(输入/输出)、输出电平、输入电平读取、翻转。一个引脚必须先由PORT配置好复用为GPIO,DIO才能对其读写;若PORT把引脚复用为LPUART0_TX,DIO对该引脚的读写不会影响引脚功能。
S32K144的PORT分为PORTA~PORTE共5组,每组32个引脚,但并非全部引出。DIO同样按组组织,每组有PDOR、PSOR、PCOR、PTOR、PDIR、PDDR、PIDR等寄存器。AUTOSAR中,Port驱动对应PORT模块,Dio驱动对应DIO模块,二者通过配置工具生成静态代码,运行时由Dio_ReadChannel/Dio_WriteChannel等API操作。
二、PORT寄存器:PCR是核心
每个引脚对应一个32位PCR寄存器(Pin Control Register)。关键位域如下:
- MUX[10:8]:复用选择。000为模拟,001为GPIO,010~111为各外设功能。例如PTD0的MUX=001时作为GPIO,MUX=010时为LPUART2_RX。
- PE(bit1):上拉/下拉使能。置1后由PS(bit0)决定方向:PS=1上拉,PS=0下拉。
- DSE(bit6):驱动强度。0为低驱动(约2mA),1为高驱动(约10mA),驱动LED时通常置1。
- SRE(bit2):压摆率。0为快,1为慢,慢压摆率可降低EMI。
- PFE(bit4):无源滤波使能,可滤除约10~30ns的窄脉冲,按键输入可开启。
- IRQC[19:16]:中断配置。0000禁用,1001为上升沿,1010为下降沿,1011为任意边沿,1100为低电平,1101为高电平。
配置示例:将PTD0配置为GPIO输出、高驱动、无上下拉,PCR值可写为:MUX=001,DSE=1,其余为0,即0x00000140。若配置为输入带上拉,则MUX=001,PE=1,PS=1,即0x00000143。
三、DIO寄存器:读写与翻转
DIO的寄存器操作非常直接。以PTD为例:
- PDDR:方向。写1为输出,写0为输入。例如PDDR |= (1<<0) 将PTD0设为输出。
- PDOR:输出数据。写1输出高,写0输出低。读PDOR返回最后写入的值。
- PSOR:置位。写1的位对应引脚输出高,写0无影响。用于原子置位,避免读改写竞争。
- PCOR:清零。写1的位对应引脚输出低。
- PTOR:翻转。写1的位对应引脚电平翻转,是LED闪烁最简洁的方式。
- PDIR:读引脚实际电平,与方向无关,输入模式下用于读取按键状态。
注意:PSOR/PCOR/PTOR是“写1有效”的原子操作,不需要先读PDOR再修改,这在中断和多任务环境中更安全。例如PTD->PTOR = (1<<0) 即可翻转PTD0,无需关心其他位。
四、按键输入与LED输出实战
假设硬件连接:PTD0接LED(低电平点亮),PTD15接按键(按下接地,外部无上拉,需内部上拉)。目标:按键按下时LED点亮,松开时熄灭;同时用PTOR实现LED每500ms翻转一次的呼吸提示。
第一步,PORT配置。PTD0:MUX=001,DSE=1,无上下拉,PCR=0x00000140。PTD15:MUX=001,PE=1,PS=1(上拉),PFE=1(滤波),PCR=0x00000153。
第二步,DIO方向。PTD0设为输出:PTD->PDDR |= (1<<0);PTD15设为输入:PTD->PDDR &= ~(1<<15)。
第三步,主循环逻辑。读取PTD15电平:若为0(按下),则PTD->PCOR = (1<<0) 点亮LED;若为1(松开),则PTD->PSOR = (1<<0) 熄灭LED。同时用SysTick或定时器每500ms执行PTD->PTOR = (1<<0) 翻转LED,作为心跳指示。
/* 简化示例,非完整工程代码 */
#define LED_PIN 0u
#define KEY_PIN 15u
/* PORT配置(实际由Port驱动初始化完成) */
PTD->PCR[LED_PIN] = 0x00000140u; /* MUX=001, DSE=1 */
PTD->PCR[KEY_PIN] = 0x00000153u; /* MUX=001, PE=1, PS=1, PFE=1 */
/* DIO方向 */
PTD->PDDR |= (1u << LED_PIN); /* LED输出 */
PTD->PDDR &= ~(1u << KEY_PIN); /* 按键输入 */
/* 主循环 */
for (;;) {
if ((PTD->PDIR & (1u << KEY_PIN)) == 0u) {
PTD->PCOR = (1u << LED_PIN); /* 按下点亮 */
} else {
PTD->PSOR = (1u << LED_PIN); /* 松开熄灭 */
}
/* 心跳翻转由定时器中断每500ms执行 */
/* PTD->PTOR = (1u << LED_PIN); */
}
五、AUTOSAR Dio/Port API映射
在AUTOSAR环境下,上述寄存器操作由驱动封装。Port驱动初始化时根据配置写入PCR;Dio驱动提供Dio_ReadChannel、Dio_WriteChannel、Dio_FlipChannel、Dio_ReadPort、Dio_WritePort等API。例如Dio_WriteChannel(DioConf_DioChannel_LED, STD_LOW) 等价于PCOR置位;Dio_FlipChannel则对应PTOR。配置工具中需要为每个引脚指定PortPinId、PortPinDirection、PortPinInitialMode、PortPinLevelValue等参数,生成的配置结构体最终映射到PCR和PDDR。