NXP S32K312 UART 与 DMA 模块结合应用讲解(含代码)

1. 简介

       本文介绍如何使用 NXP 提供的 RTD 软件包开发 S32K312 UART 与 DMA 模块结合应用,通过串口打印 Log 数据。

图 1-1 Knight S32K312 开发板

图 1-1 Knight S32K312 开发板

1.1 需求组件

硬件组件:

  • 开发板:Knight S32K312开发板;

软件组件:

  • 开发软件:S32 Design Studio for S32 Platform 3.5;
  • 拓展包:S32K3xx development V3.5.13;
  • RTD 版本:SW32K3_S32M27x_RTD_R21-11_4.0.0_P19_D2403_DS_updatesite;

2. 工程配置

2.1 UART 端口配置

       本文使用 UART1 模块为例,配置端口 PTD13 与 PTD14 分别作为 UART1 模块的 Rx 引脚与 Tx 引脚,在配置引脚时需要注意信号栏与方向栏,除了在信号栏里配置成 Tx、Rx 还需要根据 Tx、Rx 的数据输入输出调整方向,若不一致会导致执行初始化端口函数时进入硬件故障中断而无法退出。

图 2.1-1 UART 端口配置

图 2.1-1 UART 端口配置

2.2 DMA 模块配置

       配置 DMA 模块首先需要在 General 选项卡下勾选 Enable DMA Support 选项,如不勾选此选项 Specific Configuration 页面将处于灰色页面无法进行配置操作。

图 2.2-1 DMA General 页面

图 2.2-1 DMA General 页面

       Specific Configuration 页面我们需要配置 Hardware Channel、Interrupt Callback、Enable Global Config 与 Global 下 Enable DMA Request 选项。Hardware Channel 选项选择所使用的硬件 DMA 通道,S32K312 仅有 1 个 DMA 模块 12 个通道,所以使用 DMA 模块时仅需配置 Hardware Channel 无需配置 Hardware Instance 选项;由于 DMA 模块发送数据使用中断功能所以需要中断回调函数即配置 Interrupt Callback 选项内输入中断回调函数名称,该回调函数可自定义;除以上配置外使用 DMA 功能还需要使能 DMA 请求即勾选 Global 下 Enable DMA Request 选项,使能 DMA 请求需要先勾选 Enable Global Config 选项;为了更好地将在其他模块连接 DMA 通道建议同步修改 Name 栏名称为通道所用功能。

图 2.2-1 DMA 模块 Tx 通道配置

图 2.2-1 DMA 模块 Tx 通道配置

图 2.2-2 DMA 模块 Rx 通道配置

图 2.2-2 DMA 模块 Rx 通道配置

       DMA 通道配置完成之后为了能够使用 DMA 功能,还需要确定 DMA 的数据来源,然而 S32DS 内配置工具并没有提供工具用于配置 DMA 源,所以需要我们手动使用代码对寄存器进行写入。通过查询 S32K3xx_DMAMUX_map.xlsx 表格得知 LPUART1 发送 DMA 请求与接收 DMA 请求数据源分别为 39 和 40,同时查询 S32KXXRM.pdf 手册 Direct Memory Access Multiplexer(DMAMUX)章节下 DMAMUX register descriptions 小段得知 0x40280000-0x40280003 寄存器分别对应 DMA 通道3 到通道 0 的配置,寄存器为 8 位寄存器,0-5 位为 DMA 通道源在该位写入值将指定特殊 DMA 数据来源到指定 DMA 通道;第 6 位是 DMA 通道触发使能位,该位写入 1 会周期触发 DMA 通道;第 7 位是 DMA 通道使能位,写入 1 将使能相应的 DMA 通道,例如向 0x40280003 第 7 位写入 1 会使能 DMA 通道 0。综上所属本例程使用 DMA 通道 0 和通道 1 用作 LPURAT1 的 Tx 和 Rx 功能,即向 0x40280003 寄存器写入 0xA7 数据与 0x40280002 寄存器写入 0xA8 数据,具体写入代码如下:

    IP_DMAMUX_0->CHCFG[3]=0xA7;

    IP_TCD->CH0_CSR=1;

    IP_DMAMUX_0->CHCFG[2]=0xA8;

    IP_TCD->CH1_CSR=1;

图 2.2-3 DMAMUX 寄存器地址与偏移地址

图 2.2-3 DMAMUX 寄存器地址与偏移地址

图 2.2-4 寄存器位说明

图 2.2-4 寄存器位说明

图 2.2-4 寄存器位说明

2.3 UART 模块配置

       UART 模块配置相比普通串口模式配置只需在 GeneralConfiguration 页面内勾选 Uart DMA Enable 选项,并在 UartGlobalConfig 页面选择发送模式为 DMA 模式并链接相应的 Tx 与 Rx DMA 通道即可。

图 2.3-1 UART 模块 GeneralConfiguration

图 2.3-1 UART 模块 GeneralConfiguration

图 2.3-2 UART 模块 UartGlobalConfig

