你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 DMA总结库函数串口使用DMA

[复制链接]
STMCU小助手 发布时间:2022-5-8 19:00
前言
DMA,全称为:Direct Memory Access,即直接存储器访问。DMA 传输方式无需 CPU 直接
控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备
开辟一条直接传送数据的通路,能使 CPU 的效率大为提高。

一、配置步骤
1)使能 DMA 时钟


  1. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能 DMA 时钟
复制代码


2)初始化 DMA 通道 4 参数


  1. void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)
复制代码
  1. DMA_InitTypeDef DMA_InitStructure;
  2. DMA_InitStructure.DMA_PeripheralBaseAddr = &USART1->DR; //DMA 外设 ADC 基地址
  3. DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA 内存基地址
  4. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //从内存读取发送到外设
  5. DMA_InitStructure.DMA_BufferSize = 64; //DMA 通道的 DMA 缓存的大小
  6. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不变
  7. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增
  8. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //8 位
  9. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 8 位
  10. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式
  11. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA 通道 x 拥有中优先级
  12. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存传输
  13. DMA_Init(DMA_CHx, &DMA_InitStructure); //根据指定的参数初始化
复制代码

3)使能串口 DMA 发送
  1. USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
复制代码

4)使能 DMA1 通道 4,启动传输

  1. DMA_Cmd(DMA_CHx, ENABLE);
复制代码

5)查询 DMA 传输状态

在 DMA 传输过程中,我们要查询 DMA 传输通道的状态:

FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)

比如我们要查询 DMA 通道 4 传输是否完成:

DMA_GetFlagStatus(DMA2_FLAG_TC4);

获取当前剩余数据量大小的函数:
  1. uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx)
复制代码

比如我们要获取 DMA 通道 4 还有多少个数据没有传输:
  1. DMA_GetCurrDataCounter(DMA1_Channel4);
复制代码

二、代码实例
我们需要创建dma.c 文件和其头文件 dma.h,
同时我们要引入 DMA 相关的库函数文件 stm32f10x_dma.c 和 stm32f10x_dma.h。

——dma.c 文件

  1. #include "dma.h"
  2. DMA_InitTypeDef DMA_InitStructure;
  3. u16 DMA1_MEM_LEN;//保存 DMA 每次数据传送的长度
  4. //DMA1 的各通道配置
  5. //这里的传输形式是固定的,这点要根据不同的情况来修改
  6. //从存储器->外设模式/8 位数据宽度/存储器增量模式
  7. //DMA_CHx:DMA 通道 CHx
  8. //cpar:外设地址
  9. //cmar:存储器地址
  10. //cndtr:数据传输量
  11. void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
  12. {
  13. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能 DMA 时钟
  14. DMA_DeInit(DMA_CHx); //将 DMA 的通道 1 寄存器重设为缺省值
  15. DMA1_MEM_LEN=cndtr;
  16. DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA 外设 ADC 基地址
  17. DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA 内存基地址
  18. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向内存到外设
  19. DMA_InitStructure.DMA_BufferSize = cndtr; //DMA 通道的 DMA 缓存的大小
  20. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不变
  21. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增
  22. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  23. //数据宽度为 8 位
  24. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度
  25. //为 8 位
  26. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式
  27. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DM 通道拥有中优先级
  28. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存传输
  29. DMA_Init(DMA_CHx, &DMA_InitStructure); //初始化 DMA 的通道
  30. }
  31. //开启一次 DMA 传输
  32. void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
  33. {
  34. DMA_Cmd(DMA_CHx, DISABLE ); //关闭 USART1 TX DMA1 所指示的通道
  35. DMA_SetCurrDataCounter(DMA1_Channel4,DMA1_MEM_LEN);//设置 DMA 缓存的大小
  36. DMA_Cmd(DMA_CHx, ENABLE); //使能 USART1 TX DMA1 所指示的通道
  37. }
复制代码

收藏 评论0 发布时间:2022-5-8 19:00

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版