DMA,全称是Direct Memory Access,中文意思为直接存储器访问

DMA可用于实现外设与存储器之间或者存储器与存储器之间数据传输的高效性

DMA请求映像

各通道的DMA1请求:

各通道的DMA2请求:

DMA配置步骤

1.使能DMA控制器时钟

2.初始化DMA通道,DMA_InitTypeDef

3.使能外设DMA功能

4.开启DMA的通道

5.查询DMA传输状态

举例

u8 txBuffer[50] = {0};
u8 rxBuffer[50] = {0}; void DMA_send(u32 num)
{
DMA_Cmd(DMA1_Channel4, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel4, num);
DMA_Cmd(DMA1_Channel4, ENABLE); //开启DMA的通道
} void DMA1_Channel4_IRQHandler(void)
{
while(DMA_GetFlagStatus(DMA1_FLAG_TC4) != SET); DMA_ClearFlag(DMA1_FLAG_TC4);
} typedef struct
{
uint32_t DMA_PeripheralBaseAddr; //外设地址
uint32_t DMA_MemoryBaseAddr; //存储器地址
uint32_t DMA_DIR; //数据传输方向
uint32_t DMA_BufferSize; //数据传输数量
uint32_t DMA_PeripheralInc; //外设地址增量模式
uint32_t DMA_MemoryInc; //存储器地址增量模式
uint32_t DMA_PeripheralDataSize; //外设数据宽度
uint32_t DMA_MemoryDataSize; //存储器数据宽度
uint32_t DMA_Mode; //循环模式
uint32_t DMA_Priority; //通道优先级
uint32_t DMA_M2M; //存储器到存储器模式
}DMA_InitTypeDef; void DMA_nvic_init(DMA_Channel_TypeDef *DMAy_Channelx, uint8_t NVIC_IRQChannel)
{
NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = NVIC_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(DMAy_Channelx, DMA_IT_TC, ENABLE);
} void DMA_init(DMA_Channel_TypeDef *DMAy_Channelx, uint32_t dir, u32 mem_addr, u32 buf_size)
{
DMA_InitTypeDef dma = {0}; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA控制器时钟 dma.DMA_PeripheralBaseAddr = (u32)&USART1->DR; //USART1数据寄存器
dma.DMA_MemoryBaseAddr = mem_addr;
dma.DMA_DIR = dir;
dma.DMA_BufferSize = buf_size;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //不执行外设地址增量操作
dma.DMA_MemoryInc = DMA_MemoryInc_Enable; //执行存储器地址增量操作
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma.DMA_Mode = DMA_Mode_Normal; //不执行循环操作
dma.DMA_Priority = DMA_Priority_Medium; //中
dma.DMA_M2M = DMA_M2M_Disable; //非存储器到存储器模式
DMA_Init(DMAy_Channelx, &dma); //初始化DMA通道 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); //使能DMA发送模式
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); //使能DMA接收模式
} void USART1_IRQHandler(void)
{
uint16_t rxCount; if(USART_GetFlagStatus(USART1, USART_FLAG_IDLE) != RESET)
{
//清中断
USART1->SR;
USART1->DR; //接收
DMA_Cmd(DMA1_Channel5, DISABLE);
rxCount = sizeof(rxBuffer) - DMA_GetCurrDataCounter(DMA1_Channel5); //获取接收字节数
DMA_SetCurrDataCounter(DMA1_Channel5, sizeof(rxBuffer)); //计数重置
DMA_Cmd(DMA1_Channel5, ENABLE); //开启下一次接收 //发送
DMA_send(rxCount); //开启一次发送
}
} int main(void)
{
//USART1发送
DMA_init(DMA1_Channel4, DMA_DIR_PeripheralDST, (u32)txBuffer, sizeof(txBuffer));
DMA_nvic_init(DMA1_Channel4, DMA1_Channel4_IRQn); //USART1接收
DMA_init(DMA1_Channel5, DMA_DIR_PeripheralSRC, (u32)rxBuffer, sizeof(rxBuffer));
DMA_Cmd(DMA1_Channel5, ENABLE); //使能接收 while(1)
{
led1 = ~led1;
delay_ms(1000);
}
}

