【LM401】USART串口配置过程
本文主要记录基于 LM401模组的3路串口调试过程,MCU 是 STM32WLE5,主要包括串口IO配置以及DMA中断配置
1. 板载资源说明
LM401 模组是基于 STM32WLE5
系列芯片,模组支持3路串口,其中一路可以配置为低功耗串口。另外还有2路7通道DMA
【普通串口和低功耗串口区别】
USART
可以工作在 Stop 0 1
模式,LPUART1
可以工作在 Stop 0 1 2
模式,LPUART1
在匹配 start address 或者 received frame event 时会 产生唤醒中断
板载总线示意图如下:
demo 例程中是用的 usart2
,我想用 UASRT1
的PB6
和PB7
引脚,开始串口的配置过程
2.uart.c 串口配置文件修改
2.1接口文件 uart_if.c
可以用 STM32Cube IDE 开发环境对MCU进行可视化配置,然后生成代码接口,给码农减小了工作量。从下图中可以看出,串口的的接口是 vcom
在 uart_if.c
文件中,找到接口,是一个结构体,结构体成员是函数指针,以下4个函数功能为:
const UTIL_ADV_TRACE_Driver_s UTIL_TraceDriver =
{
vcom_Init, // 初始化串口,并分配相应的 DMA channel
vcom_DeInit, // 串口和DMA的去使能
vcom_ReceiveInit, // 串口接收数据初始化
vcom_Trace_DMA, // 使用 DMA 将databuffer 发送至串口
};
2.2整体配置流程
- 初始化
uart.c
uart_if.c
-
中断处理函数配置
stm32wlxx_it.c
-
DMA1_Channel1_IRQHandler
-
USART1_IRQHandler
-
2.2.1初始化串口,分配DMA
【vcom_Init】
其中,EXTI
表示(external interrupt/event controller)外部中断控制,请参考博文:【stm32中的外部中断】
UTIL_ADV_TRACE_Status_t vcom_Init(void (*cb)(void *))
{
TxCpltCallback = cb;
MX_USART1_UART_Init(); //串口1 参数初始化
MX_DMA_Init(); // 分配 DMA
LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_27); // Enable ExtiLine Interrupt request for Lines in range 0 to 31.
return UTIL_ADV_TRACE_OK;
}
下面重点分析以下,串口1初始化和分配DMA函数的功能,该功能主要涉及2个函数,在 uart.c
文件中
- 【MX_USART1_UART_Init()】 【HAL_UART_MspInit()】【HAL_UART_MspDeInit()】 代码在文末
注意:串口DMA选择了 DMA1_Channel1
2.2.2配置串口和DMA中断
在 dma.c
文件中,配置DMA通道中断,因为选择了 DMA1_Channel1
,因此设置中断 DMA1_Channel1_IRQn
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMAMUX1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
在 stm32wlxx_it.c
文件中,设置中断处理函数,设置为: DMA处理来自于串口1的中断请求
// DMA 通道中断
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_tx); // DMA处理来自于串口1的中断请求
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
/* USER CODE END DMA1_Channel1_IRQn 1 */
}
// 串口中断
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
3.调试过程分析
以下是调试成功之后的打印信息,但是在调试过程中遇到过以下问题, ****************************
是初始化时打印的第一条信息
【问题1:只打印第一条信息,以后的消息不打印了】
解决: DMA 通道配置错误,造成无法正确执行
4.给出代码
4.1 uart.c
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_tx;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();