STM32串口DMA收发数据

本文详细介绍了如何在STM32cubemx中配置USART1进行串口通信,包括初始化设置、启用DMA接收、数据接收中断处理、发送数据以及错误中断处理。
摘要由CSDN通过智能技术生成

STM32cubemx配置串口和DMA

串口初始化

#define USART_BUF_LEN    1024
 
typedef struct
{
  uint16_t pRxBuffer;                 //接收buffer数据量                   
  uint16_t pTxBuffer;                 //发送buffer数据量
  uint8_t RxBuffer[USART_BUF_LEN];    //接收buffer
  uint8_t TxBuffer[USART_BUF_LEN];    //发送buffer
}USART_TYPE;
USART_TYPE PC_USART;
/* USART1 init function */

void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  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();
  }
  /* USER CODE BEGIN USART1_Init 2 */
  /* Enable the UART Parity TC Interrupt */
  __HAL_UART_ENABLE_IT(&huart1, UART_IT_TC);            //使能发送完成中断
  __HAL_UART_ENABLE_IT(&huart1, UART_IT_ERR);           //使能错误中断
  __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);          //使能空闲中断
  HAL_UART_Receive_DMA(&huart1, PC_USART.RxBuffer, USART_BUF_LEN);    //开启DMA接收
  /* USER CODE END USART1_Init 2 */

}

数据接收中断处理

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  Usart_Idel_Handle(&huart1);
  /* USER CODE END USART1_IRQn 1 */
}

//串口接受空闲中断数据处理
void Usart_Idel_Handle(UART_HandleTypeDef *huart)
{
  if((__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET)) 
  {
    /* 1.清除标志 */
    __HAL_UART_CLEAR_IDLEFLAG(huart); //清除空闲标志

    /* 2.读取DMA */
    HAL_UART_DMAStop(huart); //先停止DMA,暂停接收
    //获取DMA中传输的数据个数,数据接收不要大于 USART_BUF_LEN
    if(huart->Instance == USART1)
    {
      PC_USART.pRxBuffer = USART_BUF_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
      HAL_UART_Receive_DMA(&huart1, PC_USART.RxBuffer, USART_BUF_LEN);
    }
  } 
}

数据处理

/*主程序中调用*/
void Pc_Usart_Process(void)
{
  if(PC_USART.pRxBuffer > 0)
  {
    //处理数据
    PC_USART.pRxBuffer = 0;
  }
}

串口DMA数据发送

//发送缓冲数组填充
uint16_t PC_USART_FillTxBuf_Array(uint8_t *pbuf, uint16_t len)
{  
  uint16_t n = 0;
  
  while(n < len)
  {
    if(PC_USART.pTxBuffer < USART_BUF_LEN)
    {
      PC_USART.TxBuffer[PC_USART.pTxBuffer++] = *pbuf++;  
      n++;
    }
    else      
      break;
  }
  return n;  
}

//发送数据
void PC_USART_TxStart(void)
{
  HAL_UART_Transmit_DMA(&huart1, PC_USART.TxBuffer, PC_USART.pTxBuffer);
}

//--------串口发送完成回调函数---------------------
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
  if(huart->Instance == USART1)
  {
    PC_USART.pTxBuffer = 0;
  }
}

串口错误中断处理

//-----串口接收错误处理---------------------
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
  if(__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET) //帧错误
  {
    __HAL_UART_CLEAR_FEFLAG(huart);
  }
  
  if(__HAL_UART_GET_FLAG(huart, UART_FLAG_NE) != RESET) //噪音错误
  {
    __HAL_UART_CLEAR_NEFLAG(huart);
  }
    
  if(__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET)//过载错误
  {
    __HAL_UART_CLEAR_OREFLAG(huart);    
  }
  //重新开启DMA接收
  if(huart->Instance == USART1)
  {
    HAL_UART_Receive_DMA(&huart1, PC_USART.RxBuffer, USART_BUF_LEN);
  }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值