历史上的今天
今天是:2024年09月22日(星期日)
2018年09月22日 | 【STM32电机矢量控制】记录11——DMA传输
2018-09-22 来源:eefocus
DMA传输:
原理:DMA 传输将数据从一个地址空间复制到另外一个地址空间。
DMA传输数据,但是不需要占用MCU,即在传输数据时,MCU可以做别的事,像多线程。数据传输从外设到存储器或者从存储器到存储器。DMA控制器包含了DMA1和DMA2,其中DMA1有7个通道,DMA2有5个通道,可以理解为传输数据的一种管道。要注意的是,DMA2只存在于大容量单片机中。
工作过程:
1.DMA请求
如果外设想通过DMA传输数据,必须先向DMA控制器发送DMA请求,DMA收到请求信号后,控制器会给外设一个应答信号,当外设应答且DMA控制器收到应答信号后,就会启动DMA传输,直到传输完毕。
DMA有DMA1和DMA2两个控制器,DMA1有两个控制器,DMA1有7个通道,DMA2有5个通道,不同DMA控制器的通道有不同的外设请求。
2、通道
DMA有12个独立可编程的通道,DMA1有7个通道,DMA2有5个通道,每个通道对应不同外设的DMA请求。虽然每个通道可以接收多个外设请求,但是同一时间只能接收一个,不能同时接收多个。
3、仲裁器
当同时有多个DMA请求时,就意味着有先后响应的问题,这个就由仲裁器管理。仲裁器管理DMA请求分为2个阶段:第一阶段属于软件阶段,可以在MDA_CCRx寄存器中设置,有 4 个等级:非常高、高、中和低四个优先级。第二阶段属于硬件阶段,如果两个或以上的DMA 通道请求设置的优先级一样,则他们优先级取决于通道编号,编号越低优先权越高,比如通道 0 高于通道 1。在大容量产品和互联型产品中,DMA1 控制器拥有高于 DMA2 控制器的优先级。
配置:
DMA_ InitTypeDef 初始化结构体
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_Init TypeDef;
DMA数据配置:
void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(DMA_CLOCK, ENABLE);// 开启 DMA 时钟
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)aSRC_Const_Buffer;// 源数据地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)aDST_Buffer;// 目标地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 方向:外设到存储器(这里是内部的 FLASH)
DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE; // 传输大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; // 外设(内部的 FLASH)地址递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; // 外设数据单位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; // 内存数据单位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ; // DMA 模式,一次或者循环模式
//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // 优先级:高
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; // 使能内存到内存的传输
DMA_Init(DMA_CHANNEL, &DMA_InitStructure); // 配置 DMA 通道
DMA_Cmd(DMA_CHANNEL,ENABLE); // 使能 DMA
}
调用 RCC_AHBPeriphClockCmd 函数开启 DMA时钟,使用 DMA控制器之前必须开启对应的时钟。 源地址和目标地址使用之前定义的数组首地址,传输的数据量为宏BUFFER_SIZE 决定,源和目标地址指针地址递增,使用一次传输模式不能循环传输,因为只有一个 DMA通道,优先级随便设置,最后调用 DMA_Init 函数完成 DMA 的初始化配置。
DMA_ClearFlag函数用于清除DMA标志位,代码用到传输完成标志位,使用之前先清除传输完成标志位以免产生不必要干扰。DMA_ClearFlag 函数需要 1 个形参,即事件标志位,可选有传输完成标志位、半传输标志位、FIFO 错误标志位、传输错误标志位等等,非常多,我们这里选择传输完成标志位,由宏DMA_FLAG_TC 定义。
DMA_Cmd 函数用于启动或者停止 DMA 数据传输,它接收两个参数,第一个是 DMA通道,另外一个是开启 ENABLE 或者停止 DISABLE。
主要完成任务:
1、FOC2.0程序进行细致的梳理;
2、起动的检测采样的细致过程有了更深的理解;
3、对ADC采样时的扇区判断,及其注入方式的程序书写进行更深的了解。
总的来说,FOC2.0 无霍尔控制方式的BLDC电机运行程序已经大致掌握,但应该还有些细节还未发掘。
接下来,用 有霍尔控制的电机运行程序 来再次深入学习 FOC2.0
史海拾趣
|
学习MISRA C之一:“安全第一”的C语言编程规范 C语言是开发嵌入式应用的主要工具,然而C语言并非是专门为嵌入式系统设计,相当多的嵌入式系统较一般计算机系统对软件安全性有更苛刻的要求。1998 年,MISRA指出,一些在C看来可以接受,却存在安全隐 ...… 查看全部问答> |
|
摘要:介绍了基于PDIUSBD12芯片的USB设备硬件组成,详细论述了USB枚举的具体过程和 基于PDIUSBD12的MCU固件编程思想,给出了部分单片机C程序代码,分析了制约实际数据传输速 率的原因,并提出了解决方法。… 查看全部问答> |
|
小弟课题实验,512K*8的内存,采用19地址线的SRAM,不想借用P1口,因为还有别的用处```关于页面管理的方法也不是很懂``` 初步采用8255.但是没有什么概念```8155可以么? 在线等待,谢谢 … 查看全部问答> |
|
【求助】为DELL PowerEdge 860添加硬盘,什么样的sata盘都可以吗? 被朋友托了下周去IDC为DELL PowerEdge 860的服务器加块硬盘,但之前我没有去过IDC. RT,想了解一下是不是什么样的sata盘都可以吗,需要单买盘架吗? 另外,去之前要注意些什么事情?… 查看全部问答> |
|
想做一个云台解码器,看到pelco-d的官方文档时,并没有发现有诸如“巡航”等功能的指令。那么这些功能要执行,究竟要接收到什么命令?还是这些指令的“解释权”由产品的厂家实现?望不吝赐教… 查看全部问答> |
|
以下用的是行列翻转法测矩阵键盘,下面只是一个子程序,但是不能实现功能。 我看别人写的程序都是用的行扫描法,理论上来说行列扫描也可以的。 请各位帮个忙查查错,我搞了几天了,实在弄不明白。 void keyscan(){ uchar h,l,temp; &n ...… 查看全部问答> |
|
又到了一年一度的电子设计大赛时刻,可是电源模块实在是最简单,又是最基础最重要的模块。 目的:希望用线性稳压芯片LM337.LM317搭建可调模块,它具有纹波小,效率低特点 问题:搭建的LM317电路接负载时,输入正常,电压幅度不变。搭建的LM337电 ...… 查看全部问答> |




