內(nèi)容提要 1. S32K1xx系列MCU的引腳功能特性詳解(PORT和GPIO模塊)1.1 S32K1xx的PORT模塊配置寄存器介紹 1.2 S32K1xx的GPIO模塊配置與狀態(tài)寄存器介紹 1.3 S32K1xx系列MCU的GPIO IRQ中斷 2. PinSettings組件配置的S32K1xx系列MCU硬件模塊2.1 PinSettings組件屬性配置詳解 2.2 PinSettings組件API函數(shù)詳解 2.3 PinSettings組件使用Tips 3. 基于S32K144-EVB的GPIO IRQ中斷控制RGB LED亮滅樣例工程3.1 S32K144-EVB的用戶按鍵輸入硬件設(shè)計(jì)及其PinSettings組件GPIO中斷配置 3.2 S32K144-EVB的RGB LED硬件設(shè)計(jì)及其PinSettings組件GPIO輸入配置 3.3 GPIO IRQ中斷控制RGB LED亮滅功能代碼實(shí)現(xiàn) GPIO--General Porpurse Input Output,通用輸入輸出端口是嵌入式MCU對(duì)外進(jìn)行信息交換實(shí)現(xiàn)人機(jī)交互(HMI)的重要模塊,MCU片內(nèi)各種功能外設(shè)模塊的功能實(shí)現(xiàn)也大多需要配置GPIO才能實(shí)現(xiàn)---比如將某一GPIO引腳配置為定時(shí)器模塊的輸入捕捉通道(IC)或者輸出比較(OC)通道,或者是作為通信外設(shè)的信號(hào)發(fā)送(TX)、信號(hào)接收(RX)或者同步時(shí)鐘(CLK)等等??梢哉f(shuō)GPIO是學(xué)習(xí)和使用一款MCU首先要學(xué)習(xí)和掌握的。所以,本文首先介紹S32K1xx系列MCU的GPIO功能特性,然后再詳細(xì)介紹S32K SDK中相應(yīng)的Processor Expert 組件--PinSettings的配置和使用,以幫助大家更好的使用S32K的GPIO。1. S32K1xx系列MCU的引腳功能特性詳解(PORT和GPIO模塊)S32K1xx系列MCU的引腳功能由以下兩個(gè)模塊配置和控制:① PORT--引腳端口功能復(fù)用和中斷模塊;② GPIO--引腳做GPIO功能時(shí)的輸入輸出配置/控制模塊;S32K1xx系列MCU的引腳信號(hào)復(fù)用框圖如下,引腳的PAD結(jié)構(gòu)圖如下,其控制引腳的輸出驅(qū)動(dòng)(Output Driver)、輸入接收器(Input Receiver)/緩沖器(Input Buffer)和上下拉邏輯(Pull logic):輸出關(guān)閉(obe=0)時(shí):輸出緩沖器關(guān)閉,引腳pad為高阻態(tài)(若輸入緩沖器未使能);輸出使能(obe=1)時(shí):輸出緩沖器使能,引腳pad為GPIO輸出控制寄存器狀態(tài)或者復(fù)用外設(shè)的輸出;輸入關(guān)閉(ibe=0)時(shí):輸入緩沖器關(guān)閉,內(nèi)部讀取輸入值為低;輸入使能(ibe=1)時(shí):輸入緩沖器使能,內(nèi)部讀取輸入值為反映引腳pad外部輸入狀態(tài);可以通過(guò)pue和pus配置是否使能引腳pad的上下拉功能,以及具體為上拉還是下拉;Tips:S32K1xx系列MCU的引腳并不是全部都支持開(kāi)漏輸出(OD), 只有配置為需要開(kāi)漏結(jié)構(gòu)的外設(shè)功能時(shí)才自動(dòng)工作在開(kāi)漏模式,在PCR寄存器中也沒(méi)有控制開(kāi)漏的配置位。Tips:S32K1xx系列MCU復(fù)位后大多數(shù)引腳的默認(rèn)配置為disable狀態(tài),也就是三態(tài)(tristate),若該引腳有ADC輸入通道的復(fù)用,則為ADC模擬信號(hào)輸入,否則,該引腳既不做GPIO也不復(fù)用任何外設(shè)功能; Tips:對(duì)于引腳裁剪封裝的part,比如LQFP-64封裝的S32K144,其未扇出的(Unbonded)的引腳,用戶無(wú)法使用,默認(rèn)配置也是disable的以避免額外的功耗,因此,不要擅自修改其端口配置寄存器(PCR);Tips:S32K1xx系列MCU的特殊功能引腳復(fù)用后默認(rèn)配置都是使能的,需要特別注意。①調(diào)試接口--JTAG/SWD引腳,SWD的SWD_CLK和SWD_IO引腳分別與JTAG的TMS和TCK復(fù)用:②系統(tǒng)功能--RESET復(fù)位、不可屏蔽中斷NMI、時(shí)鐘輸出CLKOUT:③外部時(shí)鐘/晶振--OSC引腳, XTAL與EXTAL:④系統(tǒng)跟蹤調(diào)試--TRACE引腳S32K142/4/6只有SWO(單線輸出跟蹤):而S32K148除了SWO之外還有ETM(嵌入式跟蹤模塊)的時(shí)鐘和數(shù)據(jù)信號(hào)引腳:其中, SWD/JTAG調(diào)試接口的時(shí)鐘信號(hào)--SWDCLK/JTAG_TCK,與PTC4復(fù)用,其默認(rèn)配置是下拉的,所以不能再外部接上拉電阻,否則會(huì)帶來(lái)額外的功耗,尤其是在低功耗模式下要特別注意。1.1 S32K1xx的PORT模塊配置寄存器介紹S32K1xx系列MCU的PORT模塊寄存器地址映射時(shí),為每一個(gè)端口PORT分配了32個(gè)PCR寄存器,意味著每個(gè)端口最多支持32個(gè)引腳PIN。但是實(shí)際不同part各組端口(PORTA/B/C/B/E)的引腳(GPIO PIN)數(shù)不同:PCR寄存器用于配置某個(gè)引腳的PAD特性,包括:PE:上下拉是否使能, 1->使能,0->關(guān)閉;PS:上下拉選擇,1->上拉(Pullup),0->下拉(Pulldown)PFE:被動(dòng)濾波器使能選擇,1->使能,0->關(guān)閉;DSE:驅(qū)動(dòng)能力選擇, 當(dāng)此引腳配置為數(shù)字輸出口時(shí):1->強(qiáng)驅(qū)動(dòng),0->普通驅(qū)動(dòng);MUX:引腳外設(shè)功能復(fù)用選擇, 用于該引腳的復(fù)用功能, MUX = 0b000 -> 引腳disable,若有ADC輸入通道復(fù)用,則為ADC輸入功能;MUX = 0b0001 -> GPIO,通用輸入輸出功能;LK:寫保護(hù)鎖, 1 -> PCR[15:0]鎖定,不允許重新配置,直到下次系統(tǒng)復(fù)位為止, 0 -> PCR[15:0]未鎖定,允許重配置;IRQC:引腳中斷配置,配置中斷狀態(tài)標(biāo)志位(ISF)置位的條件:IRQC = 0b0000 -> 中斷關(guān)閉;IRQC = 0b0001 -> 上升沿觸發(fā),產(chǎn)生DMA請(qǐng)求;IRQC = 0b0010 -> 下升沿觸發(fā),產(chǎn)生DMA請(qǐng)求;IRQC = 0b0011 -> 上升沿或下降沿觸發(fā),產(chǎn)生DMA請(qǐng)求;IRQC = 0b1000 -> 低電平觸發(fā),產(chǎn)生CPU中斷請(qǐng)求;IRQC = 0b1001 -> 上升沿觸發(fā),產(chǎn)生CPU中斷請(qǐng)求;IRQC = 0b1010 -> 下升沿觸發(fā),產(chǎn)生CPU中斷請(qǐng)求;IRQC = 0b1011 -> 上升沿或下降沿觸發(fā),產(chǎn)生CPU中斷請(qǐng)求;IRQC = 0b1100 -> 高電平觸發(fā),產(chǎn)生CPU中斷請(qǐng)求;其余配置為保留;ISF:中斷狀態(tài)標(biāo)志位,該bit的置位條件由IRQC配置。0 -> 中斷未發(fā)生;1 ->中斷發(fā)生:若配置為產(chǎn)生DMA請(qǐng)求,則DMA請(qǐng)求傳輸完成后被自動(dòng)清除,若配置為產(chǎn)生CPU中斷,則該位置1,直到CPU寫1清除。若配置為電平中斷,則該中斷標(biāo)志位會(huì)保持置1直到中斷電平變化;PCR寄存器定義如下: ② 全局引腳控制寄存器(PORT_GPCL/HR)除了PCR寄存器之外,S32K1xx的PORT模塊還提供了全局引腳控制低寄存器(PORT_GPCLR)、全局引腳控制高寄存器(PORT_GPCHR)用于對(duì)通過(guò)相同功能屬性配置(PCR[15:0])的同一個(gè)PORT的多個(gè)引腳進(jìn)行快速配置:每個(gè)PORT有一個(gè)PORT_GPCLR和一個(gè)PORT_GPCHR寄存器分別配置該P(yáng)ORT的低16個(gè)引腳和高16個(gè)引腳的PCR寄存器配置,這兩個(gè)寄存器的該16-bit為寫使能配置位,每個(gè)GPWE位對(duì)應(yīng)一個(gè)引腳,使能(對(duì)應(yīng)位為1)時(shí),GPWD配置對(duì)該引腳的PCR寄存器寫有效,否則無(wú)效:③ 全局中斷控制寄存器(PORT_GICL/HR)此外,每個(gè)PORT還提供了全局中斷控制低寄存器(PORT_GICLR)、全局中斷控制高寄存器(PORT_GICHR)用于快速配置該P(yáng)ORT的相同中斷配置(PCR[31:16])的多個(gè)引腳中斷配置,其工作原理與全局引腳控制高低寄存器類似:Tips:以上全局控制寄存器提供了一種高效配置引腳PCR寄存器的方法,以便快速實(shí)現(xiàn)S32K1xx系列MCU引腳的配置,在實(shí)現(xiàn)功能安全要求的外設(shè)功能自測(cè)可以使用,以節(jié)約引腳PCR寄存器配置時(shí)間。④ 端口中斷狀態(tài)標(biāo)志寄存器(PORT_ISFR)此外,S32K1xx系列MCU的PORT模塊還提供了32-bit的中斷狀態(tài)標(biāo)志寄存器(PORT_ISFR),該寄存器每一個(gè)寫1清0(w1c) 的bit位對(duì)應(yīng)一個(gè)引腳的中斷狀態(tài),1 ->中斷發(fā)生, 0 -> 中斷未發(fā)生,與相應(yīng)引腳的PCR[ISF]一一對(duì)應(yīng):⑤ 數(shù)字濾波器配置寄存器(PORT_DFER/DFCR/PORT_DFWR)S32K1xx系列MCU的PORT模塊還為每個(gè)GPIO引腳提供了一個(gè)數(shù)字濾波器,以實(shí)現(xiàn)對(duì)輸入信號(hào)噪聲過(guò)濾的作用。其通過(guò)以下寄存器進(jìn)行配置:數(shù)字濾波器使能寄存器(PORT_DFER), 該寄存器每一個(gè)bit位配置相應(yīng)PORT引腳的輸入數(shù)字濾波器是否使能:1 -> 使能, 0 -> 關(guān)閉:數(shù)字濾波器時(shí)鐘選擇寄存器(PORT_DFCR):該寄存器僅最低bit位有效,用于選擇該P(yáng)ORT輸入引腳數(shù)字濾波器的參考時(shí)鐘:1 -> 使用低功耗時(shí)鐘(LPO_CLK), 0 -> 使用總線時(shí)鐘(BUS_CLK)數(shù)字濾波器寬度配置寄存器(PORT_DFWR):該寄存器的僅最低5個(gè)bit位FILT[4:0]有效,用于配置PORT的引腳輸入數(shù)字濾波器濾波寬度,只有大于FILT[4:0] 個(gè)濾波時(shí)鐘周期的信號(hào)才能被MCU識(shí)別:1.2 S32K1xx的GPIO模塊配置與狀態(tài)寄存器介紹S32K1xx系列MCU的GPIO模塊,為每個(gè)MCU引腳配置為通用輸入輸出(GPIO)功能時(shí)的輸入和輸出操作提供了用戶接口寄存器,包括:32-bit的端口數(shù)據(jù)輸出寄存器(PDOR):每個(gè)bit位對(duì)應(yīng)一個(gè)GPIO引腳,1 ->輸出高電平, 0 -> 輸出低電平;32-bit的端口數(shù)據(jù)置位輸出寄存器(PSOR):每個(gè)寫1有效的bit位對(duì)應(yīng)一個(gè)GPIO引腳,1 ->輸出高電平, 0 -> 不影響輸出電平狀態(tài);32-bit的端口數(shù)據(jù)清除輸出寄存器(PCOR):每個(gè)寫1有效的bit位對(duì)應(yīng)一個(gè)GPIO引腳,1 ->輸出低電平, 0 -> 不影響輸出電平狀態(tài);32-bit的端口數(shù)據(jù)翻轉(zhuǎn)輸出寄存器(PTOR):每個(gè)寫1有效的bit位對(duì)應(yīng)一個(gè)GPIO引腳,1 ->翻轉(zhuǎn)輸出電平, 0 -> 不影響輸出電平狀態(tài);32-bit的端口數(shù)據(jù)輸入寄存器(PDIR):每個(gè)bit位對(duì)應(yīng)一個(gè)GPIO引腳,1 ->輸入高電平, 0 -> 輸入低電平;32-bit的端口數(shù)據(jù)方向寄存器(PDDR):每個(gè)bit位對(duì)應(yīng)一個(gè)GPIO引腳,1 -> 引腳數(shù)據(jù)方向?yàn)檩敵觯?0 -> 引腳數(shù)據(jù)方向?yàn)檩斎耄?/section>32-bit的端口輸入關(guān)閉寄存器(PIDR):每個(gè)bit位對(duì)應(yīng)一個(gè)GPIO引腳,1 -> 引腳輸入關(guān)閉,對(duì)PDIR相應(yīng)bit位為0, 0 -> 引腳配置為通用輸入功能;1.3 S32K1xx系列MCU的GPIO IRQ中斷S32K1xx系列MCU的每個(gè)GPIO引腳都有IRQ中斷功能,具體配置請(qǐng)參考1.1小節(jié)介紹。S32K11x系列MCU的GPIO引腳中斷向量分配如下,所有PORT的全部GPIO引腳共用一個(gè)中斷向量(Interrupt Vector):S32K14x系列MCU的GPIO引腳中斷向量分配如下,每一個(gè)PORT的若干GPIO引腳共用一個(gè)中斷向量(Interrupt Vector):因此,在GPIO引腳的中斷ISR函數(shù)中,用戶需要讀取各個(gè)PORT的中斷標(biāo)志寄存器(PORT->ISFR)來(lái)判斷具體是哪一個(gè)GPIO引腳發(fā)生了中斷,然后做相應(yīng)的處理并清除對(duì)應(yīng)的中斷標(biāo)志位,具體請(qǐng)參考本文的3.3小節(jié)。Tips:使用時(shí)將用到的GPIO引腳中斷盡量分配到同一個(gè)PORT,可以減少中斷ISR,縮短查詢中斷的時(shí)間--僅讀取一個(gè)PORT的ISFR寄存器即可進(jìn)行判斷。Tips:在基于S32K1xx SDK的S32K1xx系列MCU應(yīng)用工程啟動(dòng)文件(S32K1xx_Startup.s)中,已經(jīng)通過(guò)弱符號(hào)(Weak Symbol)定義了所有的外設(shè)中斷ISR。比如,在S32DS使用的GCC編譯器啟動(dòng)文件中,S32K11x系列MCU的中斷ISR定義如下:.long PORT_IRQHandler /* Port A, B, C, D and E pin detect interrupt */
.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*/ 然后使用默認(rèn)死循環(huán)的中斷ISR(DefaultISR)進(jìn)行了替換:.align 1 .thumb_func .weak DefaultISR .type DefaultISR, %function DefaultISR: 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文件中定義與啟動(dòng)文件中PORT中斷ISR同名的無(wú)參數(shù)無(wú)返回(void)類型函數(shù)比如S32K14x系列MCU的PORTA中斷ISR實(shí)現(xiàn)如下: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文件中定義無(wú)參數(shù)無(wú)返回(void)類型的指定ISR函數(shù),然后調(diào)用Interrupt_Manager組件提供的比如同樣功能的S32K14x系列MCU的PORTA中斷ISR實(shí)現(xiàn)如下: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); } } 然后,調(diào)用InterruptManager組件的INT_SYS_InstallHandler()注冊(cè)該中斷ISR到PORTA的中斷向量表中:/* * install PORTA IRQ interrupt ISR */ INT_SYS_InstallHandler(PORTA_IRQn, User_Button_IRQ_ISR, NULL); PinSettings組件的初始化函數(shù)只是配置使能了S32K1xx系列MCU的GPIO引腳中斷,用戶還需要調(diào)用InterruptManager組件的INT_SYS_EnableIRQ(),使能其對(duì)應(yīng)的NVIC IRQ中斷:/* * enable PORTC IRQ interrupt */ INT_SYS_EnableIRQ(PORTA_IRQn); 2. PinSettings組件配置的S32K1xx系列MCU硬件模塊在S32K1xx SDK中,提供了外設(shè)驅(qū)動(dòng)層(PD)的PinSettings組件,用于配置S32K1xx系列MCU的PORT和GPIO功能,并提供相應(yīng)的底層驅(qū)動(dòng)API函數(shù)。其與CPU組件和clock_manager組件以及interrupt_manager組件一起作為默認(rèn)組件添加到使用SDK工程的S32K1xx系列MCU應(yīng)用工程中,無(wú)需用戶自己手動(dòng)添加:接下來(lái),本章節(jié)就來(lái)詳細(xì)介紹一下其屬性配置和API函數(shù)功能以及使用Tips。在SDK組件的處理器專家組件視窗(Component Inspector)中可以看到PinSettings組件的屬性配置界面如下:在其信號(hào)分配(Routing)欄,提供了按外設(shè)模塊區(qū)分的MCU引腳功能復(fù)用和方向配置:從上面的介紹可知,S32K1xx系列MCU的引腳若有ADC輸入的功能,則其默認(rèn)配置(PCR[MUX] = 0b0000)就是ADC輸入功能,而且對(duì)于大部分ADC輸入通道來(lái)說(shuō)只有一個(gè)引腳映射,所以無(wú)需用戶特別配置。其用戶配置界面如下:只有在S32K14x系列MCU中,為了支持BLDC/PMSM三相電機(jī)的三電阻采樣方案,ADC0與ADC1之間有有交錯(cuò)(interleave)功能的4個(gè)ADC通道(ADC0_CH8/9和ADC1_CH14/15),需要用戶進(jìn)行引腳映射配置,以匹配硬件設(shè)計(jì):② CAN/LPI2C/LPSPI/LPUART通信模塊引腳映射配置S32K1xx系列MCU集成了多達(dá)3路FlexCAN通信模塊,每個(gè)FlexCAN模塊需要配置其發(fā)送(TXD)和接收(RXD)的引腳。默認(rèn)是未使用的(No pin routed),使用CAN模塊時(shí),用戶必須根據(jù)實(shí)際硬件設(shè)計(jì)從下拉菜單中選擇正確的引腳映射,其用戶配置界面如下:LPI2C模塊的引腳映射配置界面如下, 由于存在多種引腳映射可能,默認(rèn)是未使用的(No pin routed), 使用時(shí)用戶需要根據(jù)實(shí)際需求配置主機(jī)請(qǐng)求(Host Request), 串行時(shí)鐘(Serial Clock),串行數(shù)據(jù)(Serial Data)以及次串行時(shí)鐘(Secondary Serial Clock)和次串行數(shù)據(jù)(Secondary Serial Data):LPSPI模塊的引腳映射配置界面如下, 由于存在多種引腳映射可能,默認(rèn)是未使用的(No pin routed), 使用時(shí)用戶需要根據(jù)實(shí)際需求配置外設(shè)片選(PCS0~3)、串行時(shí)鐘(Serial Clock),串行數(shù)據(jù)輸入(Serial Data Input)和串行數(shù)據(jù)輸出(Serial Data Output),并根據(jù)Master和Slave選擇配置正確的信號(hào)傳輸方向:LPUART模塊的引腳映射配置界面如下, 由于存在多種引腳映射可能,默認(rèn)是未使用的(No pin routed), 使用時(shí)用戶需要根據(jù)實(shí)際需求配置清除發(fā)送(Clear to Send)、請(qǐng)求發(fā)送(Request to Send),接收數(shù)據(jù)(RXD)和發(fā)送數(shù)據(jù)(TXD),并根據(jù)LPUART功能選擇配置TXD的信號(hào)傳輸方向:S32K1xx系列MCU片上模擬比較器CMP模塊,大多數(shù)功能引腳也是唯一的映射,且為模擬功能,無(wú)需用戶配置,但輸入1(Analog Input 1)和輸出(Analog Output)以及輪回觸發(fā)輸出(Round Robin Port Output Trigger)有多個(gè)引腳映射,默認(rèn)未使用的(No pin routed),使用時(shí),用戶必須根據(jù)實(shí)際硬件設(shè)計(jì)從下拉菜單中選擇正確的引腳映射,其用戶配置界面如下:S32K1xx系列MCU的外面看門狗檢測(cè)EWM模塊,需要配置輸入輸出信號(hào)的引腳映射。由于存在多種引腳映射可能,默認(rèn)是未使用的(No pin routed),使用時(shí),用戶必須根據(jù)實(shí)際硬件設(shè)計(jì)從下拉菜單中選擇正確的引腳映射,其用戶配置界面如下:S32K1xx系列MCU的FlexIO模塊,用8個(gè)數(shù)據(jù)端口,需要配置其引腳映射。由于存在多種引腳映射可能,默認(rèn)是未使用的(No pin routed),使用時(shí),用戶必須根據(jù)實(shí)際硬件設(shè)計(jì)從下拉菜單中選擇正確的引腳映射,其用戶配置界面如下:⑥ FlexTimer/LPTMR/RTC定時(shí)器模塊引腳映射配置S32K1xx系列MCU集成了若干FlexTimer(FTM)定時(shí)器模塊,每個(gè)FlexTimer模塊有1一個(gè)外部參考時(shí)鐘輸入信號(hào),8個(gè)通道信號(hào)和4個(gè)失效輸入信號(hào)可以配置引腳映射。由于存在多種引腳映射可能,默認(rèn)都是未使用的(No pin routed),使用時(shí),用戶必須根據(jù)實(shí)際硬件設(shè)計(jì)從下拉菜單中選擇正確的引腳映射,對(duì)應(yīng)FTM通道,還需要配置其信號(hào)方向,比如用作輸入捕捉(IC)功能時(shí)為方向?yàn)檩斎耄敵霰容^(OC)和PWM功能時(shí)則為輸出。其用戶配置界面如下:除了FlexTimer外,S32K1xx系列MCU還有一個(gè)LPTMR低功耗定時(shí)器模塊,其支持輸入脈沖計(jì)數(shù)功能,由于存在多種引腳映射可能,默認(rèn)都是未使用的(No pin routed使用時(shí)需要配置其外部脈沖輸入信號(hào)引腳映射。其用戶配置界面如下:S32K1xx系列MCU的RTC定時(shí)器功能引腳配置界面如下,其支持外部32.768KHz有源時(shí)鐘輸入作為其工作參考時(shí)鐘(Clock Input)和對(duì)RTC_CLK的輸出(Clock Output), 如有使用,需要在此配置:S32K1xx系列MCU的引腳用作通用GPIO功能時(shí),需要通過(guò)如下界面,配置其端口引腳(PORT->GPIO PIN)信號(hào)選擇和方向。默認(rèn)是未使用的(No pin routed):⑧ SWD/JTAG/Platform/PowerAndFround引腳映射配置這些界面通常用戶無(wú)需關(guān)心,使用其默認(rèn)配置即可。JTAG和SWD為S32K1xx系列MCU的調(diào)試接口引腳映射配置,在使用SWD調(diào)試接口時(shí),可以將JTAG接口的TDO(PTC5)和TDO(PTA10)引腳用作其他外設(shè)功能。在Platform界面,用戶可以配置CLKOUT時(shí)鐘輸出引腳映射、NMI-不可屏蔽內(nèi)核異常輸入、RESET系統(tǒng)復(fù)位輸入和外設(shè)晶振信號(hào)(EXTAL/XTAL)的引腳映射:Tips:用戶需要十分小心對(duì)JTAG/SWD調(diào)試接口和Platform界面的RESET復(fù)位引腳信號(hào)映射的配置,關(guān)閉這些引腳會(huì)導(dǎo)致調(diào)試器連接失敗。下次連接調(diào)試器必須在PinSettings配置生效前。另外,在PinSettings組件的功能實(shí)現(xiàn)(Functional Properties)欄,提供了對(duì)每個(gè)MCU引腳的PORT_PCR寄存器屬性配置:① Interrupt Flag:中斷標(biāo)志位ISF,是否在初始化時(shí)清除(寫1清0): Don't modify(默認(rèn)配置) -> 不清除;Clear Flag -> 寫1清零;② Interrupt :中斷條件配置,具體參考前面章節(jié)介紹,默認(rèn)配置為關(guān)閉中斷:Interrupt Status Flag(ISF) is disabled:③ Pin Mux:引腳功能復(fù)用,具體參見(jiàn)前面章節(jié)介紹,默認(rèn)配置為關(guān)閉引腳或者模擬信號(hào)(ADC或者ACMP輸入)功能:Pin disabled(引腳復(fù)用功能推薦在PinSettings組件的Routing一欄按照外設(shè)模塊功能分類進(jìn)行配置):④ Lock:運(yùn)行配置鎖配置,具體參考前面章節(jié)介紹,Unlocked( 默認(rèn)配置) -> 關(guān)閉,允許運(yùn)行時(shí)重新配置PCR寄存器; locked -> 使能,禁止運(yùn)行時(shí)重新配置PCR寄存器; ⑤ Pull Enable:使能上下拉配置,Disable( 默認(rèn)配置) -> 關(guān)閉;Enable -> 使能;⑥ Pull Select:上下拉選擇配置,Pull Down( 默認(rèn)配置) -> 下拉;Pull Up-> 上拉;⑦ Digital Filter:數(shù)字濾波器配置,Disable( 默認(rèn)配置) -> 關(guān)閉;Enable -> 使能;⑧ Drive Strength:電流驅(qū)動(dòng)強(qiáng)度配置,Low( 默認(rèn)配置) -> 低;High-> 高(僅對(duì)大電流IO可用,輸出驅(qū)動(dòng)電流可達(dá)20mA);⑨ Passive Filter:被動(dòng)濾波器配置,僅對(duì)NMI(PTD3)和RESET(PTA5)引腳可用;Enable -> 使能;⑩ Initial Value:GPIO輸出初始化電平配置,Low( 默認(rèn)配置) -> 低電平;High-> 高電平;? ADC Interleave:ADC交錯(cuò)功能配置(僅對(duì)S32K14x系列MCU可用):Not muxed in SIM_CHIPCTL( 默認(rèn)配置) ->使用默認(rèn)配置;muxed in SIM_CHIPCTL ->由SIM_CHIPCTL配置;Tips:以上②~⑩的PCR寄存器配置的默認(rèn)配置與芯片設(shè)計(jì)相同,具體請(qǐng)參考S32K1xx系列MCU的參考手冊(cè)附件excel--S32K1xx_IO_Signal_Description_Input_Multiplexing.xlsx;2.2 PinSettings組件API函數(shù)詳解PinSettings組件提供了豐富的API函數(shù)供用戶調(diào)用:通常,用戶對(duì)引腳的絕多數(shù)功能配置都可以由2.1小節(jié)介紹的配置界面圖形化方式配置,由Processor Expert生成初始化配置結(jié)果,在應(yīng)用工程Generated_Code目錄下,由pin_mux.c/pin_mux.h保存:用戶只需在main()函數(shù)中,完成系統(tǒng)時(shí)鐘初始化后拖拽(Drag & Drop)調(diào)用初始化API- -PINS_DRV_Init()函數(shù)即可完成引腳配置:若用戶需要配置某個(gè)引腳的數(shù)組濾波器,則需手動(dòng)調(diào)用如下API函數(shù):/*! * @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引腳電平,則可以調(diào)用以下API函數(shù):/*! * @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函數(shù)中,用戶需要調(diào)用一下API函數(shù),判斷具體的中斷引腳并清除相應(yīng)的中斷標(biāo)志(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函數(shù)還有全局引腳控制(PINS_DRV_SetGlobalPinControl())和中斷控制(PINS_DRV_SetGlobalIntControl())配置函數(shù):/*! * @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); 調(diào)用PinSettings組件的API函數(shù)時(shí),需要注意以下事項(xiàng):① API函數(shù)參數(shù)是PORT_Type 還是GPIO_Type ?若是PORT_Type ,則合法的參數(shù)為: 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 ,則合法的參數(shù)為: 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函數(shù)參數(shù)是Pin Mask還是PIN Number?比如寫GPIO輸出的以下兩個(gè)API函數(shù):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()的第二個(gè)參數(shù)pin為Pin Number,而PINS_DRV_WritePins()的第二個(gè)參數(shù)pins為Pin Mask:所以要在PTA3上輸出高電平,以上兩個(gè)函數(shù)的調(diào)用如下:PINS_DRV_WritePin(PTA, 3, 1);/*output high on PTA3*/ PINS_DRV_WritePins(PTA, 1<<3 );/*output high on PTA3*/ 而要在PTA3上輸出低電平,則調(diào)用如下:PINS_DRV_WritePin(PTA, 3, 0);/*output low on PTA3*/ PINS_DRV_WritePins(PTA, 0<<3 );/*output low on PTA3*/ Tips:以上API函數(shù)中均是對(duì)GPIO->PDOR寄存器的操作,不同之處在于前者是讀改寫的操作,不會(huì)影響同一個(gè)PORT的其他引腳輸出狀態(tài),而后者則是直接將值寫入GPIO->PDOR寄存器,會(huì)影響同一個(gè)PORT的其他引腳輸出狀態(tài);Tips:對(duì)GPIO引腳輸出狀態(tài)控制時(shí),更為推薦使用如下API函數(shù),其分別對(duì)GPIO->PSOR寄存器(輸出高電平)、GPIO->PCOR寄存器(輸出低電平)和GPIO->PTOR寄存器(翻轉(zhuǎn)輸出電平)的pin mask操作,更為高效快捷(具體請(qǐng)參考1.2小節(jié)相關(guān)寄存器介紹):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生成的引腳配置代碼量和引腳初始化時(shí)間將PinSettings組件的Settings欄 -> Generate configured Pins only選擇為 “yes”,則僅生成配置與默認(rèn)復(fù)位配置不同的引腳配置數(shù)據(jù),從而減少生成的引腳初始配置代碼量,同時(shí)也將減少引腳初始化時(shí)間;否則(選擇為“NO”),將為每個(gè)引腳都生成初始化配置參數(shù):3. 基于S32K144-EVB的GPIO IRQ中斷控制RGB LED亮滅樣例工程為了幫助大家更好的理解本文所講內(nèi)容,接下來(lái),將以S32K144-EVB為例,介紹如何配置使用GPIO引腳輸入中斷和輸出高低電平。3.1 S32K144-EVB的用戶按鍵輸入硬件設(shè)計(jì)及其PinSettings組件GPIO中斷配置S32K144-EVB的2個(gè)用戶按鍵輸入電路設(shè)計(jì)如下:按鍵 | S32K144 GPIO端口 | SW2 | PTC12 | SW3 | PTC13 | 首先,在PinSettings組件的Routing欄GPIO中配置PTC12和PTC13為方向(Direction)為輸入(Input):然后,在PinSettings組件的Functional Properties欄,配置PTC12和PTC13的中斷條件為上升沿觸發(fā)CPU IRQ中斷并使能內(nèi)部下拉及數(shù)字濾波器:3.2 S32K144-EVB的RGB LED硬件設(shè)計(jì)及其PinSettings組件GPIO輸入配置S32K144-EVB的3個(gè)用戶RGB LED電路設(shè)計(jì)如下: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初始化后為熄滅狀態(tài):3.3 GPIO IRQ中斷控制RGB LED亮滅功能代碼實(shí)現(xiàn)首先,定義用戶按鍵和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函數(shù)如下,實(shí)現(xiàn)功能為:讀取PORTC中斷標(biāo)志位,判斷:若發(fā)生了SW2中斷(用戶按下),則翻轉(zhuǎn)GPIO閃爍藍(lán)色RGB LED,并清除相應(yīng)的引腳中斷標(biāo)志;若發(fā)生了SW3中斷(用戶按下),則翻轉(zhuǎn)GPIO閃爍紅色RGB LED,并清除相應(yīng)的引腳中斷標(biāo)志:/************************************************************ * 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); } } 最后,調(diào)用Interrupt_Manager組件的以下API函數(shù)安裝(INT_SYS_InstallHandler())以上中斷ISR函數(shù)并使能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); 本文詳細(xì)介紹了S32K1xx系列MCU的端口(PORT)和通用輸入輸出(GPIO)功能特性,以及如何使用S32K1xx SDK提供的Processor Expert PinSettings組件配置MCU引腳的PORT和GPIO功能以及外設(shè)功能復(fù)用和引腳映射,并基于S32K144-EVB硬件設(shè)計(jì)詳細(xì)介紹了其提供的用戶API函數(shù)使用方法和使用Tips。-------------------------------------
|