一 引言
最近在调试stm32的多串口。没想到居然遇到那么多的问题。这里做一个总结,还是非常有必要的。
二 问题
这里先弄清楚几个问题。
1 串口有必要使用DMA吗?
DMA可以在串口高速的时候不占用CMU的资源,这在多任务系统中非常重要。无论是串口还是i2C,SPI,都是非常有必要使用DMA的,这里基础的概念东西搞清楚即可。
2 DMA的主要函数有哪些?
DMA的初始化要记得,这个千万不要漏了。不过一般是标注的,不想要你改动什么的。
/**
* Enable DMA controller clock
*/
void MX_DMA_Init(void)
{ /* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE(); /* DMA interrupt init */
/* DMA1_Channel4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
/* DMA1_Channel6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 8, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
/* DMA2_Channel4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Channel4_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(DMA2_Channel4_IRQn);
/* DMA2_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Channel5_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(DMA2_Channel5_IRQn); }
hdma_usart3_rx这里需要在这个中断注册:这个很关键
 

/**
* @brief This function handles DMA1 channel6 global interrupt.
*/
void DMA1_Channel6_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel6_IRQn 0 */ /* USER CODE END DMA1_Channel6_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart3_rx);
/* USER CODE BEGIN DMA1_Channel6_IRQn 1 */ /* USER CODE END DMA1_Channel6_IRQn 1 */
}
DMA的核心函数有两个,已经被封装的很好了。一个是DMA发送的,一个是DMA接收数据的。
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
3 DMA和串口的链接是怎么样子呢?
3 DMA和串口的链接是怎么样子呢?
其实,串口和DMA建立链接很容易的,只需要把DMA发送的第一个入参数填入对应的串口句柄即可。实例如下所示:
 
4 串口使用DMA的基本流程是什么?
首先初始化的时候
    if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)
{
Error_Handler();
} __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart3_rx); /* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspInit 1 */
__HAL_UART_CLEAR_IDLEFLAG(&huart3);
HAL_UART_Receive_DMA(&huart3, GPS_RX_BUFF, GPS_RX_BUFF_SIZE);
__HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE);
 
其次在串口中断的中的读取这块要注意:
/**
* @brief This function handles USART3 global interrupt.
*/
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */
uint16_t temp;
if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)!=RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart3);
//HAL_UART_DMAStop(&huart3);
//temp=huart3.hdmarx->Instance->CNDTR;
// if(temp<LCD_RX_Buffer_Size-1)
// LCD_Rx_Flag=String_Flag;
// else
// LCD_Rx_Flag=Byte_Flag;
gps_recive_flag++;
__HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE); HAL_UART_Receive_DMA(&huart3, GPS_RX_BUFF, GPS_RX_BUFF_SIZE); //osSemaphoreRelease(myBinarySem_LCDHandle);
}
/* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3);
/* USER CODE BEGIN USART3_IRQn 1 */ /* USER CODE END USART3_IRQn 1 */
}
 
三 总结
其实,虽然函数简单,其实,这里涉及的知识点还是非常多的。对这些底层的代码阅读和反复使用,才能了然于心。
 
 

