stm32寄存器版学习笔记08 DMA
DMA(Direct Memory Access),直接存储器访问。DMA传输方式无需CPU直接控制传输,通过硬件为RAM与I/O设备开辟一条直接传送数据的通路,使CPU效率大大提高。stm32f103有2个DMA控制器,DMA1有7个通道,DMA2有5个通道,专门用来管理来自外设对存储器的访问请求,还有一个仲裁器来协调各个DMA请求的优先权。
1.DMA各通道请求
从外设产生的DMA请求通过逻辑"或"输入到DMA控制器,这就意味着同时只能有一个请求有效。
例如,串口1发送的DMA,就要用到DMA1的通道4。


2.DMA1通道4(串口1发送)配置步骤
①设置外设地址
设置外设地址通过DMA1_CPAR4来设置,在这个寄存器里面写入&USART1_DR的值。该地址将作为DMA传输的目标地址。
DMA通道x外设地址寄存器(DMA_CPARx)(x = 1…7)

Eg:DMA_CHx->CPAR=cpar; //DMA1 外设地址
DMA_CHx->CPAR=&USART1_DR;
②设置存储器地址
设置存储器地址通过DMA1_CMAR4来设置,假设要把数组SendBuf作为存储器,在该寄存器写入&SendBuf的值。该地址将作为DMA传输的源地址


Eg:DMA_CHx->CMAR=(u32)cmar; //DMA1,存储器地址
③设置传输数据量
写入此次要传输的数据量,也就是SendBuf的大小。该寄存器在DMA启动后自减,每次新的DMA传输都重新向该寄存器写入要传输的数据量。
DMA通道x传输数量寄存器(DMA_CNDTRx)(x = 1…7)

Eg:DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量
④设置通道4的配置信息
若有多个通道,则要设置优先级,编号越小优先级越高。
DMA通道x配置寄存器(DMA_CCRx)(x = 1…7)




⑤使能DMA1通道4,启动传输
DMAx_CCRx 最低位开启DMA传输。注意要设置USART1的使能DMA传输位,通过USART1->CR3的第七位设置,这样就可以启动一次USART1的DMA传输了。
3.DMA中断状态显示及清除
DMA中断状态寄存器(DMA_ISR)



DMA中断标志清除寄存器(DMA_IFCR)


