NXP S32K144 LPUART、LPIT模块应用讲解

1.  前言

        本文以世平集团推出的 NXP Echoes-S32K144评估板为例,采用对直接对寄存器进行配置的编程方式来调用 GPIO、LPIT、LPUART 模块实现每 2 秒通过串口向 PC 端发送字符 hello world 功能。

        S32K144 是恩智浦(NXP)公司于 2017 推出面向通用汽车应用市场的高性能微处理器,该微处理器基于 32位 ARM Cortex-M4F 内核,最快内核频率达 112MHz。NXP Echoes-S32K144评估板采用 14×14mm LQFP100 封装,引脚间距 0.5mm,具有丰富的外设资源。该方案支持 JTAG 标准调试接口和 JTAG 4 线 SWD 调试模式,具有 micro USB 或外部 12V 电源两种供电选择,板载 CAN、LIN 与 UART 连接。

图 1-1 NXP Echoes-S32K144评估板

        本文将各模块独立介绍并在各模块章节中讲解初始化函数代码,最后在主函数代码章节中调用各模块初始化函数。由于模块头文件为各函数声明,所以本文默认各头文件声明已创建并编写无误,若未有头文件,可创建 .h 文件并将各函数名复制到 .h 文件中编译成功即可。

2.   S32K144 GPIO 模块

2.1      S32K144 GPIO 模块介绍

        S32K14x 系列 MCU 最高支持 156 个 I/O 口设置,本文所使用的 S32K144-100LQFP 支持最大 89 个 I/O 口设置。同时这些 I/O 可以被配置许多功能,包括:pin interrupt/DMA request、数字故障滤波器、输入上拉/下拉/磁滞、NMI_b 和 RESET_b 输入脚配置被动输入滤波器等功能配置。

图 2.1-1 S32K144-100LQFP 引脚名称图

        除了配置各种功能外这些引脚可以通过复用实现 I/O、UART、CAN、SPI等功能,本文将 PTC2 与 PTC3 引脚复用成 LPUART0_RX、LPUART0_TX 来实现 UART功能。具体引脚复用与功能分配请参照 《S32K144_IO_Signal_Description_Input_Multiplexing》。

        S32K144 包含 5 个主要端口:PORTA、PORTB、PORTC、PORTD、PORTE,每个端口又有 18 个 I/O 口。每个 PORT 通过自身的寄存器配置输入输出值,通过 Port Control and Interrupt 寄存器控制 PORT 口的复用、上拉/下拉、输入滤波器等功能的配置。

 

图 2.1-1 S32K144-100LQFP 部分引脚复用

2.2      S32K144 GPIO 寄存器介绍

        GPIO 控制有7个寄存器分别是 PDOR、PSOR、PCOR、PTOR、PDIR、PDDR、PIDR,具体寄存器映射见下表。

表 2.2.1 GPIO Memory Map

Offset

Register

Width

Access

Reset value

0h

Port Data Output Register(PDOR)

32

RW

00000000h

4h

Port Set Output Register(PSOR)

32

WORZ

00000000h

8h

Port Clear Output Register(PCOR)

32

WORZ

00000000h

Ch

Port Toggle Output Register(PTOR)

32

WORZ

00000000h

10h

Port Data Input Register(PDIR)

32

RO

00000000h

14h

Port Data Direction Register(PDDR)

32

RW

00000000h

18h

Port Input Disable Register(PIDR)

32

RW

00000000h


2.3      S32K144 GPIO 寄存器代码编写

GPIO.c

#include "S32K144.h"

#include "GPIO.h"                                                                              //包含外部声明

 

void gpio_uart0_init()                                                                        //GPIO 复用初始化函数

{

        PCC->PCCn[PCC_PORTC_INDEX]|=PCC_PCCn_CGC_MASK;    //使能 PTC 时钟

 

        PORTC->PCR[2]|=PORT_PCR_MUX(4);                                       // PTC2 复用功能4 LPUART0_RX

        PORTC->PCR[3]|=PORT_PCR_MUX(4);                                       // PTC3 复用功能4 LPUART0_TX

}

 

 

3.  S32K144 LPUART 模块

