0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32基础知识:串口通信-DMA方式

CHANBAEK 来源:上下求索电子er 作者:上下求索电子er 2023-10-26 11:48 次阅读

串口通信-DMA方式

1 DMA概述

直接存储器访问 (DMA) : 用于在外设与存储器之间以及存储器与存储器之间进行高速数据传输。DMA传输过程的初始化和启动由CPU完成,传输过程由DMA控制器来执行,无需CPU参与,从而节省CPU资源,提高利用率。

DMA数据传输的四个要素:

  • 传输源 :DMA数据传输的来源
  • 传输目标:DMA数据传输的目的
  • 传输数量:DMA传输数据的数量
  • 触发信号:启动一次DMA数据传输的动作

STM32的DMA控制器特点

图片

  1. 每个DMA控制器有8个数据流,每个数据流可以映射到8个通道(或请求);
  2. 每一个DMA控制器用于管理一个或多个外设的存储器访问请求,并通过总线仲裁器来协调各个DMA请求的优先级;
  3. 数据流(stream)是用于连接传输源和传输目标的数据通路,每个数据流可以配置为不同的传输源和传输目标,这些传输源和传输目标称为通道(Channel);
  4. 具备16字节的FIFO。使能FIFO功能后,源数据先送入FIFO,达到FIFO的触发阈值后,再传送到目标地址。
    图片

DMA数据传输方式

  • 普通模式:传输结束后(即要传输数据的数量达到零),将不再产生DMA操作。若 开始新的DMA传输,需在关闭DMA通道情况下,重新启动DMA传输。
  • 循环模式:可用于处理环形缓冲区和连续数据流(例如ADC扫描模式)。当激活循 环模式后,每轮传输结束时,要传输的数据数量将自动用设置的初始值进行加载,并继续响应DMA请求。

2 DMA方式的接口函数

  1. 串口DMA方式发送函数:HAL_UART_Transmit_DMA

    函数原型HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_Handle TypeDef *huart, uint 8_t *pData, uint 16_t Size)
    功能描述在DMA方式下发送一定数量的数据
    入口参数1huart:串口句柄的地址
    入口参数pData:待发送数据的首地址
    入口参数3Size:待发送数据的个数
    返回值HAL状态值:HAL_OK表示发送成功;HAL_ERROR表示参数错误;HAL_BUSY表示串口被占用;
    注意事项1. 该函数将启动DMA方式的串口数据发送2. 完成指定数量的数据发送后,可以触发DMA中断,在中断中将调用发送中断回调函数HAL_UART_TxCpltCallback进行后续处理3. 该函数由用户调用户调用
  2. 串口DMA方式接收函数:HAL_UART_Receive_DMA

    函数原型HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_Handle TypeDef *huart, uint 8_t *pData, uint 16_t Size)
    功能描述在DMA方式下接收一定数量的数据
    入口参数1huart:串口句柄的地址
    入口参数pData:待接收数据的首地址
    入口参数3Size:待接收数据的个数
    返回值HAL状态值:HAL_OK表示发送成功;HAL_ERROR表示参数错误;HAL_BUSY表示串口被占用;
    注意事项1. 该函数将启动DMA方式的串口数据接收2. 完成指定数量的数据接收后,可以触发DMA中断,在中断中将调用接收中断回调函数HAL_UART_ExCpltCallback进行后续处理3. 该函数由用户调用户调用
  3. 获取未传输数据个数函数:__HAL_DMA_GET_COUNTER

    函数原型__HAL_DMA_GET_COUNTER
    功能描述获取DMA数据流中未传输数据的个数
    参数HANDLE :串口句柄的地址
    返回值NDTR寄存器的内容,即DMA数据流中无传输数据的个数
    注意事项1. 该函数是宏函数,进行宏替换,不发生函数调用2. 该函数需要由用户调用,用于获取未传输数据的个数
  4. 关闭DMA数据流:__HAL_DMA_DISABLE

    函数原型__HAL_DMA_DISABLE(__HANDLE__)
    功能描述关闭指定的DMA数据流
    参数HANDLE :串口句柄的地址
    返回值
    注意事项1. 该函数是宏函数,进行宏替换,不发生函数调用2. 该函数需要由用户调用,用于关闭指定的DMA数据流3. 关闭DMA数据流后触发DMA中断,最终调用串口收发的回调函数

任务实践4

