版权归如下公司,禁止非授权转载:

  • 北京西普阳光教育科技股份有限公司(https://www.simpleware.com.cn)
  • 维周机器人科技有限公司(http://www.vejoe.com)

文章目录

  • 【实验目的】
  • 【实验原理】
    • 一、DMA功能简介:
    • 二、DMA工作过程分析
    • 三、DMA库函数分析
    • 四、软件流程图
  • 【实验环境】
    • 硬件设备:
    • 操作系统:
    • 软件环境:
  • 【实验步骤】
    • 一、 配置工程环境
    • 二、 完成DMA配置,并开启时钟
    • 三、 编写main.c文件
    • 四、 编译并下载,观察实验现象
  • 【思考题】
    • 1、选择题
    • 2、简答题
  • 附录:DMA 库函数

【实验目的】

  • 掌握单片机DMA的工作原理,以及在STM32单片机上实现DMA传输的配置和流程;
  • 了解DMA传输方式相对与传统利用CPU传输方式的优势;
  • 完成以 DMA 的方式给数据赋值并显示在OLED显示屏上的实验。

【实验原理】

DMA (Direct Memory Access),直接存储器存取,是一种可以大大减轻CPU 工作量的数据存取方式,因而被广泛地使用。外设工作的时候,除了转移数据,实质上是不需要内核进行干预的,而如果数据转移的工作现在也交给了另一个外设,那么在该外设进行工作的时候,内核同时还可以进行其它操作。而STM32 的 DMA 模块正是以类似外设的形式,添加到 Cortex 内核之外,进行数据转移工作的。

一、DMA功能简介:

单片机的硬件系统,通常主要由 CPU(内核)、外设、内存(SRAM)、总线等结构组成,在系统工作中,数据经常要在各项设备之间进行转移。通常情况下,在转移数据的过程中会占用 CPU 十分宝贵的资源,所以我们希望 CPU 更多地被用在数据运算或响应中断之中,而数据转移的工作交由其它部件完成。DMA 恰恰为 CPU 分担了这部分数据转移的工作。因为 DMA 的存在, CPU 被解放出来,它可以在 DMA 转移数据的过程中同时进行数据运算,响应中断,大大提高了系统的运行效率。

在 STM32 中,DMA 的传输模式分为3种:

  1. 外设到存储器的传输。
  2. 存储器到存储器的传输。
  3. 存储器到外设的传输。

二、DMA工作过程分析

由 DMA 控制器挂载在AHB(高级高性能总线)上,与内核共享数据总线。DMA控制器在收到一个传输命令后,开始访问源地址寄存器中储存的地址,并加载该地址对应的数据,然后将数据存储到目标地址寄存器中指定的地址上去。在完成一次数据转移后,DMA内记录数据总数的寄存器执行一次减一操作,然后根据预先设定的传输模式决定是否对源/目标地址进行位移操作。例如,若是从外设(GPIO或其他有固定接口的设备)到存储器的传输,则在执行一次操作后,只需目标地址进行位移,源地址不变;而若是从存储器到存储器的传输,则需要同时将源地址和目标地址进行位移。

三、DMA库函数分析

DMA_InitTypeDef结构体参数的配置如下:

typedef struct
{uint32_t DMA_PeripheralBaseAddr;        // DMA 外设基地址
uint32_t DMA_MemoryBaseAddr;        //DMA 内存基地址
uint32_t DMA_DIR; //规定了外设是作为数据传输的目的地还是来源
uint32_t DMA_BufferSize;                // DMA 缓存的大小
uint32_t DMA_PeripheralInc;             // 外设地址寄存器递增与否
uint32_t DMA_MemoryInc;             // 内存地址寄存器递增与否       uint32_t DMA_PeripheralDataSize;       // 外设数据宽度
uint32_t DMA_MemoryDataSize;            // 内存数据宽度
uint32_t DMA_Mode;                  // 工作模式
uint32_t DMA_Priority;                  // DMA 软件优先级
uint32_t DMA_M2M;                   //非否内存到内存传输
}DMA_InitTypeDef;
  1. DMA_PeripheralBaseAddr:外设地址,设定 DMA_CPAR 寄存器的值;一般设置为外设的数据寄存器地址,如果是存储器到存储器模式则设置为其中一个存储器地址。
  2. DMA_Memory0BaseAddr:存储器地址,设定 DMA_CMAR 寄存器值;一般设置为我们自定义存储区的首地址。
  3. DMA_DIR:传输方向选择,可选外设到存储器、存储器到外设。它设定DMA_CCR 寄存器的 DIR[1:0]位的值。 这里并没有存储器到存储器的方向选择,当使用存储器到存储器时,只需要把其中一个存储器当作外设使用即可。
  1. DMA_BufferSize:设定待传输数据数目,初始化设定 DMA_CNDTR 寄存器的值。
  2. DMA_PeripheralInc:如果配置为 DMA_PeripheralInc_Enable,使能外设地址自动递增功能,它设定 DMA_CCR 寄存器的 PINC 位的值;一般外设都是只有一个数据寄存器,所以一般不会使能该位。
  3. DMA_MemoryInc:如果配置为 DMA_MemoryInc_Enable,使能存储器地址自动递增功能,它设定 DMA_CCR 寄存器的 MINC 位的值;我们自定义的存储区一般都是存放多个数据的,所以要使能存储器地址自动递增功能。
  4. DMA_PeripheralDataSize: 外设数据宽度,可选字节(8 位)、半字(16位)和字(32位),它设定 DMA_CCR 寄存器的 PSIZE[1:0]位的值。
  5. DMA_MemoryDataSize:存储器数据宽度,可选字节(8 位)、半字(16 位)和字(32位),它设定 DMA_CCR 寄存器的 MSIZE[1:0]位的值。 当外设和存储器之间传数据时,两边的数据宽度应该设置为一致大小。
  6. DMA_Mode: DMA 传输模式选择,可选一次传输或者循环传输,它设定DMA_CCR 寄存器的 CIRC 位的值。 例程我们的 ADC 采集是持续循环进行的,所以使用循环传输模式。
  7. DMA_Priority:软件设置通道的优先级,有 4 个可选优先级分别为非常高、高、中和低,它设定 DMA_CCR 寄存器的 PL[1:0]位的值。 DMA 通道优先级只有在多个 DMA 通道同时使用时才有意义,如果是单个通道,优先级可以随便设置。
  8. DMA_M2M:存储器到存储器模式 ,使用存储器到存储器时用到设定DMA_CCR 的位14 MEN2MEN 即可启动存储器到存储器模式。

四、软件流程图


图1 实验程序流程示意图

【实验环境】

硬件设备:

双轮自平衡机器人。如图2所示,平衡车所搭载的电路板主控芯片STM32内部有DMA,另外,电路上已经预留接口并安装了OLED显示屏。
ST-Link下载器(包含USB线与下载线)。如图3所示。

操作系统:

Windows7/8/10,32bit/64bit

图2 双轮自平衡机器人

图3 ST-Link下载器与下载线

软件环境:

Keil 5,串口助手软件
实验场地:

【实验步骤】

一、 配置工程环境

打开已经建立好的工程模板,在新建立的工程模板中已经添加五个文件夹,分别命名为USER、HARDWARE、SYSTEM、CORE、FWLIB文件夹,如图4所示。其中USER文件夹存放的是主函数,HARDWARE文件夹存放的是本实验对应的硬件设备函数,SYSTEM存放的是本课程所有实验通用的函数,CORE文件夹存放的是启动文件,FWLib文件夹存放的是底层驱动函数。在本实验中,oled模块的设备函数已经在oled.c的文件中给出。

图4 工程模板对应的文件夹
在HARDWARE文件夹下新建两个文件,分别为dma.c和dma.h。分别存放DMA控制函数与DMA头文件,如图5所示。

图5 在HARDWARE文件夹下建立dma.c与dma.h文件

二、 完成DMA配置,并开启时钟

2.1 打开程序中的dma.c文件,首先将dma.h文件包含进来。其次对DMA_Config函数进行编写,对DMA的地址通信模式等进行配置。

#include "dma.h"    //包含头文件
void DMA_Config(void)
{/*定义一个GPIO_ InitTypeDef类型的结构体*/
DMA_InitTypeDef DMA_InitStructure;
/*定义一个GPIO_ InitTypeDef类型的结构体*/
DMA_DeInit(DMA1_Channel1);//(1)使能DMA时钟
/*开启DMA时钟*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//(2)初始化DMA通道参数/*配置源地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&number_origin;
/*配置目标地址*/
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&number_target;
/*配置DMA的传输方向*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
/*配置缓冲区大小*/
DMA_InitStructure.DMA_BufferSize = 1;
/*配置在完成单次转移后是否对源地址进行位移*/
DMA_InitStructure.DMA_PeripheralInc= DMA_PeripheralInc_Disable;
/*配置在完成单次转移后是否对目标地址进行位移*/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
/*配置DMA每次访问的源地址长度*/
DMA_InitStructure.DMA_PeripheralDataSize =                                                             DMA_PeripheralDataSize_HalfWord;
/*配置DMA每次访问的目标地址长度*/
DMA_InitStructure.DMA_MemoryDataSize =                                                                     DMA_MemoryDataSize_HalfWord;
/*配置DMA的传输模式*/
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
/*配置DMA的优先级*/
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
/*配置DMA是否可以进行内存到内存的转移*/
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
/*将以上配置进行部署*/
DMA_Init(DMA1_Channel1, &DMA_InitStructure);//(3)使能DMA通道,启动传输
/*使能DMA传输*/
DMA_Cmd(DMA1_Channel1, ENABLE);
}

2.2 打开dma.h文件,添加DMA_Config 函数声明及外部变量。

#ifndef __DMA_H
#define __DMA_H
#include "sys.h"
extern uint16_t number_origin;    //引用已经定义的外部变量
extern uint16_t number_target;    //引用已经定义的外部变量
void DMA_Config(void);        //声明函数
#endif

三、 编写main.c文件

将工程编译需要用到的头文件包含进来。

#include "stm32f10x.h"    //包含系统寄存器定义声明的头文件
#include "sys.h"          //包含系统文件
#include "delay.h"        //包含延时函数头文件
#include "dma.h"          //包含DMA头文件

定义待转移的源地址及目标地址。

uint16_t number_origin=123;        //待转移的源地址
uint16_t number_target=0;          //待转移的目标地址

预定义oled屏幕显示函数。

void oled_show(void);      //oled屏幕显示函数

在主函数中调用延时函数与OLED初始化函数。

delay_init();      //调用延时函数
OLED_Init();    //调用OLED初始化函数

在主函数中,更新源地址内容并调用显示函数。

int main(void)
{
delay_init();         //延时函数初始化
OLED_Init();        //OLED屏幕显示初始化
DMA_Config();        //DMA初始化while(1)
{   DMA_Cmd(DMA1_Channel1, ENABLE);   //调用DMA传输 number_origin++;delay_ms(500);oled_show();
}
}

在主函数下面新建oled_show函数,并编写显示函数。

void oled_show(void)
{OLED_ShowString(0,50,"DMA_NUM_O");  //在指定位置显示文字信息
OLED_ShowNumber(85,50,number_origin,3,12); //在指定位置显示数字信息
OLED_ShowString(0,30,"DMA_NUM_T");
OLED_ShowNumber(85,30,number_target,3,12);
/*=============刷新=======================*/
OLED_Refresh_Gram();
}
}

四、 编译并下载,观察实验现象

本实验采用仿真器为STLink V2,将仿真器与小车相连,注意正负极不要接反,如图6所示。

图6 仿真器与下载线连接图
编译程序:点击如图7所示的编译按键。

图7 Keil编译环境下的编译按键
当编译完成后,如果没有问题,Build Output栏会出现无错误、无警告的提示,如图8所示。

图8 编译通过后Build Output栏提示信息
下载程序:点击如图所示的下载按键,程序就会下载到STM32的芯片中。下载按键如图9所示。

图9 Keil编译环境下的下载按键
观察实验现象,如图12所示。重新上电以后,OLED显示屏上显示的DMA_NUM_O后数字从初始设定的123开始,每隔0.5秒加一。DMA_NUM_T紧跟着DMA_NUM_O变化。

图10 平衡车上的小灯LED2

【思考题】

1、选择题

题目1: 下面哪条语句是设置串口数据寄存地址?(A)
A:DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004C04;
B:DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
C:DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
D:DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

题目2: 在DMA进行数据转移时,内核可以进行其它操作吗?(A)
A:可以
B:不可以

2、简答题

题目1:DMA的工作意义是什么?
在转移数据的过程中会占用 CPU 十分宝贵的资源,所以我们希望 CPU 更多地被用在数据运算或响应中断之中,而数据转移的工作交由其它部件完成。DMA 正为 CPU 分担了数据转移的工作。因为 DMA 的存在, CPU 被解放出来,它可以在 DMA 转移数据的过程中同时进行数据运算,响应中断,大大提高效率。

附录:DMA 库函数


嵌入式实验 之 DMA控制器实验相关推荐

  1. 计算机组成原理实验四 微程序控制器实验报告

    我班算是几乎最后一个做实验的班级了,报告参考了一些朋友提供的数据加上一些自己的主观拙见,本人水平有限加之制作仓促难免有错误,望大家批评指正. 4.1 微程序控制器实验 一.实验目的 (1) 掌握微程序 ...

  2. 微控制器实验计算机组成原理,组成原理实验四 微控制器实验

    实验四 微控制器实验 实验四微控制器实验 实验四 一.实验目的 1.掌握时序产生器的组成原理. 微控制器实验 2.掌握微程序控制器的组成原理. 3.掌握微程序的编制.写入,观察微程序的运行.二.实验设 ...

  3. 《计算机组成原理》实验报告——TEC-2实验系统——微程序控制器实验

    实验名称: TEC-2机微程序控制器实验 实验地点:10-413 一.实验目的 比较深入透彻地学懂计算机各种指令的执行过程,以及控制器的组成.设计的具体知识.理解动态微程序设计的概念. 二.实验原理 ...

  4. 计算机组成原理实验报告 实验三:控制器实验(源码全)

    实验类型 本实验为设计型实验. 实验目的 ① 具有多周期控制器的设计能力. ② 掌握用 Verilog HDL 实现有限状态机的常用方法. ③ 熟悉 Vivado 的设计流程,具备硬件的设计仿真和测试 ...

  5. 实验五 微控制器实验

    系列文章目录 目录 系列文章目录 一.实验目的 二.实验原理 三.微程序控制电路与微指令格式 四.实验接线 五.实验步骤 ①写微程序 ②读微程序 ③单步运行 ④连续运行 六.实验结论 一.实验目的 1 ...

  6. 实验3 微程序控制器实验

    一.实验类型 本实验为原理型+分析型 二.实验目的 (1)掌握微程序控制器的原理 (2)掌握TEC-8模型计算机中微程序控制器的实现方法,尤其是微地址转移逻辑的实现方法 (3)理解条件转移对计算机的重 ...

  7. 实验四 微程序控制器实验

    1.相关控制信号说明 ALU的选通信号ALU_BUS:PC的选通信号PC_B:RAM8的选通信号RAM_BUS:地址寄存器AR的锁存信号LDAR:存储器RAM8的写使能WR=1允许写,WR=0禁止写, ...

  8. 计算机组成实验微程序控制器实验,计算机组成原理实验报告3++微程序控制器实验.doc...

    文档介绍: 计算机组成原理实验报告3微程序控制器实验计算机组成原理实验报告实验三微程序控制器实验一.实验目的与要求:实验目的:1.理解时序产生器的原理,了解时钟和时序信号的波形;2.掌握微程序控制器的 ...

  9. 计算机微程序控制器实验报告,计算机组成原理实验报告三:微程序控制器实验.doc...

    计算机组成原理实验报告三:微程序控制器实验.doc 微程序控制器实验报告一. 实验目的1 掌握微程序控制器的功能.组成知识.(2)掌握为程序的编制.写入.观察微程序的运行二.实验设备PC机一台,TD- ...

  10. 【嵌入式12】DMA通信原理及编程实验,DMA方式向上位机连续发送数据

    本文介绍DMS通信原理,STM32采用串口DMA方式,用115200bps或更高速率向上位机连续发送数据. 一.DMA介绍 什么是DMA? DMA介绍 DMA传输方式 DMA传输参数 DMA数据传输的 ...

最新文章

  1. 一般将来时语法课教案_「英语语法」一般过去时用法技巧全解
  2. 在 Chrome 开发者工具中调试 node.js
  3. Ubuntu下载连接(阿里云镜像)
  4. 一些没啥用的大数据组件以及理由(持续更新中)+2020的Gartner曲线
  5. 机器学习(一)——线性回归、分类与逻辑回归
  6. 更新pcb封装导入_PCB设计│网表导入的雷区,你还在踩?
  7. 使用ueditor实现多图片上传案例——Service层(IShoppingService)
  8. 调用支付jsapi缺少参数package_iOS微信支付(Swift)
  9. 【转】HTTP协议中PUT和POST使用区别
  10. java.sql.SQLException: The server time zone value ‘???ú±ê×??±??‘ is unrecognized or represents more
  11. Spring第三篇【Core模块之对象依赖】
  12. 基于PyQt的扫雷游戏实现_下篇
  13. 从 Microsoft Dynamics CRM 4.0 server迁移到 Microsoft Dynamics CRM 2013 Server
  14. 可变剪切的意义和重要性
  15. 华硕主板开机提示按F1怎么办?华硕主板开机提示按F1的解决方法
  16. Roson的Qt之旅#71 Qt绘制星空和旋转的星球
  17. 3.1 TMO MATLAB 框架(Advanced High Dynamic Range Imaging )
  18. 机器学习可行性与VC dimension
  19. WPF软件导致Win10系统的平板电脑小键盘自动隐藏问题
  20. 求助大神 VMware 卸载

热门文章

  1. 斯坦福大学公开课:量子力学_TimelineMax:了解力学
  2. 服务器显示无vga电缆怎么回事,无vga电缆是什么意思
  3. 百家姓中国心头像大全
  4. 使用EasyExcel的模板导出复杂表头的Excel- 先单组数据填充,再多组数据填充
  5. JavaSE Map集合 HashMap和Hashtable的区别 Collections(集合工具类) 集合练习 模拟斗地主(洗牌,发牌,看牌)
  6. NVIDIA Jetson TX2简介
  7. 抖音账号都是如何出售的
  8. [渝粤教育] 哈尔滨工业大学 大学计算机—计算思维导论 参考 资料
  9. android wine教程_如何在 Android 上借助 Wine 来运行 Apps
  10. 计算机配置里面没有网络选项,win7网络共享中心里面的更改适配器设置里面没有无线网络连接...-win7适配器没有无线网络连接,win7网络适配器未...