stm32F1 DMA
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的更多相关文章
- 嵌入式单片机stm32之DMA实验
一. 对于大容量的STM32芯片有2个DMA控制器,控制器1有7个通道,控制器2有5个通道 每个通道都可以配置一些外设的地址. 二. 通道的配置过程: 1. 首先设置CPARx寄存器和CMARx寄存器 ...
- STM32F1和STM32F4 区别
STM32F4相对于STM32F1的改进不只一点点,为了便于初学者了解,我们比对相关资料将改进点进行了汇总. STM32F1和STM32F4 区别 (安富莱整理)u F1采用Crotex M3内 ...
- STM32F10x_ADC三通道DMA连续转换(3通道、软件单次触发)
Ⅰ.概述 上一篇文章讲述的内容是:三通道逐次转换(单次.单通道软件触发),也就是说3条通道要三次软件触发才能完成转换,而且是通过软件读取转换数值. 本文讲述三通道DMA连续转换(3通道.软件单次触发) ...
- stm32 DMA配置
DMA就是将一个地址空间复制到另外一个地址空间.DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备直接传送数据,使CPU的效率大大的提高 ...
- STM32之串口DMA接收不定长数据
STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...
- stm32 ADC模数转换 ADC多通道 ADC DMA
通过调节电位器,改变AD转换值和电压值 STM32F1 ADC 配置步骤 1.使能GPIO时钟和ADC时钟 2.配置引脚模式为模拟输入 3.配置ADC的分频因子 4.初始化ADC参数,ADC_Init ...
- 数据传输还用 CPU?不如交给 DMA 吧!
https://mp.weixin.qq.com/s/CQQSV26Xvmt2xuAPFnh-YQ 鱼鹰 鱼鹰谈单片机 3月3日 预计阅读时间: 9 分钟 "数据传输耗时又耗力?交给 DM ...
- 【STM32】使用DMA+SPI传输数据
DMA(Direct Memory Access):直接存储器访问 一些简单的动作,例如复制或发送,就可以不透过CPU,从而减轻CPU负担 由于本人使用的是正点原子开发板,部分代码取自里面的范例 本篇 ...
- STM32基于HAL库通过DMA读写SDIO
通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...
随机推荐
- java最简单复制文件方法,不依赖任何框架
java最简单复制文件方法 把java2.txt内容复制到java.txt中 import java.io.File; import java.io.IOException; import jav ...
- web手工项目02-注册功能输入分析,处理,输出方法-测试用例及缺陷编写-首页轮播图和购物车
web手工项目第二天笔记 昨日回顾 搭建测试环境(WAMP,phpStudy,tpshop项目文件) 熟悉项目(四个步骤,三个来源) 项目测试流程(需求评审,测试计划与方案,测试用例设计与评审,测试执 ...
- VCL组件之TPanel
TPanel位于Standard组件面板上,也是常用的一种容器控件.面板的一个优点就是放在面板上的组件称为面板的一部分,因此它们与面板一起移动.这在设计阶段很有用. Panel组件的大部分功能在于其A ...
- python2.6.6升级python2.7.14
Centos 6.8系统镜像默认安装的 python 环境是 2.6.6,线上需求需要升级到 2.7.14 版本,网上找了相关资料,升级 python 版本比较容易,但 yum/pip 等命令的使用也 ...
- shuffle 打乱一维数组
<?php $arr = range(,); print_r($arr); echo '<br />'; shuffle($arr); print_r($arr); ?> Ar ...
- Java多线程——线程池使用示例
示例代码: import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public cla ...
- 看看BeginInvoke的用法,亲爱的们
看看它是杂带参数的哈 using System; using System.Threading; class MyTest { delegate bool deleTest(string a,stri ...
- 项目中常用的19条MySQL优化技巧
原文:https://segmentfault.com/a/1190000012155267 声明一下:下面的优化方案都是基于 “ Mysql-索引-BTree类型 ” 的 一.EXPLAIN 做My ...
- 【C# 开发技巧】在VS程序如何取消.vshost的进程
我们在双击执行一个EXE程序,会有两个进程,程序关闭之后,貌似只能关闭你的程序,附加的vshost.exe仍然存在.如下图 解决方案: 1.在调试页面,改成release,同时取消最后一项启用承载进程 ...
- 《Fluid Engine Development》 学习笔记3-光滑粒子流体动力学
用粒子表示流体最热门的方法就是就是光滑粒子流体动力学(Smoothed Particle Hydrodynamics (SPH).) 这种方法模糊了流体的边界,用有限数量的粒子代表流体,该方法的基本思 ...