×
单片机 > 单片机程序设计 > 详情

【STM32电机矢量控制】记录11——DMA传输

发布时间:2020-05-23 发布时间:
|

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


关键字:STM32  电机  矢量控制  DMA传输 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机制作超级流水灯