3.1      S32K144 LPUART 模块介绍

        低功耗通用异步收发器(Low Power Universal Asynchronous Receiver/Transmitter, LPUART)支持带有DMA 接口功能的基本 UART,和 x4 到 x32 的过采样波特率,支持 LIN 主从操作。该模块在 Stop 和 VLPS 模式提供的时钟保持启用时,仍可保持功能。

        S32K144 具有 3 个 LPUART 模块,这些模块具有一下特点:

  • 全双工,标准的非归零(non-return-to-zero,NRZ)格式。
  • 可编程的波特率(13 位数模转换器)与可配置的比率从 x4 到 x32 的过采样。
  • 发送和接受波特率可以异步操作到总线时钟:
  • 波特率可以配置独立的总线时钟频率、支持在 Stop 模式下操作。
  • 中断,DMA 或者拉起操作:

        发送数据寄存器为空,发送完成、接收数据寄存器满、接收溢出,奇偶校验错误,帧错误,噪声干扰、闲置接收器检测、接受引脚边缘有效、支持 LIN 的中断检测接收数据匹配。

  • 硬件奇偶校验生成和检查。
  • 可编程的 7-bit、8-bit、9-bit 或10-bit 的字符长度。
  • 可编程的 1-bit 或者 2-bit 停止位。
  • 3 种接收器唤醒方法:

        闲置线唤醒、地址标记唤醒、接收数据匹配。

  • 自动地址匹配,减少中断服务程序(ISR)开销:

        地址标志匹配、闲置线地址匹配、地址匹配开始和结束。

  • 可选的 13-bit 终止字符生成或 11-bit 终止字符检测。
  • 可配置的空闲长度检测,支持 1、2、4、8、16、32、64 或 128 空闲字符。
  • 可选的发送器输出和接收器输入极性。
  • 硬件流控制支持 RTS(request to send)和 CTS(clear to send)信号。
  • 可选的 4 归零变换(return-to-zero-inverted,RZI)格式,可编程脉宽。
  • 独立的 FIFO 收发结构:

        可独立配置水印的收发请求、如果接收 FIFO 不是空的,在可配置的闲置字符长度后,可以选择让接收器声明请求。

 

3.2      LPUART 工作模式介绍

        LPUART 具有 4 种工作模式,分别为运行模式、停止模式、等待模式与调试模式。

        在运行模式下 LPUART 可以运行所有模块功能支持 Interrupt 与 DMA 请求。

        在停止模式下只要使能异步发送和接收时钟,LPUART 将在停止模式下继续工作。在停止模式中唤醒需要 LPUART 产生一个 Interrupt 或者 DMA 请求。

        在等待模式下如果 DOZEEN 位配置为 1 时,发送器与接收器将会在完成当前字节的发送或者接收后停止工作。

        在调试模式中 LPUART 模块将会保持功能。


图 3.2-1 LPUART 发送器框图

图 3.2-2 LPUART 接收器框图

3.3      LPUART 寄存器介绍

        LPUART 寄存器包含控制波特率、选择 LPUART 选项、报告 LPUART 状态以及发送或者接收数据功能,对有效寄存器映射之外的地址访问将会产生总线错误。详细的寄存器内存映射见下表。

表 3.3.1 LPUART Memory Map

Offset

Register

Width

Access

Reset value

0h

Version ID Register (VERID)

32

RO

04010003h

4h

Parameter Register (PARAM)

32

RO

00000202h

8h

LPUART Global Register (GLOBAL)

32

RW

00000000h

Ch

LPUART Pin Configuration Register (PINCFG)

32

RW

00000000h

10h

LPUART Baud Rate Register (BAUD)

32

RW

0F000000h

14h

LPUART Status Register (STAT)

32

RW

00C00000h

18h

LPUART Control Register (CTRL)

32

RW

00000000h

1Ch

LPUART Data Register (DATA)

32

RW

00001000h

20h

LPUART Match Address Register (MATCH)

32

RW

00000000h

24h

LPUART Modem IrDA Register (MODIR)

32

RW

00000000h

28h

LPUART FIFO Register (FIFO)

32

RW

00C00011h

2Ch

LPUART Watermark Register (WATER)

32

RW

00000000h

 

3.4      S32K144 LPUART 寄存器代码编写

#include "S32K144.h"

#include "LPUART.h"                                                                                      //包含外部声明

void uart0_init()                                                                                           //LPUART 模块初始化函数

