天天看點

序列槽中斷IDLE接收,不使用DMA

之前在網上看到有DMA傳輸接收不定長資料,使用到IDLE中斷。這次使用序列槽中斷接收不定長資料,通過IDLE中斷的标志位

新手上路,想試試寫個部落格,記錄一下自己學的東西。

在大佬的文章上學習到的使用DMA及IDLE中斷接收大量不定長資料的方法。但現在我要接收的隻是很短的不定長資料,就想不使用DMA,用序列槽中斷接收及IDLE的方式接收資料。

大佬的連結:

連結: link.

下面是我自己寫的使用序列槽中斷和IDLE中斷接收不定長資料的方法。

使用cubeMX建立工程,打開序列槽中斷。

序列槽中斷IDLE接收,不使用DMA

序列槽3中斷接收初始化,IDLE中斷初始化

__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
HAL_UART_Receive_IT(&huart3, (uint8_t *)&RxByte, 1);
           

定義變量

uint8_t RxByte;//序列槽接收到的一個位元組資料
uint8_t count=0;//序列槽接收資料個數
uint8_t UART3_RxBuffer[50];//将序列槽接收到的資料存入數組中
uint8_t recv_end_flag=0;//序列槽接收完成标志位
           

添加回調函數

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
 	if(huart->Instance==USART3)//如果是序列槽3
	{
		UART3_RxBuffer[count++] = RxByte;   //接收資料轉存
		HAL_UART_Receive_IT(&huart3, (uint8_t *)&RxByte, 1);   //再開啟接收中斷
	}
}
           

在stm32l1xx_it.c中的序列槽3中斷函數USART3_IRQHandler中添加讀取IDLE标志位的代碼

void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
	uint32_t tmp_flag=0;
	tmp_flag =__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE);//讀取IDLE中斷标志位
	if((tmp_flag != RESET))//idle标志被置位
    {
		__HAL_UART_CLEAR_IDLEFLAG(&huart3);//清除IDLE标志位
		recv_end_flag = 1;//接收完成标志位
	}
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */
  /* USER CODE END USART3_IRQn 1 */
}
           

主函數

int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART3_UART_Init();
  /* USER CODE BEGIN 2 */
	__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
	HAL_UART_Receive_IT(&huart3, (uint8_t *)&RxByte, 1);
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
		if(recv_end_flag==1)//如果接收完成
		{
				recv_end_flag=0;//接收标志位複位
				HAL_UART_Transmit(&huart3, UART3_RxBuffer, count, 1000);//将接收到的資料通過序列槽發送回去
				count=0;//清空接收計數
				memset(UART3_RxBuffer,0x00,sizeof(UART3_RxBuffer));//清除接收數組
		}
  }
  /* USER CODE END 3 */
}
           

結果

序列槽中斷IDLE接收,不使用DMA

随機發送的資料完整發送回來。

源代碼連結: https://pan.baidu.com/s/1aBkpL_JwlDoKMgWpwvccZA

提取碼:vapt