STM32 HAL库使用中断实现串口接收不定长数据

  以前用DMA实现接收不定长数据,DMA的方法接收串口助手的数据,全部没问题,不过如果接收模块返回的数据,而这些数据如果包含回车换行的话就会停止接收,例如接收:AT\r\nOK\r\n,就只能接收到AT\r,导致没有接收完成,具体原因还没搞懂,有了解的,希望可以告知一下,DMA不定长接收方法传输门:https://www.cnblogs.com/xingboy/p/9714907.html

  好了,不多说了,现在进入正文。首先建立一个STM32Cumebx的工程,打开串口中断,完成配置,具体的配置流程就不细说了,没什么难度就只是打开串口跟中断而已。

  生成工程代码后,先定义好一些变量:

//串口4中断接收定义
#define MAX_RECV_LEN 1024         //设定可以接收的最大字节
uint8_t msg_buff[MAX_RECV_LEN] = {0}; //接收缓存区
uint8_t * msg = msg_buff;    //定义一个指针指向接收缓存区
int flag = 0;        //接收完成标志
int len_u4=0;  //数据长度记录

  接着重写串口接收回调函数

/*重写串口接收回调函数*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)
{
     uint8_t ret = HAL_OK;
    msg++;
        len_u4++;//数据长度计数
    if( msg == msg_buff + MAX_RECV_LEN)
    {
        msg = msg_buff;
    }
         do  
    {  
        ret = HAL_UART_Receive_IT(UartHandle,(uint8_t *)msg,1);            
    }while(ret != HAL_OK);
        if(*(msg-1) == '\n')   //接收以\n为结尾字符,则表示接收完成
    {
        flag  = 1;
    }
}

  最后在main函数里面编写接收后的逻辑,注意要在while(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_DMA_Init();

  MX_USART3_UART_Init();

  MX_UART4_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    //自己添加代码部分:while前打开串口中断接收
    HAL_UART_Receive_IT(&huart4, (uint8_t *)msg, 1); //开启第一次中断
  while (1)
  {
  /* USER CODE END WHILE *//* USER CODE BEGIN 3 */
//======自己添加代码部分=========        
            if (flag == 1)
    {
            printf("msg_buff = %s ;len = %d\r\n",msg_buff,len_u4);
            HAL_UART_Transmit(&huart3,msg_buff, len_u4,100);     //将串口4接收到的数据通过串口3传出    
            memset(msg_buff, 0, sizeof(msg_buff));   //清空缓存区
           // 指向接收缓存的头部
            msg = msg_buff;
            (&huart4)->pRxBuffPtr = msg;
            flag = 0;
                        len_u4=0;//每次数据长度清0
    }
        HAL_Delay(10);
  }
//==============================
  /* USER CODE END 3 */

}

  运行结果如下,效果正确

  

猜你喜欢

转载自www.cnblogs.com/xingboy/p/10154475.html