资讯详情

S32K SDK使用详解之PinSettings组件配置与使用详解(S32K1xx PORT 和GPIO模块)

内容提要

引言

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

--

G

eneral

P

orpurse

I

nput

O

utput,通用输入输出端口为嵌入式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引脚信号复用框图如下,

90b636470829876375991726398ba814.png

引脚的

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_IRQHandlerdef_irq_handler PORTA_IRQHandlerdef_irq_handler PORTB_IRQHandlerdef_irq_handler PORTC_IRQHandlerdef_irq_handler PORTD_IRQHandlerdef_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<

最后,调用

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。

标签: 26k1电阻电阻9k1

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台