不定长数据的收发:利用串口调试助手,从PC上发送任意长度的字符到开发板,开发板收到后原样发回到PC。

空闲中断的特点:

  1. 在一帧数据传输结束后,通信线路将会维持高电平,这个状态称为空闲状态;
  2. 当CPU检测到通信线路处于空闲状态时,且空闲状态持续时间大于一个字节传输时间时,空闲状态标志IDLE将由硬件置1。如果串口控制寄存器CR1中的IDLEIE位为1,将会触发空闲中断( IDLE中断);
  3. 由于空闲标志是在一帧数据传输完成后才置位,在有效数据传输过程中不会置位,因此借助空闲中断,可以实现不定长数据的收发。

设计思路:

  1. 使能IDLE中断,在串口2的中断服务程序USART2_IRQHandler中添加对IDLE中断的判断,该函数位于stm32f4xx_it.c文件;

  2. 设置传输模式为普通模式,启动DMA传输。串口一旦接收到数据,则触发DMA操作,将数据存放到用户定义的接收缓冲区;

  3. 当一帧数据发送完成后,线路处于IDLE状态,将触发IDLE中断,调用IDLE中断回调函数,设置数据接收完成标志;

  4. 主程序检测到接收完成标志置位后,将接收的一帧数据原样发回到PC,并禁能DMA,以触发DMA中断。DMA中断将调用接收中断回调函数,在回调函数中重新启动DMA传输。

  5. 串口1的DMA配置
    图片
    DMA数据流的中断使能由CubeMX自动勾选,手动使能串口2中断
    图片

  6. 编写程序
    stm32f1xx_it.c中添加空闲中断的处理

    /**
      * @brief This function handles USART1 global interrupt.
      */
    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 */
    
      // Add handling of idle interrupts
      if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE != RESET))
      {
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);   // Clear the IDLE interrupt flag
        HAL_UART_IdleCpltCallback(&huart1);   // User-written IDLE interrupt callback function
      }
      /* USER CODE END USART1_IRQn 1 */
    }
    

    main.c

    添加用户宏变量、变量定义

    /* USER CODE BEGIN PM */
    #define LENGTH 100   // Receive buffer size
    /* USER CODE END PM */
    
    /* USER CODE BEGIN PV */
    uint8_t RxBuffer[LENGTH];
    uint8_t RecCount = 0;
    uint8_t RxFlag = 0;
    /* USER CODE END PV */
    

    声明和定义空闲中断回调函数,定义DMA接收中断回调函数

    /* USER CODE BEGIN PFP */
    void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart)
    /* USER CODE END PFP */
    
    /* USER CODE BEGIN 4 */
    int fputc (int ch, FILE *f)
    {
        HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
        return ch;
    }
    
    int fgetc(FILE *f)
    {
        uint8_t ch = 0;
        HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
        return ch;
    }
    
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
      if (huart- >Instance == USART1)
      {
        HAL_UART_Receive_DMA(&huart1, (uint8_t*)RxBuffer, LENGTH);
      }
    }
    
    void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart)
    {
      RxFlag = 1;
    }
    /* USER CODE END 4 */
    

    编写用户应用代码

    /* USER CODE BEGIN 2 */
      printf("***  UART coummunication using IDLE IT + DMAn");
      pringf("PLease enter arbitrary length characters:n");
      __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
      HAL_UART_Receive_DMA(&huart1, (uint8_t*)RxBuffer, LENGTH);
     /* USER CODE END 2 */
    
      /* USER CODE BEGIN 3 */
        if (RxFlag == 1)
        {
          RxFlag = 0;
          RecCount = LENGTH - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
          HAL_UART_Transmit_DMA(&huart1, (uint8_t*)RxBuffer, RecCount);
          RecCount = 0;
          __HAL_DMA_DISABLE(&hdma_uasrt1_rx);
        }
      }
      /* USER CODE END 3 */
    
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 存储器
    +关注

    关注

    38

    文章

    7151

    浏览量

    162013
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10451

    浏览量

    206583
  • STM32
    +关注

    关注

    2240

    文章

    10675

    浏览量

    348868
  • 串口通信
    +关注

    关注

    32

    文章

    1578

    浏览量

    54871
  • dma
    dma
    +关注

    关注

    3

    文章

    536

    浏览量

    99070
