分享

S32K SDK使用详解之PinSettings组件配置与使用详解(S32K1xx PORT 和GP...

 xingqingzl 2020-01-06

内容提要

引言
1. S32K1xx系列MCU的引脚功能特性详解(PORT和GPIO模块)

1.1 S32K1xx的PORT模块配置寄存器介绍

1.2 S32K1xx的GPIO模块配置与状态寄存器介绍

1.3 S32K1xx系列MCU的GPIO IRQ中断

2. PinSettings组件配置的S32K1xx系列MCU硬件模块

2.1 PinSettings组件属性配置详解

2.2 PinSettings组件API函数详解

2.3 PinSettings组件使用Tips

3. 基于S32K144-EVB的GPIO IRQ中断控制RGB LED亮灭样例工程

3.1 S32K144-EVB的用户按键输入硬件设计及其PinSettings组件GPIO中断配置

3.2 S32K144-EVB的RGB LED硬件设计及其PinSettings组件GPIO输入配置

3.3 GPIO IRQ中断控制RGB LED亮灭功能代码实现

总结

引言

GPIO--General Porpurse Input Output,通用输入输出端口是嵌入式MCU对外进行信息交换实现人机交互(HMI)的重要模块,MCU片内各种功能外设模块的功能实现也大多需要配置GPIO才能实现---比如将某一GPIO引脚配置为定时器模块的输入捕捉通道(IC)或者输出比较(OC)通道,或者是作为通信外设的信号发送(TX)、信号接收(RX)或者同步时钟(CLK)等等。可以说GPIO是学习和使用一款MCU首先要学习和掌握的。

所以,本文首先介绍S32K1xx系列MCU的GPIO功能特性,然后再详细介绍S32K SDK中相应的Processor Expert 组件--PinSettings的配置和使用,以帮助大家更好的使用S32K的GPIO。

1. S32K1xx系列MCU的引脚功能特性详解(PORT和GPIO模块)

S32K1xx系列MCU的引脚功能由以下两个模块配置和控制:

① PORT--引脚端口功能复用和中断模块;

② GPIO--引脚做GPIO功能时的输入输出配置/控制模块;

S32K1xx系列MCU的引脚信号复用框图如下,

引脚的PAD结构图如下,其控制引脚的输出驱动(Output Driver)、输入接收器(Input Receiver)/缓冲器(Input Buffer)和上下拉逻辑(Pull logic):

其中控制信号配置的真值表如下:

输出关闭(obe=0)时:输出缓冲器关闭,引脚pad为高阻态(若输入缓冲器未使能);

输出使能(obe=1)时:输出缓冲器使能,引脚pad为GPIO输出控制寄存器状态或者复用外设的输出;

输入关闭(ibe=0)时:输入缓冲器关闭,内部读取输入值为低;

输入使能(ibe=1)时:输入缓冲器使能,内部读取输入值为反映引脚pad外部输入状态;

可以通过pue和pus配置是否使能引脚pad的上下拉功能,以及具体为上拉还是下拉;

Tips:S32K1xx系列MCU的引脚并不是全部都支持开漏输出(OD), 只有配置为需要开漏结构的外设功能时才自动工作在开漏模式,在PCR寄存器中也没有控制开漏的配置位。

Tips:S32K1xx系列MCU复位后大多数引脚的默认配置为disable状态,也就是三态(tristate),若该引脚有ADC输入通道的复用,则为ADC模拟信号输入,否则,该引脚既不做GPIO也不复用任何外设功能;

Tips:对于引脚裁剪封装的part,比如LQFP-64封装的S32K144,其未扇出的(Unbonded)的引脚,用户无法使用,默认配置也是disable的以避免额外的功耗,因此,不要擅自修改其端口配置寄存器(PCR);

Tips:S32K1xx系列MCU的特殊功能引脚复用后默认配置都是使能的,需要特别注意。

S32K1xx系列MCU的特殊功能引脚如下:

①调试接口--JTAG/SWD引脚,SWD的SWD_CLK和SWD_IO引脚分别与JTAG的TMS和TCK复用:


②系统功能--RESET复位、不可屏蔽中断NMI、时钟输出CLKOUT:


③外部时钟/晶振--OSC引脚, XTAL与EXTAL:


④系统跟踪调试--TRACE引脚

S32K142/4/6只有SWO(单线输出跟踪):

而S32K148除了SWO之外还有ETM(嵌入式跟踪模块)的时钟和数据信号引脚:

其中, SWD/JTAG调试接口的时钟信号--SWDCLK/JTAG_TCK,与PTC4复用,其默认配置是下拉的,所以不能再外部接上拉电阻,否则会带来额外的功耗,尤其是在低功耗模式下要特别注意。


1.1 S32K1xx的PORT模块配置寄存器介绍

① 引脚控制寄存器(PORT_PCRn)

S32K1xx系列MCU的PORT模块寄存器地址映射时,为每一个端口PORT分配了32个PCR寄存器,意味着每个端口最多支持32个引脚PIN。但是实际不同part各组端口(PORTA/B/C/B/E)的引脚(GPIO PIN)数不同:

PCR寄存器用于配置某个引脚的PAD特性,包括:

PE:上下拉是否使能, 1->使能,0->关闭;

PS:上下拉选择,1->上拉(Pullup),0->下拉(Pulldown)

PFE:被动滤波器使能选择,1->使能,0->关闭;

DSE:驱动能力选择, 当此引脚配置为数字输出口时:1->强驱动,0->普通驱动;

MUX:引脚外设功能复用选择, 用于该引脚的复用功能, MUX = 0b000 -> 引脚disable,若有ADC输入通道复用,则为ADC输入功能;MUX = 0b0001 -> GPIO,通用输入输出功能;

LK:写保护锁, 1 -> PCR[15:0]锁定,不允许重新配置,直到下次系统复位为止, 0 ->  PCR[15:0]未锁定,允许重配置;

IRQC:引脚中断配置,配置中断状态标志位(ISF)置位的条件:IRQC = 0b0000 -> 中断关闭;IRQC = 0b0001 -> 上升沿触发,产生DMA请求;IRQC = 0b0010 -> 下升沿触发,产生DMA请求;IRQC = 0b0011 -> 上升沿或下降沿触发,产生DMA请求;IRQC = 0b1000 -> 低电平触发,产生CPU中断请求;IRQC = 0b1001 -> 上升沿触发,产生CPU中断请求;IRQC = 0b1010 -> 下升沿触发,产生CPU中断请求;IRQC = 0b1011 -> 上升沿或下降沿触发,产生CPU中断请求;IRQC = 0b1100 -> 高电平触发,产生CPU中断请求;其余配置为保留;

ISF:中断状态标志位,该bit的置位条件由IRQC配置。0 -> 中断未发生;1 ->中断发生:若配置为产生DMA请求,则DMA请求传输完成后被自动清除,若配置为产生CPU中断,则该位置1,直到CPU写1清除。若配置为电平中断,则该中断标志位会保持置1直到中断电平变化;

PCR寄存器定义如下:

② 全局引脚控制寄存器(PORT_GPCL/HR)

除了PCR寄存器之外,S32K1xx的PORT模块还提供了全局引脚控制低寄存器(PORT_GPCLR)、全局引脚控制高寄存器(PORT_GPCHR)用于对通过相同功能属性配置(PCR[15:0])的同一个PORT的多个引脚进行快速配置:

每个PORT有一个PORT_GPCLR和一个PORT_GPCHR寄存器分别配置该PORT的低16个引脚和高16个引脚的PCR寄存器配置,这两个寄存器的该16-bit为写使能配置位,每个GPWE位对应一个引脚,使能(对应位为1)时,GPWD配置对该引脚的PCR寄存器写有效,否则无效:


③ 全局中断控制寄存器(PORT_GICL/HR)

此外,每个PORT还提供了全局中断控制低寄存器(PORT_GICLR)、全局中断控制高寄存器(PORT_GICHR)用于快速配置该PORT的相同中断配置(PCR[31:16])的多个引脚中断配置,其工作原理与全局引脚控制高低寄存器类似:

Tips:以上全局控制寄存器提供了一种高效配置引脚PCR寄存器的方法,以便快速实现S32K1xx系列MCU引脚的配置,在实现功能安全要求的外设功能自测可以使用,以节约引脚PCR寄存器配置时间。

④ 端口中断状态标志寄存器(PORT_ISFR)

此外,S32K1xx系列MCU的PORT模块还提供了32-bit的中断状态标志寄存器(PORT_ISFR),该寄存器每一个写1清0(w1c) 的bit位对应一个引脚的中断状态,1 ->中断发生, 0 -> 中断未发生,与相应引脚的PCR[ISF]一一对应:


⑤ 数字滤波器配置寄存器(PORT_DFER/DFCR/PORT_DFWR)

S32K1xx系列MCU的PORT模块还为每个GPIO引脚提供了一个数字滤波器,以实现对输入信号噪声过滤的作用。其通过以下寄存器进行配置:

数字滤波器使能寄存器(PORT_DFER), 该寄存器每一个bit位配置相应PORT引脚的输入数字滤波器是否使能:1 -> 使能, 0 -> 关闭:

数字滤波器时钟选择寄存器(PORT_DFCR):该寄存器仅最低bit位有效,用于选择该PORT输入引脚数字滤波器的参考时钟:1 -> 使用低功耗时钟(LPO_CLK), 0 -> 使用总线时钟(BUS_CLK)

数字滤波器宽度配置寄存器(PORT_DFWR):该寄存器的仅最低5个bit位FILT[4:0]有效,用于配置PORT的引脚输入数字滤波器滤波宽度,只有大于FILT[4:0] 个滤波时钟周期的信号才能被MCU识别:


1.2 S32K1xx的GPIO模块配置与状态寄存器介绍

S32K1xx系列MCU的GPIO模块,为每个MCU引脚配置为通用输入输出(GPIO)功能时的输入和输出操作提供了用户接口寄存器,包括:

32-bit的端口数据输出寄存器(PDOR):每个bit位对应一个GPIO引脚,1 ->输出高电平, 0 -> 输出低电平;

32-bit的端口数据置位输出寄存器(PSOR):每个写1有效的bit位对应一个GPIO引脚,1 ->输出高电平, 0 -> 不影响输出电平状态;

32-bit的端口数据清除输出寄存器(PCOR):每个写1有效的bit位对应一个GPIO引脚,1 ->输出低电平, 0 -> 不影响输出电平状态;

32-bit的端口数据翻转输出寄存器(PTOR):每个写1有效的bit位对应一个GPIO引脚,1 ->翻转输出电平, 0 -> 不影响输出电平状态;

32-bit的端口数据输入寄存器(PDIR):每个bit位对应一个GPIO引脚,1 ->输入高电平, 0 -> 输入低电平;

32-bit的端口数据方向寄存器(PDDR):每个bit位对应一个GPIO引脚,1 -> 引脚数据方向为输出, 0 -> 引脚数据方向为输入;

32-bit的端口输入关闭寄存器(PIDR):每个bit位对应一个GPIO引脚,1 -> 引脚输入关闭,对PDIR相应bit位为0, 0 -> 引脚配置为通用输入功能;

1.3 S32K1xx系列MCU的GPIO IRQ中断

S32K1xx系列MCU的每个GPIO引脚都有IRQ中断功能,具体配置请参考1.1小节介绍。

S32K11x系列MCU的GPIO引脚中断向量分配如下,所有PORT的全部GPIO引脚共用一个中断向量(Interrupt Vector):


S32K14x系列MCU的GPIO引脚中断向量分配如下,每一个PORT的若干GPIO引脚共用一个中断向量(Interrupt Vector):

因此,在GPIO引脚的中断ISR函数中,用户需要读取各个PORT的中断标志寄存器(PORT->ISFR)来判断具体是哪一个GPIO引脚发生了中断,然后做相应的处理并清除对应的中断标志位,具体请参考本文的3.3小节。

Tips:使用时将用到的GPIO引脚中断尽量分配到同一个PORT,可以减少中断ISR,缩短查询中断的时间--仅读取一个PORT的ISFR寄存器即可进行判断。

Tips:在基于S32K1xx SDK的S32K1xx系列MCU应用工程启动文件(S32K1xx_Startup.s)中,已经通过弱符号(Weak Symbol)定义了所有的外设中断ISR。

比如,在S32DS使用的GCC编译器启动文件中,S32K11x系列MCU的中断ISR定义如下:

.long PORT_IRQHandler /* Port A, B, C, D and E pin detect interrupt */
而S32K14x系列MCU的中断ISR定义如下:





.long   PORTA_IRQHandler   /* Port A pin detect interrupt*/.long   PORTB_IRQHandler   /* Port B pin detect interrupt*/.long   PORTC_IRQHandler   /* Port C pin detect interrupt*/.long   PORTD_IRQHandler   /* Port D pin detect interrupt*/.long   PORTE_IRQHandler   /* Port E pin detect interrupt*/
然后使用默认死循环的中断ISR(DefaultISR)进行了替换:























.align 1 .thumb_func .weak DefaultISR .type DefaultISR, %functionDefaultISR: b DefaultISR .size DefaultISR, . - DefaultISR
/* Macro to define default handlers. Default handler * will be weak symbol and just dead loops. They can be * overwritten by other handlers */ .macro def_irq_handler handler_name .weak \handler_name .set \handler_name, DefaultISR .endm /* Exception Handlers */ 。。。。。。。。。。 def_irq_handler LPTMR0_IRQHandler def_irq_handler PORTA_IRQHandler def_irq_handler PORTB_IRQHandler def_irq_handler PORTC_IRQHandler def_irq_handler PORTD_IRQHandler def_irq_handler PORTE_IRQHandler
所以用户有两种方式写S32K1xx系列MCU的GPIO引脚中断ISR:

方法一、在任意C文件中定义与启动文件中PORT中断ISR同名的无参数无返回(void)类型函数

比如S32K14x系列MCU的PORTA中断ISR实现如下:

















void PORTA_IRQHandler(void){    uint32_t Port_IntFlag = 0;       /* read the PORT interrupt flags*/   Port_IntFlag = PINS_DRV_GetPortIntFlag(PORTA);     if(Port_IntFlag & (1<<3))     {         /*         *the PTA3 PIN IRQ interrupt happaned,          *add corresponding user handle code here         */              /* clean the PTA3 interrupt flag bit */         PINS_DRV_ClearPinIntFlagCmd(PORTA,3);     }}
方法二、先在任意C文件中定义无参数无返回(void)类型的指定ISR函数,然后调用Interrupt_Manager组件提供的

比如同样功能的S32K14x系列MCU的PORTA中断ISR实现如下:

先定义PTA3的中断ISR函数:

















void User_Button_IRQ_ISR(void){ uint32_t Port_IntFlag = 0; /* read the PORT interrupt flags*/ Port_IntFlag = PINS_DRV_GetPortIntFlag(PORTA); if(Port_IntFlag & (1<<3)) { /* *the PTA3 PIN IRQ interrupt happaned, *add corresponding user handle code here */ /* clean the PTA3 interrupt flag bit */ PINS_DRV_ClearPinIntFlagCmd(PORTA,3); }}
然后,调用InterruptManager组件的INT_SYS_InstallHandler()注册该中断ISR到PORTA的中断向量表中:




/** install PORTA IRQ interrupt ISR*/INT_SYS_InstallHandler(PORTA_IRQn, User_Button_IRQ_ISR, NULL);
PinSettings组件的初始化函数只是配置使能了S32K1xx系列MCU的GPIO引脚中断,用户还需要调用InterruptManager组件的INT_SYS_EnableIRQ(),使能其对应的NVIC IRQ中断:




/** enable PORTC IRQ interrupt */INT_SYS_EnableIRQ(PORTA_IRQn);
2. PinSettings组件配置的S32K1xx系列MCU硬件模块

在S32K1xx SDK中,提供了外设驱动层(PD)的PinSettings组件,用于配置S32K1xx系列MCU的PORT和GPIO功能,并提供相应的底层驱动API函数。

其与CPU组件和clock_manager组件以及interrupt_manager组件一起作为默认组件添加到使用SDK工程的S32K1xx系列MCU应用工程中,无需用户自己手动添加:

接下来,本章节就来详细介绍一下其属性配置和API函数功能以及使用Tips。

2.1 PinSettings组件属性配置详解

在SDK组件的处理器专家组件视窗(Component Inspector)中可以看到PinSettings组件的属性配置界面如下:

在其信号分配(Routing)栏,提供了按外设模块区分的MCU引脚功能复用和方向配置:

① ADC输入通道引脚映射配置

从上面的介绍可知,S32K1xx系列MCU的引脚若有ADC输入的功能,则其默认配置(PCR[MUX] = 0b0000)就是ADC输入功能,而且对于大部分ADC输入通道来说只有一个引脚映射,所以无需用户特别配置。其用户配置界面如下:

只有在S32K14x系列MCU中,为了支持BLDC/PMSM三相电机的三电阻采样方案,ADC0与ADC1之间有有交错(interleave)功能的4个ADC通道(ADC0_CH8/9和ADC1_CH14/15),需要用户进行引脚映射配置,以匹配硬件设计:


② CAN/LPI2C/LPSPI/LPUART通信模块引脚映射配置

S32K1xx系列MCU集成了多达3路FlexCAN通信模块,每个FlexCAN模块需要配置其发送(TXD)和接收(RXD)的引脚。默认是未使用的(No pin routed),使用CAN模块时,用户必须根据实际硬件设计从下拉菜单中选择正确的引脚映射,其用户配置界面如下:

LPI2C模块的引脚映射配置界面如下, 由于存在多种引脚映射可能,默认是未使用的(No pin routed), 使用时用户需要根据实际需求配置主机请求(Host Request), 串行时钟(Serial Clock),串行数据(Serial Data)以及次串行时钟(Secondary  Serial Clock)和次串行数据(Secondary Serial Data):

LPSPI模块的引脚映射配置界面如下, 由于存在多种引脚映射可能,默认是未使用的(No pin routed), 使用时用户需要根据实际需求配置外设片选(PCS0~3)、串行时钟(Serial Clock),串行数据输入(Serial Data Input)和串行数据输出(Serial Data Output),并根据Master和Slave选择配置正确的信号传输方向:

LPUART模块的引脚映射配置界面如下, 由于存在多种引脚映射可能,默认是未使用的(No pin routed), 使用时用户需要根据实际需求配置清除发送(Clear to Send)、请求发送(Request to Send),接收数据(RXD)和发送数据(TXD),并根据LPUART功能选择配置TXD的信号传输方向:

③ CMP模块引脚映射配置

S32K1xx系列MCU片上模拟比较器CMP模块,大多数功能引脚也是唯一的映射,且为模拟功能,无需用户配置,但输入1(Analog Input 1)和输出(Analog Output)以及轮回触发输出(Round Robin Port Output Trigger)有多个引脚映射,默认未使用的(No pin routed),使用时,用户必须根据实际硬件设计从下拉菜单中选择正确的引脚映射,其用户配置界面如下:


④ EWM模块引脚映射配置

S32K1xx系列MCU的外面看门狗检测EWM模块,需要配置输入输出信号的引脚映射。由于存在多种引脚映射可能,默认是未使用的(No pin routed),使用时,用户必须根据实际硬件设计从下拉菜单中选择正确的引脚映射,其用户配置界面如下:


⑤ FlexIO模块引脚映射配置

S32K1xx系列MCU的FlexIO模块,用8个数据端口,需要配置其引脚映射。由于存在多种引脚映射可能,默认是未使用的(No pin routed),使用时,用户必须根据实际硬件设计从下拉菜单中选择正确的引脚映射,其用户配置界面如下:


⑥ FlexTimer/LPTMR/RTC定时器模块引脚映射配置

S32K1xx系列MCU集成了若干FlexTimer(FTM)定时器模块,每个FlexTimer模块有1一个外部参考时钟输入信号,8个通道信号和4个失效输入信号可以配置引脚映射。由于存在多种引脚映射可能,默认都是未使用的(No pin routed),使用时,用户必须根据实际硬件设计从下拉菜单中选择正确的引脚映射,对应FTM通道,还需要配置其信号方向,比如用作输入捕捉(IC)功能时为方向为输入,而输出比较(OC)和PWM功能时则为输出。其用户配置界面如下:

除了FlexTimer外,S32K1xx系列MCU还有一个LPTMR低功耗定时器模块,其支持输入脉冲计数功能,由于存在多种引脚映射可能,默认都是未使用的(No pin routed使用时需要配置其外部脉冲输入信号引脚映射。其用户配置界面如下:

S32K1xx系列MCU的RTC定时器功能引脚配置界面如下,其支持外部32.768KHz有源时钟输入作为其工作参考时钟(Clock Input)和对RTC_CLK的输出(Clock Output), 如有使用,需要在此配置:


⑦ GPIO模块引脚映射配置

S32K1xx系列MCU的引脚用作通用GPIO功能时,需要通过如下界面,配置其端口引脚(PORT->GPIO PIN)信号选择和方向。默认是未使用的(No pin routed):


⑧ SWD/JTAG/Platform/PowerAndFround引脚映射配置

这些界面通常用户无需关心,使用其默认配置即可。

JTAG和SWD为S32K1xx系列MCU的调试接口引脚映射配置,在使用SWD调试接口时,可以将JTAG接口的TDO(PTC5)和TDO(PTA10)引脚用作其他外设功能。

在Platform界面,用户可以配置CLKOUT时钟输出引脚映射、NMI-不可屏蔽内核异常输入、RESET系统复位输入和外设晶振信号(EXTAL/XTAL)的引脚映射:

Tips:用户需要十分小心对JTAG/SWD调试接口和Platform界面的RESET复位引脚信号映射的配置,关闭这些引脚会导致调试器连接失败。下次连接调试器必须在PinSettings配置生效前。

另外,在PinSettings组件的功能实现(Functional Properties)栏,提供了对每个MCU引脚的PORT_PCR寄存器属性配置:

其中,包括:

① Interrupt Flag:中断标志位ISF,是否在初始化时清除(写1清0): Don't modify(默认配置) -> 不清除;Clear Flag -> 写1清零;

② Interrupt :中断条件配置,具体参考前面章节介绍,默认配置为关闭中断:Interrupt Status Flag(ISF) is disabled:


③ Pin Mux:引脚功能复用,具体参见前面章节介绍,默认配置为关闭引脚或者模拟信号(ADC或者ACMP输入)功能:Pin disabled(引脚复用功能推荐在PinSettings组件的Routing一栏按照外设模块功能分类进行配置):

④ Lock:运行配置锁配置,具体参考前面章节介绍,Unlocked( 默认配置) -> 关闭,允许运行时重新配置PCR寄存器; locked -> 使能,禁止运行时重新配置PCR寄存器;  

⑤ Pull Enable:使能上下拉配置,Disable( 默认配置) -> 关闭;Enable -> 使能;

⑥ Pull Select:上下拉选择配置,Pull Down( 默认配置) -> 下拉;Pull Up-> 上拉;

⑦ Digital Filter:数字滤波器配置,Disable( 默认配置) -> 关闭;Enable -> 使能;

⑧ Drive Strength:电流驱动强度配置,Low( 默认配置) -> 低;High-> 高(仅对大电流IO可用,输出驱动电流可达20mA);

⑨ Passive Filter:被动滤波器配置,仅对NMI(PTD3)和RESET(PTA5)引脚可用;Enable -> 使能;

⑩ Initial Value:GPIO输出初始化电平配置,Low( 默认配置) -> 低电平;High-> 高电平;

⑪ ADC Interleave:ADC交错功能配置(仅对S32K14x系列MCU可用):Not muxed in SIM_CHIPCTL( 默认配置) ->使用默认配置;muxed in SIM_CHIPCTL ->由SIM_CHIPCTL配置;

Tips:以上②~⑩的PCR寄存器配置的默认配置与芯片设计相同,具体请参考S32K1xx系列MCU的参考手册附件excel--S32K1xx_IO_Signal_Description_Input_Multiplexing.xlsx;

如下为S32K144的引脚配置表内容:


2.2 PinSettings组件API函数详解

PinSettings组件提供了丰富的API函数供用户调用:

通常,用户对引脚的绝多数功能配置都可以由2.1小节介绍的配置界面图形化方式配置,由Processor Expert生成初始化配置结果,在应用工程Generated_Code目录下,由pin_mux.c/pin_mux.h保存:

用户只需在main()函数中,完成系统时钟初始化后拖拽(Drag & Drop)调用初始化API- -PINS_DRV_Init()函数即可完成引脚配置:

若用户需要配置某个引脚的数组滤波器,则需手动调用如下API函数:


































/*! * @brief Enables digital filter for digital pin muxing * * This function enables digital filter feature for digital pin muxing * * @param[in] base Port base pointer (PORTA, PORTB, PORTC, etc.) * @param[in] pin Port pin number */void PINS_DRV_EnableDigitalFilter(PORT_Type * const base,                                  uint32_t pin);
/*! * @brief Disables digital filter for digital pin muxing * * This function disables digital filter feature for digital pin muxing * * @param[in] base Port base pointer (PORTA, PORTB, PORTC, etc.) * @param[in] pin Port pin number */void PINS_DRV_DisableDigitalFilter(PORT_Type * const base, uint32_t pin);
/*! * @brief Configures digital filter for port with given configuration * * This function configures digital filter for port with given configuration * * Note: Updating the filter configuration must be done only after all filters are disabled. * * @param[in] base Port base pointer (PORTA, PORTB, PORTC, etc.) * @param[in] config the digital filter configuration struct */void PINS_DRV_ConfigDigitalFilter(PORT_Type * const base, const port_digital_filter_config_t * const config);
若用户需要输出或者读取输入GPIO引脚电平,则可以调用以下API函数:








































































































/*! * @brief Write a pin of a port with a given value * * This function writes the given pin from a port, with the given value * ('0' represents LOW, '1' represents HIGH). * * @param[in] base GPIO base pointer (PTA, PTB, PTC, etc.) * @param[in] pin Pin number to be written * @param[in] value Pin value to be written * - 0: corresponding pin is set to LOW * - 1: corresponding pin is set to HIGH */void PINS_DRV_WritePin(GPIO_Type * const base, pins_channel_type_t pin, pins_level_type_t value);
/*! * @brief Write all pins of a port * * This function writes all pins configured as output with the values given in * the parameter pins. '0' represents LOW, '1' represents HIGH. * * @param[in] base GPIO base pointer (PTA, PTB, PTC, etc.) * @param[in] pins Pin mask to be written * - 0: corresponding pin is set to LOW * - 1: corresponding pin is set to HIGH */void PINS_DRV_WritePins(GPIO_Type * const base, pins_channel_type_t pins);
/*! * @brief Get the current output from a port * * This function returns the current output that is written to a port. Only pins * that are configured as output will have meaningful values. * * @param[in] base GPIO base pointer (PTA, PTB, PTC, etc.) * @return GPIO outputs. Each bit represents one pin (LSB is pin 0, MSB is pin * 31). For each bit: * - 0: corresponding pin is set to LOW * - 1: corresponding pin is set to HIGH */pins_channel_type_t PINS_DRV_GetPinsOutput(const GPIO_Type * const base);
/*! * @brief Write pins with 'Set' value * * This function configures output pins listed in parameter pins (bits that are * '1') to have a value of 'set' (HIGH). Pins corresponding to '0' will be * unaffected. * * @param[in] base GPIO base pointer (PTA, PTB, PTC, etc.) * @param[in] pins Pin mask of bits to be set. Each bit represents one pin (LSB is * pin 0, MSB is pin 31). For each bit: * - 0: corresponding pin is unaffected * - 1: corresponding pin is set to HIGH */void PINS_DRV_SetPins(GPIO_Type * const base, pins_channel_type_t pins);
/*! * @brief Write pins to 'Clear' value * * This function configures output pins listed in parameter pins (bits that are * '1') to have a 'cleared' value (LOW). Pins corresponding to '0' will be * unaffected. * * @param[in] base GPIO base pointer (PTA, PTB, PTC, etc.) * @param[in] pins Pin mask of bits to be cleared. Each bit represents one pin (LSB * is pin 0, MSB is pin 31). For each bit: * - 0: corresponding pin is unaffected * - 1: corresponding pin is cleared(set to LOW) */void PINS_DRV_ClearPins(GPIO_Type * const base, pins_channel_type_t pins);
/*! * @brief Toggle pins value * * This function toggles output pins listed in parameter pins (bits that are * '1'). Pins corresponding to '0' will be unaffected. * * @param[in] base GPIO base pointer (PTA, PTB, PTC, etc.) * @param[in] pins Pin mask of bits to be toggled. Each bit represents one pin (LSB * is pin 0, MSB is pin 31). For each bit: * - 0: corresponding pin is unaffected * - 1: corresponding pin is toggled */void PINS_DRV_TogglePins(GPIO_Type * const base, pins_channel_type_t pins);
/*! * @brief Read input pins * * This function returns the current input values from a port. Only pins * configured as input will have meaningful values. * * @param[in] base GPIO base pointer (PTA, PTB, PTC, etc.) * @return GPIO inputs. Each bit represents one pin (LSB is pin 0, MSB is pin * 31). For each bit: * - 0: corresponding pin is read as LOW * - 1: corresponding pin is read as HIGH */pins_channel_type_t PINS_DRV_ReadPins(const GPIO_Type * const base);
在GPIO输入引脚的IRQn中断ISR函数中,用户需要调用一下API函数,判断具体的中断引脚并清除相应的中断标志(ISF):




























/*! * @brief Clears the individual pin-interrupt status flag. * * This function clears the individual pin-interrupt status flag. * * @param[in] base Port base pointer (PORTA, PORTB, PORTC, etc.) * @param[in] pin Port pin number */void PINS_DRV_ClearPinIntFlagCmd(PORT_Type * const base,                                 uint32_t pin);/*! * @brief Reads the entire port interrupt status flag * * This function reads the entire port interrupt status flag. * * @param[in] base Port base pointer (PORTA, PORTB, PORTC, etc.) * @return All 32 pin interrupt status flags */uint32_t PINS_DRV_GetPortIntFlag(const PORT_Type * const base);
/*! * @brief Clears the entire port interrupt status flag. * * This function clears the entire port interrupt status flag. * * @param[in] base Port base pointer (PORTA, PORTB, PORTC, etc.) */void PINS_DRV_ClearPortIntFlagCmd(PORT_Type * const base);
其他有用的API函数还有全局引脚控制(PINS_DRV_SetGlobalPinControl())和中断控制(PINS_DRV_SetGlobalIntControl())配置函数:











































/*! * @brief Quickly configures multiple pins with the same pin configuration. * * This function quickly configures multiple pins within the one port for the same peripheral * function with the same pin configuration. Supports up to 16 pins with the lower or upper * half of pin registers at the same port. * * Note: The set global interrupt control function (PINS_DRV_SetGlobalIntControl) cannot be * configured if you ever used this function at the same port * * @param[in] base Port base pointer (PORTA, PORTB, PORTC, etc.) * @param[in] pins Pin mask where each bit represents one pin. For each bit: * - 0: pins corresponding to bits with value of '1' is updated with the value input * - 1: pins corresponding to bits with value of '0' is not updated with the value input * @param[in] value the config value will be updated for the pins are set to '1' * @param[in] halfPort the lower or upper half of pin registers at the same port */void PINS_DRV_SetGlobalPinControl(PORT_Type * const base, uint16_t pins, uint16_t value, port_global_control_pins_t halfPort);
/*! * @brief Quickly configures multiple pins with the same interrupt configuration. * * This function quickly configures multiple pins within the one port for the same peripheral * function with the same interrupt configuration. Supports up to 16 pins with the lower or * upper half of pin registers at the same port. * * Note: The set global pin control function (PINS_DRV_SetGlobalPinControl) cannot be * configured if you ever used this function at the same port * * @param[in] base Port base pointer (PORTA, PORTB, PORTC, etc.) * @param[in] pins Pin mask where each bit represents one pin. For each bit: * - 0: pins corresponding to bits with value of '1' is updated with the value input * - 1: pins corresponding to bits with value of '0' is not updated with the value input * @param[in] value the config value will be updated for the pins are set to '1' * @param[in] halfPort the lower or upper half of pin registers at the same port */void PINS_DRV_SetGlobalIntControl(PORT_Type * const base, uint16_t pins, uint16_t value, port_global_control_pins_t halfPort);
2.3 PinSettings组件使用Tips

调用PinSettings组件的API函数时,需要注意以下事项:

① API函数参数是PORT_Type 还是GPIO_Type ?

若是PORT_Type ,则合法的参数为: PORTA/PORTB/PORTC/PORTD/PORTE;


























/* PORT - Peripheral instance base addresses *//** Peripheral PORTA base address */#define PORTA_BASE                               (0x40049000u)/** Peripheral PORTA base pointer */#define PORTA                                    ((PORT_Type *)PORTA_BASE)/** Peripheral PORTB base address */#define PORTB_BASE                               (0x4004A000u)/** Peripheral PORTB base pointer */#define PORTB                                    ((PORT_Type *)PORTB_BASE)/** Peripheral PORTC base address */#define PORTC_BASE                               (0x4004B000u)/** Peripheral PORTC base pointer */#define PORTC                                    ((PORT_Type *)PORTC_BASE)/** Peripheral PORTD base address */#define PORTD_BASE                               (0x4004C000u)/** Peripheral PORTD base pointer */#define PORTD                                    ((PORT_Type *)PORTD_BASE)/** Peripheral PORTE base address */#define PORTE_BASE                               (0x4004D000u)/** Peripheral PORTE base pointer */#define PORTE                                    ((PORT_Type *)PORTE_BASE)/** Array initializer of PORT peripheral base addresses */#define PORT_BASE_ADDRS                          { PORTA_BASE, PORTB_BASE, PORTC_BASE, PORTD_BASE, PORTE_BASE }/** Array initializer of PORT peripheral base pointers */#define PORT_BASE_PTRS                           { PORTA, PORTB, PORTC, PORTD, PORTE }
若是GPIO_Type ,则合法的参数为: PTA/PTB/PTC/PTD/PTE;

























/* GPIO - Peripheral instance base addresses *//** Peripheral PTA base address */#define PTA_BASE (0x400FF000u)/** Peripheral PTA base pointer */#define PTA ((GPIO_Type *)PTA_BASE)/** Peripheral PTB base address */#define PTB_BASE (0x400FF040u)/** Peripheral PTB base pointer */#define PTB ((GPIO_Type *)PTB_BASE)/** Peripheral PTC base address */#define PTC_BASE (0x400FF080u)/** Peripheral PTC base pointer */#define PTC ((GPIO_Type *)PTC_BASE)/** Peripheral PTD base address */#define PTD_BASE (0x400FF0C0u)/** Peripheral PTD base pointer */#define PTD ((GPIO_Type *)PTD_BASE)/** Peripheral PTE base address */#define PTE_BASE (0x400FF100u)/** Peripheral PTE base pointer */#define PTE ((GPIO_Type *)PTE_BASE)/** Array initializer of GPIO peripheral base addresses */#define GPIO_BASE_ADDRS { PTA_BASE, PTB_BASE, PTC_BASE, PTD_BASE, PTE_BASE }/** Array initializer of GPIO peripheral base pointers */#define GPIO_BASE_PTRS { PTA, PTB, PTC, PTD, PTE }

② API函数参数是Pin Mask还是PIN Number?
比如写GPIO输出的以下两个API函数:



void PINS_DRV_WritePin(GPIO_Type * const base,                       pins_channel_type_t pin,                       pins_level_type_t value);


void PINS_DRV_WritePins(GPIO_Type * const base, pins_channel_type_t pins);
PINS_DRV_WritePin()的第二个参数pin为Pin Number,而PINS_DRV_WritePins()的第二个参数pins为Pin Mask:

所以要在PTA3上输出高电平,以上两个函数的调用如下:


PINS_DRV_WritePin(PTA, 3, 1);/*output high on PTA3*/PINS_DRV_WritePins(PTA, 1<<3 );/*output high on PTA3*/
而要在PTA3上输出低电平,则调用如下:


PINS_DRV_WritePin(PTA, 3, 0);/*output low on PTA3*/PINS_DRV_WritePins(PTA, 0<<3 );/*output low on PTA3*/
Tips:以上API函数中均是对GPIO->PDOR寄存器的操作,不同之处在于前者是读改写的操作,不会影响同一个PORT的其他引脚输出状态,而后者则是直接将值写入GPIO->PDOR寄存器,会影响同一个PORT的其他引脚输出状态;

Tips:对GPIO引脚输出状态控制时,更为推荐使用如下API函数,其分别对GPIO->PSOR寄存器(输出高电平)、GPIO->PCOR寄存器(输出低电平)和GPIO->PTOR寄存器(翻转输出电平)的pin mask操作,更为高效快捷(具体请参考1.2小节相关寄存器介绍):






void PINS_DRV_SetPins(GPIO_Type * const base,                      pins_channel_type_t pins);void PINS_DRV_ClearPins(GPIO_Type * const base,                        pins_channel_type_t pins);void PINS_DRV_TogglePins(GPIO_Type * const base,                         pins_channel_type_t pins);
③ 减少Processor Expert生成的引脚配置代码量和引脚初始化时间

将PinSettings组件的Settings栏 -> Generate configured Pins only选择为 “yes”,则仅生成配置与默认复位配置不同的引脚配置数据,从而减少生成的引脚初始配置代码量,同时也将减少引脚初始化时间;否则(选择为“NO”),将为每个引脚都生成初始化配置参数:


3. 基于S32K144-EVB的GPIO IRQ中断控制RGB LED亮灭样例工程

为了帮助大家更好的理解本文所讲内容,接下来,将以S32K144-EVB为例,介绍如何配置使用GPIO引脚输入中断和输出高低电平。

3.1 S32K144-EVB的用户按键输入硬件设计及其PinSettings组件GPIO中断配置

S32K144-EVB的2个用户按键输入电路设计如下:

相应的GPIO引脚映射如下:

按键

S32K144 GPIO端口

SW2

PTC12

SW3

PTC13

首先,在PinSettings组件的Routing栏GPIO中配置PTC12和PTC13为方向(Direction)为输入(Input):

然后,在PinSettings组件的Functional Properties栏,配置PTC12和PTC13的中断条件为上升沿触发CPU IRQ中断并使能内部下拉及数字滤波器:


3.2 S32K144-EVB的RGB LED硬件设计及其PinSettings组件GPIO输入配置

S32K144-EVB的3个用户RGB LED电路设计如下:

相应的GPIO引脚映射如下:

RGB LED

S32K144 GPIO端口

RED

PTD15

GREEN

PTD16

BLUE

PTD0

首先,在PinSettings组件的Routing栏GPIO中配置PTD0、PTD15和PTD16为输出:

然后,在PinSettings组件的Functional Properties栏,配置PTD0、PTD15和PTD16的初始值(Initial Value)为High,从而保证RGB LED在GPIO初始化后为熄灭状态:


3.3 GPIO IRQ中断控制RGB LED亮灭功能代码实现

首先,定义用户按键和RGB LED引脚PORT和GPIO PIN如下:








#define BUTTON_PORT PORTC /*PORT_Type*/#define SW2_PIN 12#define SW3_PIN 13 #define LED_GPIO PTD /*GPIO_Type*/#define BLUE_PIN 0#define RED_PIN 15 #define GREEN_PIN 16
然后, 编写PORTC中断ISR函数如下,实现功能为:读取PORTC中断标志位,判断:若发生了SW2中断(用户按下),则翻转GPIO闪烁蓝色RGB LED,并清除相应的引脚中断标志;若发生了SW3中断(用户按下),则翻转GPIO闪烁红色RGB LED,并清除相应的引脚中断标志:

































/************************************************************ * the PORTC IRQ interrupt ISR * toggle RGB LED according to different user button press *  * SW2-->toggle blue LED * SW3-->toggle red LED *  * use API--PINS_DRV_ClearPinIntFlagCmd() to clear GPIO pin * interrupt flag independently to avoid interrupt missing ***********************************************************/void User_Button_IRQ_ISR(void){   uint32_t Port_IntFlag = 0;
/* read the PORT interrupt flags*/ Port_IntFlag = PINS_DRV_GetPortIntFlag(BUTTON_PORT);
if(Port_IntFlag&(1<<SW2_PIN)) /*if SW2 pressed*/ { /*toggle blue LED*/ PINS_DRV_TogglePins(LED_GPIO, 1<<BLUE_PIN); /*clear pin interrupt flag*/ PINS_DRV_ClearPinIntFlagCmd(BUTTON_PORT,SW2_PIN); }
if(Port_IntFlag&(1<<SW3_PIN)) /*if SW3 pressed*/ { /*toggle red LED*/ PINS_DRV_TogglePins(LED_GPIO, 1<<RED_PIN); /*clear pin interrupt flag*/ PINS_DRV_ClearPinIntFlagCmd(BUTTON_PORT,SW3_PIN); }}
最后,调用Interrupt_Manager组件的以下API函数安装(INT_SYS_InstallHandler())以上中断ISR函数并使能PORTC中断(INT_SYS_EnableIRQ())如下:









/** install PORTC IRQ interrupt ISR*/INT_SYS_InstallHandler(PORTC_IRQn, User_Button_IRQ_ISR, NULL);
/** enable PORTC IRQ interrupt */INT_SYS_EnableIRQ(PORTC_IRQn);
总结

本文详细介绍了S32K1xx系列MCU的端口(PORT)和通用输入输出(GPIO)功能特性,以及如何使用S32K1xx SDK提供的Processor Expert PinSettings组件配置MCU引脚的PORT和GPIO功能以及外设功能复用和引脚映射,并基于S32K144-EVB硬件设计详细介绍了其提供的用户API函数使用方法和使用Tips。

-------------------------------------
☆ END ☆

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多