之前一直用STM32CUBE配置工程,但是一用到USART1的DMA接收中断,或者USART1的接收中断,就会出现问题,在之前的调试中发现USART1的DMA与ADC1的DMA有冲突(原因我也不造啊),后来将USART1的DMA接收中断改成USART1的接收中断,在一个工程里可以使用,另一个工程出现了数据不更新的情况(明明已经将缓冲区的数据全部读取了),感觉HAL库的串口中断很坑(本人水平较低),今天给大家分享一下如何在HAL库(STM32CUBEMX)生成的工程上修改串口函数,使串口中断接收数据不发生丢失,且还能接收不定长的数据。
首先使STM32CUBE里的USART1配置
参数配置都一样
记得配置中断就可以
这里配置好以后在生成的工程里需要以下几点改变
1在USART1.C里的void MX_USART1_UART_Init(void)函数里加入 USART1->CR1|=1<<5;
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;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
}
2、将stm32f1xx_it.c里的void USART1_IRQHandler(void)的内容替换为下面的内容
void USART1_IRQHandler(void)
{
uint8_t res;
if(huart1.Instance->SR&(1<<5)) //接收到一帧数据
{
res=huart1.Instance->DR;
USART_RX_BUF[USART_RX_STA]=res;
USART_RX_STA++;
flag_rx=1; //接收数据的标志位
}
res=USART1->SR;
res=USART1->DR;
}
3、写一个将缓冲区 即USART_RX_BUF[]里的数据读出的函数
/*只有将接收缓冲区的数据都读出,才会清空缓冲区*/
void telecontroller_data(void)
{
uint8_t i;
if(flag_rx==1)
{ for(i=0;i<USART_RX_STA;i++)
{
output_data[i]=USART_RX_BUF[i];//将所有数据从缓冲区内读出,USART1_DR才会更新数据。
printf("%x\r\n",output_data[i]);
}
flag_rx=0;
USART_RX_STA=0;
}
}
记得将void telecontroller_data(void)放在while(1)里运行
给大家看一下我的成果