stm32 串口DMA调试总结和反思的更多相关文章

  1. STM32串口DMA接收数据错位——暴力解决方法

    背景:两片STM32通过串口通信,为了减小CPU负担,采用DMA进行通信,发送端为STM32F103C8T6,接收端为STM32F407VET6.在调试的过程中发现,一直出现数据错位的问题,接收端尝试 ...

  2. STM32 串口DMA方式接收(转)

    STM32 是一款基于ARM Cortex-M3内核的32位MCU,主频最高可达72M.最近因为要在车机上集成TPMS功能, 便开始着手STM32的开发工作,STM32F10x系列共有5个串口(USA ...

  3. STM32串口DMA超时接收方法,可大大节约CPU时间

    //超时时间定义#define        UART1_TimeoutComp 2  //20ms#define        UART2_TimeoutComp 10  //100ms#defin ...

  4. STM32 ~ 串口DMA通道查找

    STM32F4XX: /**************************************************************************************** ...

  5. 一个严谨的STM32串口DMA发送接收机制

    关键点: 1.一个半接收机制 2.一个是寄存器的操作顺序 参考链接: https://www.eet-china.com/mp/a167050.html

  6. STM32 HAL 库实现乒乓缓存加空闲中断的串口 DMA 收发机制,轻松跑上 2M 波特率

    前言 直接储存器访问(Direct Memory Access,DMA),允许一些设备独立地访问数据,而不需要经过 CPU 介入处理.因此在访问大量数据时,使用 DMA 可以节约可观的 CPU 处理时 ...

  7. STM32 串口功能 库函数 详解和DMA 串口高级运用(转载)

    数据传输时要从支持那些相关的标准?传输的速度?什么时候开始?什么时候结束?传输的内容?怎样防止通信出错?数据量大的时候怎么弄?硬件怎么连接出发,当然对于stm32还要熟悉库函数的功能 具起来rs232 ...

  8. STM32之串口DMA接收不定长数据

    STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...

  9. STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085和串口只发送数据不能接收数据问题

    STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085的问题讨论:http://www.rt-thr ...

  10. STM32使用DMA发送串口数据

    1.概述 上一篇文章<STM32使用DMA接收串口数据>讲解了如何使用DMA接收数据,使用DMA外设和串口外设,使用的中断是串口空闲中断.本篇文章主要讲解使用DMA发送数据,不会讲解基础的 ...

随机推荐

  1. ch57x/ch58x开启仿真

    本次使用的平台是MounRiver Studio,使用的是WCH的CH582m与WCH-LinkE 仿真之前确保LinkE处在Risc-V模式下  空闲时蓝灯常灭 Step1:首先通过ISP工具开启两 ...

  2. Linux shell 判断变量是否包含某个字符串的几种方法

    方法一:利用grep查找 strA="long string" strB="string" result=$(echo $strA | grep "$ ...

  3. 【Flink入门修炼】1-3 Flink WordCount 入门实现

    本篇文章将带大家运行 Flink 最简单的程序 WordCount.先实践后理论,对其基本输入输出.编程代码有初步了解,后续篇章再对 Flink 的各种概念和架构进行介绍. 下面将从创建项目开始,介绍 ...

  4. 借助Rich库实现Pandas DataFrame颜值升级

    pandas的DataFrame功能强大自不必说,它可以帮助我们极大的提高统计分析的效率. 不过,使用DataFrame开发我们的分析程序的时候,经常需要打印出DataFrame的内容,以验证和调试数 ...

  5. JS LeetCode 303. 区域和检索 - 数组不可变,一维数组的前缀和

    壹 ❀ 引 本题来自LeetCode303. 区域和检索 - 数组不可变,属于一道简单题,不过题目期望的做法我也是看了题解才懂得,这里大致做个记录,题目描述如下: 给定一个整数数组 nums,求出数组 ...

  6. NC24727 [USACO 2010 Feb G]Slowing down

    题目链接 题目 题目描述 Every day each of Farmer John's N (1 <= N <= 100,000) cows conveniently numbered ...

  7. Vue DevTools 安装和浏览器跳转到编辑器指定组件

    Vue DevTools install and Open component in editor 1.在谷歌浏览器安装vue 插件 1.1下载vue插件 链接:https://pan.baidu.c ...

  8. lombok-ex 编译时注解框架,性能完爆 AOP

    lombok-ex lombok-ex 是一款类似于 lombok 的编译时注解框架. 主要补充一些 lombok 没有实现,且自己会用到的常见工具. 编译时注解性能无任何损失,一个注解搞定一切,无三 ...

  9. 【Unity3D】动画混合

    1 简介 ​ 2D动画.人体模型及动画.人物跟随鼠标位置中介绍了 Aniamtion.Animator.人体模型.人体骨骼.人体动画等基础知识及人体动画的应用,本文将进一步介绍动画混合. ​ 实现动画 ...

  10. Java集合框架学习(十五) ListIterator接口详解

    ListIterator介绍 一个为list对象设计的迭代器,允许开发人员在2个方向上迭代,修改和获得list迭代位置. ListIterator 没有所谓当前元素. 它的游标位置总是位于previo ...