在HAL庫的基礎上修改串列埠中斷函式,使串列埠中斷接收不定長資料,且不發生丟失現象。
之前一直用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)裡執行
給大家看一下我的成果