stm32F1 DMA的更多相关文章

  1. 嵌入式单片机stm32之DMA实验

    一. 对于大容量的STM32芯片有2个DMA控制器,控制器1有7个通道,控制器2有5个通道 每个通道都可以配置一些外设的地址. 二. 通道的配置过程: 1. 首先设置CPARx寄存器和CMARx寄存器 ...

  2. STM32F1和STM32F4 区别

    STM32F4相对于STM32F1的改进不只一点点,为了便于初学者了解,我们比对相关资料将改进点进行了汇总. STM32F1和STM32F4 区别   (安富莱整理)u  F1采用Crotex M3内 ...

  3. STM32F10x_ADC三通道DMA连续转换(3通道、软件单次触发)

    Ⅰ.概述 上一篇文章讲述的内容是:三通道逐次转换(单次.单通道软件触发),也就是说3条通道要三次软件触发才能完成转换,而且是通过软件读取转换数值. 本文讲述三通道DMA连续转换(3通道.软件单次触发) ...

  4. stm32 DMA配置

    DMA就是将一个地址空间复制到另外一个地址空间.DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备直接传送数据,使CPU的效率大大的提高 ...

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

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

  6. stm32 ADC模数转换 ADC多通道 ADC DMA

    通过调节电位器,改变AD转换值和电压值 STM32F1 ADC 配置步骤 1.使能GPIO时钟和ADC时钟 2.配置引脚模式为模拟输入 3.配置ADC的分频因子 4.初始化ADC参数,ADC_Init ...

  7. 数据传输还用 CPU?不如交给 DMA 吧!

    https://mp.weixin.qq.com/s/CQQSV26Xvmt2xuAPFnh-YQ 鱼鹰  鱼鹰谈单片机 3月3日 预计阅读时间: 9 分钟 "数据传输耗时又耗力?交给 DM ...

  8. 【STM32】使用DMA+SPI传输数据

    DMA(Direct Memory Access):直接存储器访问 一些简单的动作,例如复制或发送,就可以不透过CPU,从而减轻CPU负担 由于本人使用的是正点原子开发板,部分代码取自里面的范例 本篇 ...

  9. STM32基于HAL库通过DMA读写SDIO

    通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...

随机推荐

  1. 算法习题---3.12浮点数(UVa11809)

    一:题目 尴尬的非会员水印 二:题目摘要 1.int和float比较 int共32位,可以表示的最大的数为2^32次方 float虽然也是32位,但是是以指数形式保存,指数占8位(含符号),最大127 ...

  2. python命令行参数解析OptionParser类用法实例

    python命令行参数解析OptionParser类用法实例 本文实例讲述了python命令行参数解析OptionParser类的用法,分享给大家供大家参考. 具体代码如下:     from opt ...

  3. [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /usr/local/nginx/conf/nginx.conf:1

    带有sudo 权限执行就可以了

  4. mysql新建数据库(database)设置为utf8

    CREATE DATABASE IF NOT EXISTS yourdbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

  5. C,OC,C++语言对比

    1.C与OC.C++的区别: C语言的特点:面向过程 1)C语言是结构化语言,层次清晰,调试和维护比较容易 2)表现能力和处理能力比较强,可直接访问内存的物理地址 3)c语言实现对硬件的编辑,c语言课 ...

  6. 调用API修改Ocelot的配置文件

    Ocelot是一个基于.net core的开源webapi服务网关开源项目,功能比较强大,Github项目地址为:https://github.com/ThreeMammals/Ocelot,关于Oc ...

  7. 转 Linux平台卸载MySQL总结

    如何在Linux下卸载MySQL数据库呢? 下面总结.整理了一下Linux平台下卸载MySQL的方法. MySQL的安装主要有三种方式:二进制包安装(Using Generic Binaries).R ...

  8. 控件setText与setValue赋值顺序先后区别

    1.text与value设置不同的值一定要先赋值 value后赋值text, 否则全为value值 2.若只setValue,则getValue 与 getText获取的值全为value值 $('#t ...

  9. [知乎]鲲鹏920对比intel8180

    作者:韩朴宇链接:https://www.zhihu.com/question/308298687/answer/568737742来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

  10. java多线程上篇(二) -- 进程的控制、同步

    一.进程的控制 进程的基本数据信息是操作系统控制管理进程的数据集合,这些信息就是用来控制进程的,此处我们说的进程控制就是进程的管理. 比如进程有状态,那么进程的创建.终止,状态的切换,这都不是进程自主 ...