Eg:if(DMA1->ISR&(1<<13))//等待通道4传输完成
{
DMA1->IFCR|=1<<13;//清除通道4传输完成标志
break;
}
4.DMA1通道4(串口1发送)应用
u16 DMA1_MEM_LEN;//保存DMA每次数据传送的长度
//DMA1的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_CHx:DMA通道CHx
//cpar:外设地址
//cmar:存储器地址
//cndtr:数据传输量
void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
RCC->AHBENR|=<<; //开启DMA1时钟
delay_ms(); //等待DMA时钟稳定
DMA_CHx->CPAR=cpar; //DMA1 外设地址
DMA_CHx->CMAR=(u32)cmar; //DMA1,存储器地址
DMA1_MEM_LEN=cndtr; //保存DMA传输数据量
DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量
DMA_CHx->CCR=0X00000000; //复位
DMA_CHx->CCR|=<<; //从存储器读
DMA_CHx->CCR|=<<; //普通模式
DMA_CHx->CCR|=<<; //外设地址非增量模式
DMA_CHx->CCR|=<<; //存储器增量模式
DMA_CHx->CCR|=<<; //外设数据宽度为8位
DMA_CHx->CCR|=<<; //存储器数据宽度8位
DMA_CHx->CCR|=<<; //中等优先级
DMA_CHx->CCR|=<<; //非存储器到存储器模式
}
//开启一次DMA传输
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
DMA_CHx->CCR&=~(<<); //关闭DMA传输
DMA_CHx->CNDTR=DMA1_MEM_LEN; //DMA1,传输数据量
DMA_CHx->CCR|=<<; //开启DMA传输
}
DMA.c
const u8 TEXT_TO_SEND[]={"STM32 DMA USART1"};
#define TEXT_LENTH sizeof(TEXT_TO_SEND)-1 //TEXT_TO_SEND字符串长度(不包含结束符)
u8 SendBuff[(TEXT_LENTH+)*];
int main(void)
{
u16 i;
u8 t=;
float pro=; //进度
Stm32_Clock_Init(); //系统时钟设置
uart_init(,); //串口初始化为9600
delay_init(); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init(); //初始化LCD
KEY_Init(); //按键初始化
MYDMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,(TEXT_LENTH+)*);//DMA1通道4,外设为串口1,存储器为SendBuff,长(TEXT_LENTH+2)*100.
POINT_COLOR=RED;//设置字体为红色
//显示提示信息
for(i=;i<(TEXT_LENTH+)*;i++)//填充ASCII字符集数据
{
if(t>=TEXT_LENTH)//加入换行符
{
SendBuff[i++]=0x0d;
SendBuff[i]=0x0a;
t=;
}else SendBuff[i]=TEXT_TO_SEND[t++];//复制TEXT_TO_SEND语句
}
POINT_COLOR=BLUE;//设置字体为蓝色
i=;
while()
{
t=KEY_Scan();
if(t==KEY0_PRES)//KEY0按下
{
LCD_ShowString(,,,,,"Start Transimit....");
LCD_ShowString(,,,,," %");//显示百分号
printf("\r\nDMA DATA:\r\n ");
USART1->CR3=<<; //使能串口1的DMA发送
MYDMA_Enable(DMA1_Channel4);//开始一次DMA传输!
//等待DMA传输完成,此时我们来做另外一些事,点灯
//实际应用中,传输数据期间,可以执行另外的任务
while()
{
if(DMA1->ISR&(<<))//等待通道4传输完成
{
DMA1->IFCR|=<<;//清除通道4传输完成标志
break;
}
pro=DMA1_Channel4->CNDTR;//得到当前还剩余多少个数据
pro=-pro/((TEXT_LENTH+)*);//得到百分比
pro*=; //扩大100倍
LCD_ShowNum(,,pro,,);
}
LCD_ShowNum(,,,,);//显示100%
LCD_ShowString(,,,,,"Transimit Finished!");//提示传送完成
}
i++;
delay_ms();
if(i==)
{
LED0=!LED0;//提示系统正在运行
i=;
}
}
}
main.c
stm32寄存器版学习笔记08 DMA的更多相关文章
- stm32寄存器版学习笔记06 输入捕获(ETR脉冲计数)
STM32外部脉冲ETR引脚:TIM1-->PA12;TIMER2-->PA0:TIMER3-->PD2;TIMER4-->PE0… 1.TIM2 PA0计数 配置步骤 ①开启 ...
- stm32寄存器版学习笔记07 ADC
STM32F103RCT有3个ADC,12位主逼近型模拟数字转换器,有18个通道,可测量16个外部和2个内部信号源.各通道的A/D转换可以单次.连续.扫描或间断模式执行. 1.通道选择 stm32把A ...
- stm32寄存器版学习笔记05 PWM
STM32除TIM6和TIM7外都可以产生PWM输出.高级定时器TIM1和TIM8可以同时产生7路PWM,通用定时器可以产生4路PWM输出. 1.TIM1 CH1输出PWM配置步骤 ①开启TIM1时钟 ...
- stm32寄存器版学习笔记03 外部中断
stm32的每个I/O口都可以作为中断输入,要把I/O口设置为外部中断输入,必须将I/O口设置为上拉/下拉输入 或 浮空输入(但浮空的时候外部一定要带上拉或下拉电阻,否则可能导致 中断不停的触发),干 ...
- stm32寄存器版学习笔记04 定时计数器中断
STM32共有8个定时计数器,其中TIME1和TIME8是高级定时器,TIME2~TIME5是通用定时器,TIME6和TIME7是基本定时器.以TIME3为例总结定时计数器的基本用法. 1.TIM3的 ...
- stm32寄存器版学习笔记02 串口通信
stm32F103RCT6提供5路串口.串口的使用,只要开启串口时钟,设置相应的I/O口的模式,然后配置下波特率.数据位长度.奇偶校验等信息,即可使用. 1.串口的配置步骤 ①串口时钟使能 APB2外 ...
- stm32寄存器版学习笔记01 GPIO口的配置(LED、按键)
STM32的I/O口可以由软件配置成如下8种模式:输入浮空.输入上拉.输入下拉.模拟输入.开漏输出.推挽输出.推挽式复用功能及开漏复用功能.每个I/O口由7个寄存器来控制:配置模式的端口配置寄存器CR ...
- stm32寄存器版学习笔记10 SPI
SPI(Serial Peripheral Interface),串行外围设备接口.SPI是一种高速的.全双工.同步的通信总线. SPI接口一般使用4条线通信: MISO 主设备数据输入,从设备数据输 ...
- stm32寄存器版学习笔记09 IIC
I²C(Inter-Integrated Circuit)总线是一种两线式串行总线,用于连接微控制器及其外设,是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据. IIC总线在传送数据过程中 ...
随机推荐
- G - 锘爷考驾照
2017-07-17 11:56:06 writer:pprp 题目描述 大家都知道,锘爷是XDUdp第一人,所以锘爷决定要去考驾照!(这很有逻辑吧),他为了一次考到驾照,于是买了一辆越野车从学校开回 ...
- java 连接 redis集群时报错:Could not get a resource from the pool
由于弄这个的时候浪费了太多的时间,所以才记录下这个错,给大伙参考下 检查了一下,配置啥的都没问题的,但在redis集群机器上就可以,错误如下: Exception in thread "ma ...
- CDN专业一站式解决方案
调度,弱网加速,动态防御,无限节点(重)新技术
- mysql数据库开放远程连接的方法
web与mysql数据库分离开来是一个不错的选择,避免因为大量的数据库查询占用CPU而使web资源不足,同时可以使web服务器的资源尽最大的提供浏览服务,而数据库服务器单独的只处理数据库事物. 适用范 ...
- 负载均衡,会话保持,session同步
一,什么负载均衡 一个新网站是不要做负载均衡的,因为访问量不大,流量也不大,所以没有必要搞这些东西.但是随着网站访问量和流量的快速增长,单台服务器受自身硬件条件的限制,很难承受这么大的访问量.在这种情 ...
- 新男人八题---AStringGame
终于完成进度男人1/8,为了这题学了sam= = 题意先有一个串,n个子串,两个人轮流每次在子串上加字符,要求加完后还是原串的子串,最后不能加的就是输者,求赢的人 解法:sam之后在构造的状态图上跑s ...
- HDU5521-最短路-建图
Meeting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- POJ 1160 经典区间dp/四边形优化
链接http://poj.org/problem?id=1160 很好的一个题,涉及到了以前老师说过的一个题目,可惜没往那上面想. 题意,给出N个城镇的地址,他们在一条直线上,现在要选择P个城镇建立邮 ...
- IOS-H5容器的一些探究:UIWebView和WKWebView的比较和选择
一.Native开发中为什么需要H5容器 Native开发原生应用是手机操作系统厂商(目前主要是苹果的iOS和google的Android)对外界提供的标准化的开发模式,他们对于native开发提供了 ...
- C++复习2.软件开发知识小节
高质量的软件开发 1.满足正确性,健壮性,可靠性,性能,易用性,清晰性,安全性,兼容性,扩展性,可移植性等等来评价软件的质量. 2.没有错误的程序世间难求,任何一个程序,无论他多么的小,总是存在着错误 ...