一、Uart配置

配置串口选择DMA 方式:

1、UartClockRef 选择串口总线时钟。 (这里不是想选啥就选啥,必须根据时钟总线来)

二、port

发送脚:

PortPin Pull Enable 不能点,会导致输出拉不下去。

在程序里面RX 是复用模式:

.mux = PORT_MUX_ALT5,

{ .base = IP_SIUL2, 
.pinPortIdx = 16, 
.mux = PORT_MUX_ALT5, 
},

接收脚:

在程序里面管脚是GPIO模式:

.mux = PORT_MUX_AS_GPIO,

{

         .base = IP_SIUL2,

        . pinPortIdx = 15,

        .mux = PORT_MUX_AS_GPIO,

},

三、mcl配置

Dma Logic Channel 接口需进行配置。主要目的是为 LPUART6_TX 和 LPUART6_RX 配置两个 DMA 通道。

添加DMA逻辑配置:

DMA通道配置:

1:S32K312 这个对于DMA有个DMAMUX功能,

需要查DMAMUX map表确定对于外设DMA映射到哪个DMA上,这样在对rm里面才能选择对应映射。

2:图中Hardware Channel 是根据DMAMUX map表选择。

四、Mcu 配置

Mcu 时钟配置 -> 《 S32K31时钟配置》

五、rm配置

DMA MUX作用:

DMA MUX作为S32K3的DMA多路选择器,把不同外设的DMA请求路由到有限的DMA通道上。

S32K312 有大量外设,但 eDMA 硬件通道数量少,靠 DMAMUX 做请求开关。

Dma Mux Source 如果没有需求的外设选择,哪么说明配置DMA逻辑通道错了。查看DMAMUX MAP表确定应该在mcl模块的DMA 逻辑通道选择

Hardware Channel 时,应该选择哪个对应到DMAMUX上。

六、platform

S32K312中断映射在这里配置。

S32K312如何装载中断在中断中详细说明

Mcal 中断映射不是在 S 文件中断向量表中实现,而是通过 IntCtrl_Ip_InstallHandler 装载中断:

通过追踪 Platform_init 可以发现

如下:

所以配置中断实际上是把中断表中断和程序中的中断映射起来。

如下:

七 、 主程序

 

int main(void)
{
    
    Mcu_Init( &Mcu_Config);                 // 初始化MCU底层配置(时钟、复位、模式等基础参数)   
    Mcu_InitClock(0);                       // 初始化MCU时钟树(PLL、外部晶振、分频等)
    // 等待PLL锁定,确保系统时钟稳定后再继续执行
    while (MCU_PLL_LOCKED != Mcu_GetPllStatus())
    {
    }
    Mcu_DistributePllClock();                // 分发PLL时钟到各个总线和外设   
    Mcu_SetMode(0);                          // 设置MCU运行模式(RUN模式)                   
    Port_Init(&Port_Config);                 // 初始化端口引脚(复用、方向、上下拉、驱动能力)
    Mcl_Init(&Mcl_Config);                   // 初始化MCL底层核心驱动   
    Rm_Init(NULL_PTR);                       // 初始化资源管理模块(DMA/外设资源分配)
    Platform_Init(NULL_PTR);                 // 初始化平台模块(中断向量、内核相关)
    Uart_Init(&Uart_xConfig);                // 初始化UART串口驱动
    //Uart_GetBaudrate(0, &userbaud);        // 读取波特率配置(已注释)
    Uart_debug_Init();                       // 初始化调试串口(打印日志用)
    Gpt_Init(&Gpt_Config);                   // 初始化通用定时器GPT(PIT/STM)
    Gpt_StartTimer(0,30000);                 // 启动PIT通道0定时器,定时周期1ms
    Gpt_StartTimer(1,60000);                 // 启动STM通道1定时器,定时周期1ms
    Gpt_EnableNotification(0);               // 使能通道0定时器中断通知
    Gpt_EnableNotification(1);                // 使能通道1定时器中断通知    
    // 主循环
    while(1)
    {
        // 执行周期任务(调度、逻辑、通信等)
        task_period();
    }
    return 0;
}

用户回调:
 

void Uart_Callback(uint8 HwInstance, Uart_EventType Event)
{
    uint32 Remain;  // DMA接收缓冲区剩余未接收字节数
    uint16 RxLen;   // 本次实际接收到的数据长度
    // 根据不同的UART事件类型执行对应处理
    switch (Event)
    {
        case UART_EVENT_RX_FULL:
            /* RX FIFO 满事件(DMA模式下不使用该中断) */
            break;
        case UART_EVENT_IDLE_STATE:
            /* UART 总线空闲中断:表示一帧数据接收完成 */
            /* 获取DMA接收缓冲区中,剩余未接收的字节数 */
            Uart_GetStatus(UART_LPUART_INTERNAL_CHANNEL, &Remain, UART_RECEIVE);
            /* 计算本次实际接收到的数据长度 = 总DMA缓冲区大小 - 剩余未接收字节数 */
            RxLen = RX_DMA_SIZE - Remain;
            /* 将接收到的数据存入环形缓冲区,供应用层读取 */
            Uart_Rx_Debug_ring_Insert(RxDmaBuf, RxLen);
            /* 清空DMA接收缓冲区,准备下一次接收 */
            memset(RxDmaBuf, 0, RX_DMA_SIZE);
            /* 重新启动DMA异步接收,等待下一帧数据 */
            Uart_AsyncReceive(UART_LPUART_INTERNAL_CHANNEL, RxDmaBuf, RX_DMA_SIZE);
            break;

        case UART_EVENT_ERROR:
            /* UART 错误事件(溢出错误、帧错误、校验错误等) */
            break;

        case UART_EVENT_TX_EMPTY:
            /* 发送FIFO空中断(一般仅用于调试) */
            break;

        case UART_EVENT_END_TRANSFER:
            /* DMA传输完成事件(空闲中断接收模式下不使用) */
            break;

        default:
            /* 未定义的事件,不处理 */
            break;
    }
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