ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STM32CUbeMAX 串口+DMA中断收发实验

2022-05-31 17:32:15  阅读:195  来源: 互联网

标签:STM32CUbeMAX DMA HAL rx uint8 len 串口


串口配置: 异步,波特率:19200,每帧:1字节;无校验;1停止位

 

 中断设置:考虑到后期使用freertos,可控制中断配置为:4位抢占优先级,15>=中断优先级级>=5(越低,优先级越高)

 

 

 DMA设置:以字节为数据单位,内存地址累加

生成工程文件:

 

在stm32f1xx_it.h 文件添加

#define BUFF_MAX 100  #接收缓冲区大小
extern volatile uint8_t rx_len;    //接收一帧数据的长度
extern volatile uint8_t recv_end_flag; //一帧数据接收完成标志
extern uint8_t rx_buffer[BUFFER_SIZE];  //接收数据缓存数组

在stm32f1xx_it.c文件添加

volatile uint8_t rx_len ;  //接收一帧数据的长度
volatile uint8_t recv_end_flag; //一帧数据接收完成标志
uint8_t rx_buffer[BUFFER_SIZE];  //接收数据缓存数组

在stm32f1xx_it.c修改中断串口1中断函数为

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
    uint32_t tmp_flag = 0;
    uint32_t temp;
    tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
    if((tmp_flag != RESET))//idle标志被置位
    { 
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
        HAL_UART_DMAStop(&huart1); //
        temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数   
        //temp  = hdma_usart1_rx.Instance->NDTR;//读取NDTR寄存器 获取DMA中未传输的数据个数,
        //这句和上面那句等效
        rx_len =  BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
        recv_end_flag = 1;    // 接受完成标志位置1    
     }
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

在main函数添加:

uint8_t Recive_buff[Buff_Max]={0};//转存缓冲区数据,避免DMA引用的数组被其他地方操作而发生错误
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rx_buffer,BUFFER_SIZE);//打开DMA接收
    while (1)
  {
         if(recv_end_flag == 1)  //接收完成标志
        {    
            memcpy(Recive_buff,rx_buffer,rx_len);
            DMA_Usart_Send(Recive_buff,rx_len);        
            memset(rx_buffer,0,rx_len);            
            rx_len = 0;//清除计数
            recv_end_flag = 0;//清除接收结束标志位
            HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rx_buffer,BUFFER_SIZE);//重新打开DMA接收
/** HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
* 开串口hartx的DMA接收中断,响应IDLE中断,调用中断处理函数UART1_IQRHeahler();
* *huart:调用串口x
* *pData:dma转存数据地址
* BUFFER_SIZE:转存数据地址大小,此值大于最大传输数据+1(停止位),同时为 *hdma_usartx_rx->Instance->CNDTR 赋初始值,即temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx)为该值(初值)-已转移值
*/
  }
        HAL_Delay(10);
    }
void DMA_Usart_Send(uint8_t *buf,uint8_t len)//串口发送封装
{
 if(HAL_UART_Transmit_DMA(&huart1, buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数
  {
   Error_Handler();
  }
}

整体流程为:开串口及DMA中断,等待串口接收数据 ->  有数据传输,DMA转存数据,触发IDLE中断 -> 串口中断处理函数,关闭DMA传输,返回接收标志、数据大小 -> 主程序判断串口接收数据标志 - > DMA传输数据 -> 清除缓冲区 ->开启串口1 DMA接收中断

 

 

 

搜索

复制

标签:STM32CUbeMAX,DMA,HAL,rx,uint8,len,串口
来源: https://www.cnblogs.com/ysyyrps-hhl/p/16331335.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有