stm32F103串口数据接收发送(基于32CubeMX)

串口数据接收

一、串口中断接收定长数据

1. 配置串口,打开中断

2. 在初始化后加入打开串口接收中断(否则无法正常接收到数据)

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
  • 参数1:串口n的指针
  • 参数2:要接收数据的指针(注意数据类型是uint8_t ,如果是数组,可以直接传)
  • 参数3:要接收数据的长度
  • 示例:

    HAL_UART_Receive_IT(&huart1,u8_ReceiveData,3);
    

    3. 配置接收中断回调函数(只有接收到第二步中的Size字节后才会触发)

    cplt指的是complete

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    
  • 在中断回调函数中判断中断源
  • 在中断回调函数中处理接收到的数据
  • 再次打开接收中断
  • 示例

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)    //接受中断回调函数,只有接收到确定字节之后才触发
    {
    	if (huart == &huart1)                           //判断中断源
    	{
    		HAL_UART_Transmit_IT(&huart1,u8_ReceiveData,3);        //将接收的数据发送回去
    		HAL_UART_Receive_IT(&huart1,u8_ReceiveData,3);         //再次打开接收中断
    	}
    }
    

    二、串口DMA接收定长数据

    和串口中断配置很相似,只需要替换掉部分函数名即可

    1. 配置串口,打开中断

    2. CubeMX配置串口DMA

    3. 在初始化后加入打开串口DMA接收中断(否则无法正常接收到数据)

    HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
    
  • 参数1:串口n的指针
  • 参数2:要接收数据的指针(注意数据类型是uint8_t ,如果是数组,可以直接写数组名)
  • 参数3:要接收数据的长度
  • 示例:

    HAL_UART_Receive_DMA(&huart1,u8_ReceiveData,3);
    

    3. 配置接收中断回调函数(只有接收到第三步中的Size字节后才会触发)

    这个回调函数和串口中断接收的一致

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    
  • 在中断回调函数中判断中断源
  • 在中断回调函数中处理接收到的数据
  • 再次打开串口DMA接收中断
  • 示例

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)    //接受中断回调函数,只有接收到确定字节之后才触发
    {
    	if (huart == &huart1)                           //判断中断源
    	{
    		HAL_UART_Transmit_DMA(&huart1,u8_ReceiveData,3);        //将接收的数据通过DMA发送回去
    		HAL_UART_Receive_DMA(&huart1,u8_ReceiveData,3);         //再次打开DMA接收中断
    	}
    }
    

    三、串口DMA接收不定长数据

    1. 配置串口,打开中断

    2. CubeMX配置串口DMA

  • 在串口中点击DMA Settings
  • Add
  • 选择要用DMA的通道
  • ①是DMA搬运方向,串口收发是从内存变量和收发寄存器之间搬运,就是Memory和Peripheral之间
  • ②是地址自增,由于收发寄存器是一个8位的寄存器,里面数据自动变化的,无需自增;而内存变量就需要地址自增
  • ③数据宽度,一次搬运就是8位的数据,因此为一个字节的数据宽度
  • 3. 在初始化后加入打开空闲中断和DMA接收,并关闭DMA传输过半中断

    接收中断打开后记得把这个关掉,否则第一次的数据会出问题

    HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
    __HAL_DMA_DISABLE_IT (&hdma_usart1_rx,DMA_IT_HT);
    
  • 参数1:串口n的指针
  • 参数2:要接收数据的指针(注意数据类型是uint8_t ,如果是数组,可以直接写数组名)
  • 参数3:要接收数据的最大长度
  • 关闭串口1DMA接收过半中断,否则在接收到2/Size的时候就会产生中断
  • 示例:

    HAL_UARTEx_ReceiveToIdle_DMA(&huart1,u8_ReceiveData,sizeof(u8_ReceiveData));
    __HAL_DMA_DISABLE_IT (&hdma_usart1_rx,DMA_IT_HT);
    

    可能会出现错误:
    解决方法:在usart.h文件中添加extern DMA_HandleTypeDef hdma_usart1_rx;

    4. 配置接收中断回调函数(一段时间没有接收到数据时候触发中断)

    比接收中断HAL_UART_RxCpltCallback多了一个Size参数,接收不定长数据需要通过Size确定到底接受了几个字节数据,也就是说接收数据结束后Size变量就是字节数。

    HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
    
  • 在中断回调函数中判断中断源
  • 在中断回调函数中处理接收到的数据
  • 再次打开串口空闲中断和DMA接收
  • 再次关闭串口1DMA接收过半中断
  • 示例:

    	if (huart == &huart1)                           //判断中断源
    	{
    		HAL_UART_Transmit_DMA(&huart1,u8_ReceiveData,Size);//将接收的数据通过DMA发送回去,需要通过Size确定要发送几位数据
    		HAL_UARTEx_ReceiveToIdle_DMA(&huart1,u8_ReceiveData,sizeof(u8_ReceiveData)); //打开DMA接收中断,串口1,需要发送的数组,数组大小(注意此函数要在初始化时打开,否则无法接收)
    		__HAL_DMA_DISABLE_IT (&hdma_usart1_rx,DMA_IT_HT);  //关闭DMA传输过半中断,接收中断打开后记得把这个关掉
    	}
    

    作者:dfhbftgf

    物联沃分享整理
    物联沃-IOTWORD物联网 » stm32F103串口数据接收发送(基于32CubeMX)

    发表回复