一、操作步骤
使用SMT32CubeMx配置指定引脚为UART后在右侧界面点击Connectivity->USART2->Mode选择异步模式Asynchronous,查看串口的基础配置-Parameter Settings,保持默认不变。
选择NVIC Settings点击Enabled使能全局中断。
这样整个串口配置就完成了。
二、代码实现
在自动生成代码里点开MX_USART2_UART_Init(void)函数并在最后面加入此句HAL_UART_Receive_IT(&huart2,&mUART2.TEMP,1);使用变量mUART2.TEMP接收数据,每次接收一个字节。
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
HAL_UART_Receive_IT(&huart2,&mUART2.TEMP,RECLEN);
/* USER CODE END USART2_Init 2 */
}
在写中断回调函数,void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)(系统内部会自动映射到这个函数,相当于重写这个函数给系统调用)。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART2)
{
if(mUART2.TEMP == '!' && mUART2.FLG == 0)
{
mUART2.FLG = 1;
mUART2.Uart_Len = 0;
}
if(mUART2.FLG)
{
mUART2.BUF[mUART2.Uart_Len] = mUART2.TEMP;
++mUART2.Uart_Len;
}
if(mUART2.Uart_Len >6 && mUART2.BUF[mUART2.Uart_Len - 1] == 0x0a)
{
mUART2.LEN = mUART2.Uart_Len;
mUART2.Uart_Len = 0;
mUART2.FLG = 0;
mUART2.RX_FLG = 1;
}
while(HAL_UART_Receive_IT(&huart2,&mUART2.TEMP,RECLEN) != HAL_OK);
}
}
这里要接收的数据是以 '!' 开头,以0D 0A结尾的数据格式。这时候使用串口助手发送相应的数据格式,使用printf打印(需要映射,编写如下代码即可调用printf函数),发现没有进入串口中断或出现偶尔进两、三次的现象。
/***************printf映射函数的实现*****************************/
#include <stdio.h>
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1 , 0xffff);
return ch;
}
/***************printf映射函数的实现*****************************/
三、原因
主要原因是时钟的问题,发现改成38400之后,默认的时钟配置是支持的,因此重新配置时钟,使用如下配置:
默认配置是2.095M,不支持115200波特率。
四、结论
配置波特率时,注意时钟的配置,当时钟不够相应的波特率即会出现一些异常。