S32K312 使用EB tresos 配置 Uart DMA通讯方式
一、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;
}
}
更多推荐


所有评论(0)