收藏 人收藏

    评论

    相关推荐

    STM32串口通信基础知识点汇总,不看肯定后悔

    STM32串口通信基础知识点汇总,不看肯定后悔
    发表于 12-03 08:03

    DMA通信编程与STM32串口中断方式是什么

    目录DMA通信原理DMA的基本介绍DMA工作原理STM32DMA结构
    发表于 12-10 06:04

    STM32串口DMA问题详解

    昨天晚上在STM32串口DMA的问题上纠结了好长时间,所以今天上午写篇博客来谈谈我对串口DMA发送的理解。
    的头像 发表于 10-27 16:16 7987次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b><b class='flag-5'>DMA</b>问题详解

    STM32串口采用DMA方式发送数据测试

    (USART1~USART5),支持DMA方式通信DMA方式由于不需要CPU的参与,而是直接由DMA
    发表于 11-27 10:03 3196次阅读

    STM32中断与DMA通信编程

    接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED亮灯;接低电平时,LED灭灯。(2) 采用串口中断方式重做上周的串口通信作业。(3)
    发表于 11-26 10:21 3次下载
    <b class='flag-5'>STM32</b>中断与<b class='flag-5'>DMA</b><b class='flag-5'>通信</b>编程

    STM32中断与DMA通信编程

    接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED亮灯;接低电平时,LED灭灯。(2) 采用串口中断方式重做上周的串口通信作业。(3)
    发表于 11-26 12:06 7次下载
    <b class='flag-5'>STM32</b>中断与<b class='flag-5'>DMA</b><b class='flag-5'>通信</b>编程

    DMA通信编程与STM32串口中断方式

    目录DMA通信原理DMA的基本介绍DMA工作原理STM32DMA结构
    发表于 11-26 19:21 12次下载
    <b class='flag-5'>DMA</b><b class='flag-5'>通信</b>编程与<b class='flag-5'>STM32</b><b class='flag-5'>串口</b>中断<b class='flag-5'>方式</b>

    STM32中断与DMA通信编程

    接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED亮灯;接低电平时,LED灭灯。(2) 采用串口中断方式重做上周的串口通信作业。(3)
    发表于 11-26 19:21 11次下载
    <b class='flag-5'>STM32</b>中断与<b class='flag-5'>DMA</b><b class='flag-5'>通信</b>编程

    STM32中断与串口DMA通信

    端一管脚接一个LED,GPIOB端口一引脚接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED亮灯;接低电平时,LED灭灯。2. 采用串口中断方式重做上篇博客中的串口通信
    发表于 12-06 20:36 11次下载
    <b class='flag-5'>STM32</b>中断与<b class='flag-5'>串口</b><b class='flag-5'>DMA</b><b class='flag-5'>通信</b>

    串口通信基础知识详解

    目录通信基础知识STM32串口通信基础(UART)串口通信
    发表于 12-20 19:20 14次下载
    <b class='flag-5'>串口</b><b class='flag-5'>通信</b><b class='flag-5'>基础知识</b>详解

    STM32中的串口通信基础知识

    目录串口通信基本原理并行通信与串行通信串行通信中单工,半双工和全双工的区别按通信
    发表于 12-24 18:37 4次下载
    <b class='flag-5'>STM32</b>中的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>的<b class='flag-5'>基础知识</b>

    STM32采用串口DMA方式的USART串口通讯

    一.因为前面写了STM32串口中断之DMA通信,所以这个博客和上次的博客大同小异上次博客:STM32串口
    发表于 12-24 18:53 10次下载
    <b class='flag-5'>STM32</b>采用<b class='flag-5'>串口</b><b class='flag-5'>DMA</b><b class='flag-5'>方式</b>的USART<b class='flag-5'>串口</b>通讯

    STM32串口中断之DMA通信

    一.DMA介绍DMA详细介绍请转博客:嵌入式:初次了解STM32的USART串口通讯(中断方式)_LaiYiFei25的博客-CSDN博客
    发表于 12-24 19:08 12次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b>中断之<b class='flag-5'>DMA</b><b class='flag-5'>通信</b>

    STM32F103DMA串口通信

    本文在前两篇USART串口通信的基础上,使用DMA控制器来实现串口通信文章目录一、DMA1.DMA
    发表于 12-28 19:15 12次下载
    <b class='flag-5'>STM32F103DMA</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    STM32串口通信简明知识

    STM32串口通信简明知识
    的头像 发表于 10-25 15:48 801次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b><b class='flag-5'>通信简明知识</b>