首先要解决DMA怎么知道要接收的数据何时开始,何时结束的问题。而且每次传输完数据,要改变下一次数据长度。

如果把DMA设成循环模式肯定是不行的,所以把DMA设置成正常模式。

STM32的串口有监测总线是否处于空闲的功能,我们可以使用这个功能,当数据传输完总线变成空闲状态时产生中断,来对收到的数据进行处理。因此整个过程就变成:当一堆数据开始传输,DMA默默地把数据搬运到内存中,当这堆数据传输完成,总线变成空闲状态时,马上产生中断,在中断服务程序中去做相应处理。

初始化程序:

#define DMA_Rec_Len 10  //数据缓冲区大小
u8 value[DMA_Rec_Len];void uart_init_DMA_IN(u32 bound)
{//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;DMA_InitTypeDef DMA_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
//   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟USART_DeInit(USART1);  //复位串口1//USART1_TX   PA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9//USART1_RX  A.10GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA10//Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启空闲中断USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);   //使能串口1 DMA接收USART_Cmd(USART1, ENABLE);                    //使能串口 //相应的DMA配置DMA_DeInit(DMA1_Channel5);   //将DMA的通道5寄存器重设为缺省值  串口1对应的是DMA通道5DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;  //DMA外设ADC基地址DMA_InitStructure.DMA_MemoryBaseAddr = (u32)value;  //DMA内存基地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从外设读取发送到内存DMA_InitStructure.DMA_BufferSize = DMA_Rec_Len;  //DMA通道的DMA缓存的大小DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常缓存模式DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输DMA_Init(DMA1_Channel5, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道DMA_Cmd(DMA1_Channel5, ENABLE);  //正式驱动DMA传输
}

中断服务程序:

void USART1_IRQHandler(void)                 //串口1中断服务程序
{char i;if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾){USART_ReceiveData(USART1);//读取数据 注意:这句必须要,否则不能够清除中断标志位。Usart1_Rec_Cnt = DMA_Rec_Len-DMA_GetCurrDataCounter(DMA1_Channel5); //算出接本帧数据长度//***********帧数据处理函数************//printf ("The lenght:%d\r\n",Usart1_Rec_Cnt);printf ("The data:\r\n");for(i=0;i<Usart1_Rec_Cnt;i++){USART_SendData(USART1,value[i]);while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);}printf ("\r\nOver! \r\n");//*************************************//USART_ClearITPendingBit(USART1, USART_IT_IDLE);         //清除中断标志DMA_Cmd(DMA1_Channel5,DISABLE);//重新设置传输数据长度  DMA_SetCurrDataCounter(DMA1_Channel5,DMA_Rec_Len); DMA_Cmd(DMA1_Channel5,ENABLE);  //开始下一次DMA}
} 

设置DMA为正常模式,即只传输一次,当完成一次数据传输后,进入中断,对接收到的数据进行处理。然后清除中断标志,重新启动DMA进行下一次传输。

思路来自:http://www.openedv.com/thread-63849-1-1.html