图 2.3-2 UART 模块 UartGlobalConfig

2.4 IntCtrl 模块配置

DMA 模块通道发送数据使用中断功能需要在 IntCtrl 模块内对相应 DMA 模块进行中断配置。

图 2.4-1 IntCtrl 模块配置

图 2.4-1 IntCtrl 模块配置

3. 主函数编写

       各模块初始化与功能函数在工程内 MCAL 文件夹下相对应模块名称的头文件与源文件内,若使用其他版本 RTD 软件包则各函数名称会有所区别调用函数需要到相应模块文件内查找。

#include "Mcal.h"


#include "string.h"

#include "stdio.h"

#include "S32K312.h"

#include "Clock_Ip.h"

#include "Siul2_Port_Ip.h"

#include "IntCtrl_Ip.h"

#include "Lpuart_Uart_Ip.h"

#include "Dma_Ip.h"

 

#define uart1   1

#define message "this is uart1_dma example!\r\n"

#define timeout 0xFFFF

#define rxsize 30

#define txsize 30

 

ISR(LPUART_UART_IP_1_IRQHandler);

 

ISR(Dma0_Ch0_IRQHandler);

ISR(Dma0_Ch1_IRQHandler);

 

 

#pragma GCC section bss ".mcal_bss_no_cacheable"

       uint8 rxbuffer[rxsize]={0};

       uint8 txbuffer[txsize]={0};

#pragma GCC section bss

 

 

int main(void)

{

    /* Write your code here */

   int length=0;

   uint32 remainingbytes=0;

   Lpuart_Uart_Ip_StatusType status=LPUART_UART_IP_STATUS_SUCCESS;

   uint32 i,n=0;

 

Clock_Ip_Init(Clock_Ip_aClockConfig);

 

Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS_PortContainer_0_BOARD_InitPeripherals,

       g_pin_mux_InitConfigArr_PortContainer_0_BOARD_InitPeripherals);

 

   IntCtrl_Ip_Init(&IntCtrlConfig_0);

 

Lpuart_Uart_Ip_Init(uart1,&Lpuart_Uart_Ip_xHwConfigPB_1);

 

   Dma_Ip_Init(&Dma_Ip_xDmaInitPB);

 

 

   IP_DMAMUX_0->CHCFG[3]=0x80;

   IP_DMAMUX_0->CHCFG[3]=0xA7;

   IP_TCD->CH0_CSR=1;//写 0x40280000 寄存器使能 DMA 通道 0 并选择源

 

   IP_DMAMUX_0->CHCFG[2]=0x80;

   IP_DMAMUX_0->CHCFG[2]=0xA8;

   IP_TCD->CH1_CSR=1;//写 0x40280000 寄存器使能 DMA 通道 1 并选择源

 

 

   length=strlen(message);

 

status=Lpuart_Uart_Ip_AsyncSend(uart1,(uint8 *)message,length);

   do

   {

   status=Lpuart_Uart_Ip_GetTransmitStatus(uart1,&remainingbytes);

   }

while(LPUART_UART_IP_STATUS_SUCCESS!=status);

 

    for(;;)

    {

       for(i=0;i<rxsize;i++)

       {

           rxbuffer[i]='\0';

           txbuffer[i]='\0';

       }

 

       n=0;

 

    status=Lpuart_Uart_Ip_AsyncReceive(uart1,rxbuffer,rxsize);

       do

       {

       status=Lpuart_Uart_Ip_GetReceiveStatus(uart1,&remainingbytes);

       }

    while(LPUART_UART_IP_STATUS_BUSY==status);

 

 

       while(rxbuffer[n]!='\0')

       {

           txbuffer[n]=rxbuffer[n];

           n++;

       }

 

    status=Lpuart_Uart_Ip_SyncSend(uart1,txbuffer,n,timeout);

       return 0;

}

4. 调试测试

       将上文主函数添加到 S32DS 内编译工程生成 .elf 文件通过 Jlink 调试器下载进入 Knight S32K312 开发板连接 PTD13、PTD14 到串口调试助手到上位机进行调试,MCU 初始化后会发送字符串“this is uart1_dma example!”到上位机串口调试软件,随后会发送从上位机串口调试软件接收到的字符串回上位机调试软件。

图 4-1 Knight 硬件连接

图 4-1 Knight 硬件连接

图 4-2 UART 与 DMA 结合调试



图 4-2 UART 与 DMA 结合调试

由于篇幅所限本文仅介绍 S32K312 RTD UART 与 DMA 模块结合应用讲解,如想了解更多资料与设计,请联系我们 atu.sh@wpi-group.com

5. 参考文献

[1] S32K3XX Reference Manual.pdf,NXP

[2] S32K3XX Data Sheet.pdf,NXP

[3] S32K3xx_DMAMUX_map.xlsx,NXP

欢迎点击此处在博文下方留言评论,我们会及时回复您的问题。

如有更多需求,欢迎联系大联大世平集团 ATU 部门:atu.sh@wpi-group.com   
作者:Hobo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值