{

        PCC->PCCn[PCC_LPUART0_INDEX]&=~PCC_PCCn_CGC_MASK;    //禁用 LPUART0 时钟

        PCC->PCCn[PCC_LPUART0_INDEX]|=PCC_PCCn_PCS(0b010)         //选择时钟源 2

                                                                    | PCC_PCCn_CGC_MASK;        //使能时钟

 
        LPUART0->BAUD=LPUART_BAUD_OSR(15)                                     //设置 16 倍过采样率

                                        |LPUART_BAUD_SBR(52);                                     //设置波特率为 9600 8M/9600/16=~52   


        LPUART0->CTRL=LPUART_CTRL_TE_MASK                                     //使能发送器

                                       |LPUART_CTRL_RE_MASK;                                   //使能发送器

}

 

void uart0_transmit_char(char send)                                                     //LPUART 发送单字符功能函数

{

        while((LPUART0->STAT&LPUART_STAT_TDRE_MASK)>>LPUART_STAT_TDRE_SHIFT==0;

                                                                                                                 //等待发送缓存区空
        LPUART0->DATA=send;                                                                 //发送数据


}

 

void uart0_transmit_string(char data_string[])                                    //LPUART 发送字符串功能函数

{
        uint32_t i=0;

        while(data_string[i]!='\0')                                                              //一次发送一个字节
        {

             uart0_transmit_char(data_string[i]);                                        //调用发送单字符函数

             i++;
        }

}

 

4.  S32K144 LPIT 模块

4.1      S32K144 LPIT 模块介绍

        S32K144 包含 1 个低功耗中断计时器(Low Power Interrupt Timer)模块 4 个通道。低功耗周期中断定时器(LPIT)是一个多通道定时器模块,产生独立的预触发和触发输出。这些计时器通道可以单独操作,也可以链接在一起。如果配置为低功率模式,则LPIT可以在低功率模式下运行。预触发和触发输出可用于触发设备上的其他模块。

        每个计时器通道都可以配置为独立运行,并在比较或捕获模式下工作。在比较模式下,计时器在启用时递减,并生成输出预触发和超时脉冲。触发输出比预触发脉冲延迟 1 个时钟周期。每个定时器通道的启动、重新加载和重新启动都可以通过控制位进行控制。计时器可配置为始终递减,或所选触发输入的减量或上一个通道超时(当通道为链式)。通过链接计时器通道,应用程序可以实现更大的超时持续时间。在捕获模式下,计时器可用于执行测量,因为计时器值为当所选触发输入被置位时捕获(在定时器值寄存器中)。捕获模式下,计时器可以支持一次关闭或多次测量(例如:频率测量)。

        计时器通道在异步时钟上运行,该时钟独立于寄存器读或写访问时钟。时钟域之间的时钟同步确保正常操作。


图 4.1-1 LPIT 顶层框图

 

4.2      LPIT 寄存器介绍

        存映射由 32 位对齐寄存器组成,可通过 8 位、16 位或 32 位访问进行访问。对保留位置的写入访问将生成传输错误。对保留位置的读取访问也将生成传输错误,读取数据总线将显示所有 0。内存映射和完整模块采用 Big Endian 格式。模块不会检查寄存器中编程值的正确性,软件必须确保写入的值正确。详细的寄存器映射见下表。

表 4.2.1 LPIT Memory Map

Offset

Register

Width

(In bits)

Access

Reset value

0h

Version ID Register (VERID)

32

RO

01000000h

4h

Parameter Register (PARAM)

32

RO

00000404h

8h

Module Control Register (MCR)

32

RW

00000000h

Ch

Module Status Register (MSR)

32

W1C

00000000h

10h

Module Interrupt Enable Register (MIER)

32

RW

00000000h

14h

Set Timer Enable Register (SETTEN)

32

RW

00000000h

18h

Clear Timer Enable Register (CLRTEN)

32

WORZ

00000000h

20h

Timer Value Register (TVAL0)

32

RW

00000000h

24h

Current Timer Value (CVAL0)

32

RO

FFFFFFFFh

28h

Timer Control Register (TCTRL0)

32

RW

00000000h

30h

Timer Value Register (TVAL1)

32

RW

00000000h

34h

Current Timer Value (CVAL1)

32

RO

FFFFFFFFh

38h

Timer Control Register (TCTRL1)

32

RW

00000000h

40h

Timer Value Register (TVAL2)

32

RW

00000000h

44h

Current Timer Value (CVAL2)

32

RO

FFFFFFFFh

48h

Timer Control Register (TCTRL2)

32

RW

00000000h

50h

Timer Value Register (TVAL3)

32

RW

00000000h

54h

Current Timer Value (CVAL3)

32

RO

FFFFFFFFh

58h

Timer Control Register (TCTRL3)

32

RW

00000000h

 

4.3     S32K144 LPIT 寄存器代码编写

#include "S32K144.h"

#include "LPIT.h"                                                                                                   //包含外部声明

 

void lpit0_ch0_init(uint16_t period_ms)                                                              //LPIT 通道 0 初始化函数

{

        PCC->PCCn[PCC_LPIT_INDEX]=PCC_PCCn_PCS(6);                                    //选择时钟源

        PCC->PCCn[PCC_LPIT_INDEX]|=PCC_PCCn_CGC_MASK;                           //使能时钟

        LPIT0->MCR|=LPIT_MCR_M_CEN_MASK;                                                   //使能模块时钟

        LPIT0->TMR[0].TVAL=40000*period_ms;                                                   //通道 0 超时周期

        LPIT0->TMR[0].TCTRL|=LPIT_TMR_TCTRL_T_EN_MASK;                            //使能计时器通道

        LPIT0->MIER|=LPIT_MIER_TIE0_MASK;                                                       //中断使能

}

 

void lpit0_ch0_LPIT0_Ch0_IRQ_nvic_init()                                                          //LPIT 通道 0 中断配置

{

        S32_NVIC->ICPR[LPIT0_Ch0_IRQn/32]=1<<(LPIT0_Ch0_IRQn%32);       //清除挂起中断线

        S32_NVIC->ISER[LPIT0_Ch0_IRQn/32]=1<<(LPIT0_Ch0_IRQn%32);       //设置中断线

        S32_NVIC->IP[LPIT0_Ch0_IRQn]=0x0a;                                                      //设置优先级

}

 

5.  主函数代码编写

#include "S32K144.h"

#include "clocks_and_modes.h"                                                                            //例程时钟配置,导入任意例程可获得

#include "LPUART.h"

#include "GPIO.h"

#include "LPIT.h"                                                                                                    //包含外部声明

 

int main(void)

{

        SOSC_init_8MHz();    

        SPLL_init_160MHz();

        NormalRUNmode_80MHz();                                                                         //调用例程时钟配置

        gpio_uart0_init();                                                                                            //调用 LPUART 模块端口复用配置

        uart0_init();                                                                                                     //调用 LPUART 模块初始化

        lpit0_ch0_init(2000);                                                                                       //调用 LPIT 模块初始化,计时器超时为 2 秒

        lpit0_ch0_LPIT0_Ch0_IRQ_nvic_init();                                                             //LPIT 中断配置

 

        uart0_transmit_string("this is an example\r\n");                                           //调用 LPUART 发送 this is an example

 

        while(1)

        {

        }

  return 0;

}

 

void LPIT0_Ch0_IRQHandler()                                                                             //LPIT 中断服务函数

{

        uart0_transmit_string("hello world\r\n");                                                     //LPUART 发送 hello world

        LPIT0->MSR|=LPIT_MSR_TIF0_MASK;                                                         //清除 LPIT 中断标志位

}

 

        将评估板按下图与 TTL 转换助手连接绿线为转换助手 Tx 连接评估板的 C2 Rx 口,蓝线为转换助手 Rx 连接评估板的 C3 Tx 口,黑线为转换助手的 GND 连接评估板的 GND。使用 ARM 仿真器连接评估板的 JTAG 口,将代码通过仿真器下载进评估板进行调试,在 PC 端上打开串口调试助手得到评估板先向 PC 端发送 this is an example 字符串,随后每两秒发送 hello world 字符串一次,与代码编写符合。


图 5-1 评估板连接图


图 5-2 串口调试助手接收图

 

6.  参考文献

[1] S32K144 Reference Manual.pdf,NXP

[2] S32K1xx Series Cookbook.pdf,NXP

[3] S32K144_IO_Signal_Description_Input_Multiplexing,NXP

[4] PCB - P20-033 Echoes_V2.0_Jadyn Li_20210618, 大大购

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论