STM32使用DMA从串口读可变长度数据到内存相关推荐

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

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

  2. STM32使用DMA接收串口数据

    目录 01.概述 02.DMA接收 03.中断 04.代码 01.概述 在之前的文章里<STM32串口详解>和<STM32 DMA详解>文章中,详细讲解了STM32的串口和DM ...

  3. STM32F103之DMA实验,内存通过DMA向串口1发送数据

    #include "dma.h" // //DMA_InitTypeDef DMA_InitStructure;u16 DMA1_MEM_LEN;//保存DMA每次数据传送的长度 ...

  4. STM32使用DMA从串口读数据到内存

    使用DMA从串口读数据到内存和从内存搬数据到串口一样,只是要注意所使用的DMA通道不一样. 当配置好后,如果串口上有数据传输,DMA就自动把数据搬到内存中. 当工作在正常模式,DMA搬运了设定长度的数 ...

  5. STM32:DMA方式接收SPI总线数据,并按照协议进行处理

    一.前言 为满足高速数据传输的要求,采用SPI总线.MCU端(STM32F072  Cortex-M0)接收CPU发送的SPI数据(数据18个字节为一包,起始包为0xAA,最后一包为CheckSum校 ...

  6. STM32学习之串口采用DMA收发数据:需要利用状态机加DMA加串口

    写在前面 在学习这一节知识点的时候,真的是感觉太抽象了,没有一个合适的视频讲的我有那种豁然开朗的感觉,直到我看到了这篇文章,大家可以去看看,里面的描述特别形象. 链接:https://blog.csd ...

  7. javarxtx串口接收时数据会分成好几段_【STM32】串口通信基本原理(超基础、详细版)...

    STM32F1xx官方资料: <STM32中文参考手册V10>-第25章通用同步异步收发器(USART) 通信接口背景知识 设备之间通信的方式 一般情况下,设备之间的通信方式可以分成并行通 ...

  8. STM32平台的USART串口通信

    本文目的是编写stm32串口通信程序,实现stm32上电自动循环发送hello LYJ!!!,并可通过上位机控制stm32串口发送与否.通过亲自做一下USART串口通信实验,学习如何使用stm32平台 ...

  9. STM32从零到一,从标准库移植到HAL库,UART串口1以DMA模式收发不定长数据代码详解+常见问题 一文解析

    前言 本文的参考资料 感谢提供标准库版本的CSDN同学:这两篇文章至少是我看过的最详细的标准库配置DMA版本.而且代码实测稳定能用. STM32 | DMA配置和使用如此简单(超详细)_...| .. ...

最新文章

  1. 数据包编辑工具bittwiste
  2. 机器视觉:mvs相机调试
  3. rtmp 常用字段含义
  4. JavaFX技巧30:带有DropShadow的ScrollPane
  5. linux下recv 、send阻塞、非阻塞区别和用法
  6. 前端学习(731):函数的使用
  7. 12 Essential Bootstrap Tools for Web Designers
  8. fastapi 传输文件存文件_揭秘|国内影视文件传输的真相,跨境文件传输更不简单...
  9. MySQL explain 命令
  10. OSChina 周四乱弹 ——因为穷和丑错过的体验
  11. C++新特性探究(八):初始化列表(Initialization List)再探究
  12. 随想录(fpga处理图像的优缺点)
  13. 雷电三接口有什么用_「滕·Gallery」我是如何用奥睿科雷电三硬盘盒来弥补之前的失误的? | 数字尾巴 分享美好数字生活...
  14. xml文档的pull解析与SAX解析
  15. 容器与拷贝构造函数的问题
  16. 文字时钟罗盘动态html代码_文字时钟罗盘动态html代码工具-文字时钟APP最新版下载-游戏窝...
  17. Adapter模式 适配器模式
  18. 移动 APP 的测试方法,以及移动专项测试的思路与方法
  19. 工作 10 年后,我突然决定读硕士了!
  20. DeiT:Training data-efficient image transformers distillation through attention

热门文章

  1. 使用TensorFlow1.0及以上版本的问题
  2. “纹身贴皮电路“:未来在皮肤上画个电路就能监测身体健康状况
  3. Magic Leap大举进军AR医疗:新品率先与医疗机构合作,挖走HoloLens老客户
  4. 换血吃药改基因,硅谷富豪们想用钱收买死神丨视频
  5. 今年央视春晚的创意担当,给了这个1岁的拓荒牛机器人
  6. 对话图灵奖得主John Hennessy,他说对美国留学签证变化很忧心
  7. 小鹏汽车招股书,满是智能技术自研的标签
  8. Service Mesh:调度千军万马微服务,2.0妥妥的
  9. 华为算力最强AI芯片商用:2倍于英伟达V100!开源AI框架,对标TensorFlow和PyTorch...
  10. JS编程建议——8:谨慎使用运算符(3)