【北京迅为】《STM32MP157开发板使用手册》- 第三十三章Cortex-M4 DMA实验

news2024/9/23 11:13:34

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7+单核cortex-M4异构处理器,既可用Linux、又可以用于STM32单片机开发。开发板采用核心板+底板结构,主频650M、1G内存、8G存储,核心板采用工业级板对板连接器,高可靠,牢固耐用,可满足高速信号环境下使用。共240PIN,CPU功能全部引出:底板扩展接口丰富底板板载4G接口(选配)、千兆以太网、WIFI蓝牙模块HDMI、CAN、RS485、LVDS接口、温湿度传感器(选配)光环境传感器、六轴传感器、2路USB OTG、3路串口,CAMERA接口、ADC电位器、SPDIF、SDIO接口等


第三十三章Cortex-M4 DMA实验

本章节最终所完成的实验例程存放路径为“iTOP-STM32MP157开发板网盘资料汇总\06_Cortex-M4实验例程\09_DMA.zip”。

33.1 DMA 简介 

DMA,全称Direct Memory Access,即直接存储器访问。DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。

我们知道CPU有转移数据、计算、控制程序转移等很多功能,系统运作的核心就是CPU,CPU无时不刻的在处理着大量的事务,但有些事情却没有那么重要,比方说数据的复制和存储数据,如果我们把这部分的CPU资源拿出来,让CPU去处理其他的复杂计算事务,是不是能够更好的利用CPU的资源呢?

因此转移数据(尤其是转移大量数据)是可以不需要CPU参与。比如希望外设A的数据拷贝到外设B,只要给两种外设提供一条数据通路,直接让数据由A拷贝到B 不经过CPU的处理,

 

DMA就是基于以上设想设计的,它的作用就是解决大量数据转移过度消耗CPU资源的问题。有了DMA使CPU更专注于更加实用的操作–计算、控制等。

DMA定义:

DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。

DMA传输方式

DMA的作用就是实现数据的直接传输,而去掉了传统数据传输需要CPU寄存器参与的环节,主要涉及四种情况的数据传输,但本质上是一样的,都是从内存的某一区域传输到内存的另一区域(外设的数据寄存器本质上就是内存的一个存储单元)。四种情况的数据传输如下:

1)外设到内存

2)内存到外设

3)内存到内存

4)外设到外设

DMA传输参数

我们知道,数据传输,首先需要的是1数据的源地址、2 数据传输位置的目标地址、3 传递数据多少的数据传输量、4进行多少次传输的传输模式 DMA所需要的核心参数,便是这四个。

当用户将参数设置好,主要涉及源地址、目标地址、传输数据量这三个,DMA控制器就会启动数据传输,当剩余传输数据量为0时达到传输终点,结束DMA传输,当然,DMA 还有循环传输模式 当到达传输终点时会重新启动DMA传输。也就是说只要剩余传输数据量不是0,而且DMA是启动状态,那么就会发生数据传输。 

33.2 STM32MP157 DMA 资源介绍

STM32MP157内部有3个DMA控制器:

1个高速主DMA(MDMA)和2个双口DMA(DMA1和 DMA2)。M4 和 A7 可以共享 MDMA,而 DMA1 和 DMA2 只能由 A7 或者 M4 中某一个使用。 由于我们本章节实验是通过M4核心来实现的,所以我们在这里只是关注DMA1和DMA2。STM32MP157 DMA对应的功能框图如下

Programming port 代表 DMA 控制器的从机编程接口,通过该接口可以对 DMA 的相关控制寄存器进行设置,从而配置 DMA,实现不同的功能。

Peripheral port 和Memory port 分别代表 DMA 控制器的外设接DMA 控制器的存储器接口用于访问相关外设用于访问外部存储器

DMA控制器的FIFO区,可以实现存储器接口到外设接口之间的数据长度非对齐传输。每个数据流(总共 8 个数据流)都有一个独立的 FIFO(先进先出存储器缓冲区)FIFO 用于临时存放要传输的数据,可通过 DMA_SxFCR 寄存器来控制控制 FIFO 的阈值,如果数据存储量达到阈值时,FIFO 中的数据将传输到目标中。

Arbitrer代表DMA 控制器的仲裁器,用于仲裁数据流 0~7 的请求优先级,保证数据有序传输。

左侧的From DMAMUX输入为 DMA 控制器数据流 0~7 的通道请求信号,每个数据流有多达 116 个通道请求可以选择。

DMA 请求映射表,如下图所示:

 

33.3实验目的

1)学习使用STM32CubeIED配置DMA

2)STM32CubeIED的熟练

实验要求:UART4 以 DMA 方式发送数据,打开串口调试助手,可以收到 DMA 发送的内容。

33.4实验步骤

33.4.1建立DMA工程

首先我们打开STM32CubeIDE软件,进入软件界面之后,我们点击File属性,选择NEW下的STM32 Project的选项,如下图所示:

 

然后我们会进入下图所示界面:在Part Number选择框输入STM32MP157A,然后在右边的选择界面选择STM32MP157AAA,然后点击Next选项

在Project Name框中输入工程名字DMA,然后点击Finish选项即可,如下图所示: 

等待工程创建完毕,会询问我们是否要安装OpenSTLinux ,由于我们是在windows环境下,所以我们不需要安装,点击NO即可 

至此我们的工程创建完毕,进入工程界面如下图所示界面: 

33.4.1.1串口引脚的功能配置

首先我们在下面的搜索框之中输入我们要配置的引脚,我们在这里以PB2为例进行搜索,输入名称之后,对应的引脚在工程中会闪烁,如下图所示:

然后我们使用鼠标左键点击对应的引脚会弹出PB2的复用功能选择,我们在这里选择复用为UART4_RX功能,如下图所示:    

用同样的方法对PG11进行搜索,然后我们使用鼠标左键点击对应的引脚会弹出PG11的复用功能选择,我们在这里选择复用为UART4_TX功能,如下图所示: 

配置完成之后打开左侧菜单的 System CoreàGPIO 进入 GPIO 模式配置界面:如下图所示: 

 

点击对应的引脚配置之后会弹出右下方的管脚配置界面,如上图所示:

在下方会列出要配置选项的具体说明和我们要进行的配置。

选项 GPIO Pull-up/Pull-down 用来设置 IO 口是上拉/下拉/没有上下拉。本实验我们设置为上拉(Pull-up)。

选项 GPIO mode用来设置 GPIO 口的模式,这里默认为alternate function,也就是复用功能。

选项 User Label 是用来设置初始化的 IO 口 Pin 值为我们自定义的宏,这里我们填写为 UART_RX。按照如上要求设置后的界面如下(由于PG11的配置相同,只是最后的Label值不同,也在下方列了出来):

而PG11和PB2的设置相似,只是多了出了一个选项:选项 Mzximum ouput speed 用来设置 IO 口输出速度为低速(Low)/中速(Medium)/高速 (Hign)/快速(Very High)。我们设置为高速Very High 。

设置完成之后在左侧菜单找到Connectivity下的UART4,打开之后首先选中Cortex-M4,然后配置Mode为Asynchronous(也就是异步通信模式),配置完成之后如下如图所示: 

然后进入NVIC Settings功能设置界面,使能UART4 global interrupt,配置完成如下图所示: 

33.4.1.2 DMA配置

配置完成之后继续打开左侧菜单的 System Core,选择DMA,进入模式配置界面:如下图所示:我们配置 M4 内核使用 DMA2(默认配置就已经配置了),从 DMA 配置处可以看到,而 DMA1A7 内核(Cortex-A7 non secure)使用的,DMADMA2 可以单独给 M4 或者 A7 内核使用,配置完成如下

在相同界面下,来到Configuration配置界面,选择DMA2,点击下方的add按钮,如下图所示:  

将串口的收发引脚加入DMA请求,数据流(Stream)和传输方向(Direction)不需要去进行修改,软件已经自动为我们配置好,而Priority需要设置为中速(Medium),配置完成如下图所示: 

33.4.1.3时钟配置

NVIC配置完成之后在左侧菜单找到System Core下的RCC,选择打开 HSE(也就是使用外部高速时钟),并选择Crystal/Ceramic Resonator 晶体/陶瓷谐振器选项。

 

 选择HSE(高速外部时钟)之后,打开时钟设置界面,首先将PLL3 Source Mux 设置为HSE,然后设置MCU Clock Mux为PLL3P,设置完成之后在对应的功能框之中手动输入 209 以后按下回车键,STM32CubeMX 插件会自动计算分频和倍频系数,然后在APB1DIV、APB2DIV、APB3DIV处输入 2,因为 APB1、APB2、APB3时钟最大值只能为 104.5MHz,所以我们要手动设置分频值,设置完成之后如下图所示:

至此我们的基本设置就完成了,最后需要在Project Manage下的Code Generator选项下勾选 Generate peripheral initialization as a pair of ".c/.h' files per peripheral 选项,这样可以独立生成对应外设的初始化.h 和.c 文件(方便配置的查看),如下图所示: 

33.4.2工程的生成与完善

在上述的步骤完成之后,按下键盘的“Ctrl+S”组合键保存保存 UART.ioc 文件,系统开始生成初始化代码,工程生成之后如下图所示:

 

然后我们进行工程的完善,以及添加对应的逻辑代码。

33.4.2.1 uart.h文件的完善

首先打开uart.h文件,文件存放位置如下图所示:

进入uart.h文件后在/* USER CODE BEGIN Private defines */和/* USER CODE END Private defines */之间添加定义 

#define rx_max 1024
extern uint8_t rx_flag;
extern uint16_t rx_len;
extern uint8_t rx_buf[rx_max];

其中rx_max代表接收数据量的最大值,rx_flag代表接收完成的标志,rx_len代表接收的数据长度,rx_buf代表接收数据缓冲区。添加完成如下图所示:

33.4.2.2 uart.c文件的完善

首先打开uart.c文件,文件存放位置如下图所示:

进入uart.c文件后在/* USER CODE BEGIN 0 */和/* USER CODE END 0 */之间添加内容如下:

uint8_t rx_flag = 0;

uint16_t rx_len = 0;

uint8_t rx_buf[rx_max] = {0};

添加完成之后如下图所示:

 

33.4.2.3 stm32mp1xx_it.c文件的完善

首先打开 stm32mp1xx_it.c文件,文件存放位置如下图所示:

进入 stm32mp1xx_it.c文件后在/* USER CODE BEGIN Includes *//* USER CODE END Includes  */之间添加内容如下:

#include "usart.h"

添加完成如下图所示:

 

然后在 /*USER CODE BEGIN UART4_IRQn 0*/和/* USER CODE END UART4_IRQn 0*/ 之间添加内容如下:

uint32_t temp;

 if((__HAL_UART_GET_FLAG(&huart4,UART_FLAG_IDLE) != RESET))

 {

 __HAL_UART_CLEAR_IDLEFLAG(&huart4);

  HAL_UART_DMAStop(&huart4);

  temp = huart4.hdmarx->Instance->NDTR;

  rx_len = rx_max - temp;

  rx_flag=1;

  HAL_UART_Receive_DMA(&huart4,rx_buf,rx_max);

 }

添加完成如下图所示: 

 打开main.c文件,在 /* USER CODE BEGIN 2 */和/* USER CODE END 2 */之间添加以下内容:

  HAL_UART_Receive_DMA(&huart4, rx_buf, rx_max);

  __HAL_UART_ENABLE_IT(&huart4,UART_IT_IDLE);

使能DMA串口接收并使能串口中断,添加完成如下图所示:

在/* USER CODE BEGIN 4 */和/* USER CODE END 4 */之间添加以下内容:

	  if(rx_flag) 
{
		  rx_flag=0; 
		  HAL_UART_Transmit_DMA(&huart4, rx_buf, rx_len); 
}

添加部分的内容,表示串口接收数据完成之后,再将接收到的数据发送出去,以实现串口数据的回显,方便观察。

33.4.4工程的编译

在完成以上步骤之后我们点击工具栏的小锤子进行编译,编译图标如下图所示:

 

编译完成会在下方的终端中显示打印信息,如下图所示: 

如果报错,需要自己根据错误的提示信息来进行问题的寻找和改正。

本例程实现的最终功能是,发送一个字符串,会将发送的字符串打印出来,如下图所示:

33.4.5工程的调试

由于STM32MP157的裸机部分和一般的单片机有些区别,他没有内部的存储,所以只能在程序编译成功之后,通过debug的方式来进行调试(将程序放在内存之中),调试过程如下:

首先,点击菜单栏中的小甲虫Debug调试按钮,弹出以下界面,

 在弹出来的界面,按步骤,选择响应的属性(该步骤为Jlink的步骤,如果是STLink,调试探头选择对应的即可)。如下图所示:

选择完成之后,点击右下角的Debug按钮,点击之后,会进行再一次的编译,编译完成之后会弹出如下内容(作者用的是J-LinK),这里弹出的是J-link关于设备的选择,不同调试器的弹窗可能会不同 

在弹出来的界面中,选择Accept接受,会弹出以下内容,继续点击下方的OK。 

之后会来到设备选择界面,我们选择Cortex-M4,如下图所示:

选择Cortex-M4之后,点击右下角的OK,会弹出以下界面,选择右下角Switch. 

然后会弹出一个新的页面,选择菜单栏的 resume按钮开始调试。 

连接好串口之后,打开串口调试助手,当我们发送一串字符时,开发板会返还我们相同的字符。

如果想关闭调试,则点击菜单栏的终止按钮即可。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2144120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《锐捷AP 胖模式配置示例》

目录 WEB配置方式: 1. 登录 AP 管理界面 2. 配置无线服务 3. 配置射频参数 4. 配置 VLAN (如果需要) 5. 配置 IP 地址 6. 其他高级设置(根据需求) 命令行配置: 1. 进入特权模式 2. 进入全局配置模式 3. 配置管理 IP 地址 4. 创建无线 SSID 5. 配置 SSID 加密…

Selenium打开浏览器后闪退问题解决

笔者这两天在做一个自动化方案,用来优化数据统计。其中一部分数据需要通过云上堡垒机跳转访问,而这个堡垒机在笔者日常使用的火狐浏览器上运行不是很正常(表现在有些复制粘贴按钮显示不太灵敏)。 但在Edge浏览器上基本正常&#…

工行软件开发中心积极推进低代码平台建设,助力金融业务快速研发

工行软件开发中心融合现有研发体系,打造全链路可视化研发。平台整体架构建立于行内新一代前后端分离研发体系之上,引入可视化技术,构建业务研发资产,承接现有服务体系,基于数据模型驱动技术及代码扩展能力,快速实现应用开发,并整合行内研发支撑体系,实现应用的快速构建…

python定时发送邮件的功能如何实现自动化?

Python定时发送邮件教程?如何用Python发送电子邮件? Python定时发送邮件不仅能够帮助我们自动处理日常的邮件发送任务,还能在特定时间点触发邮件发送,确保信息的及时传达。AokSend将详细探讨如何利用Python实现定时发送邮件的自动…

开放式耳机好用吗?哪个开放式耳机好用?

现在市面上的开放式耳机真的越来越火了,所以很多小伙伴也会来问我,有哪些品牌值得入手,开放式耳机到底好不好用的这个问题,作为专业的开放式耳机测评博主对于这个问题当然是信手拈来啦,这篇文章就来告诉大家如何才能选…

算法基础-扩展欧几里得算法

扩展欧几里得 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);int n in.nextInt();while (n-- > 0) {int a in.nextInt();int b in.nextInt();int[] m exgcd(a, b);System.out.println(m[0] " " m[1]);}}…

【ollama 下载不下来的问题解决】

国内从官网下载ollama经常遇到下载不下来,或者卡住的问题,今天给大家分享解决这个问题的方法。 官网 官网地址:https://ollama.com/download 但是官网地址,就一直卡住,一直下载不下来,所以选用下面的方法…

【精选书籍】ChatGLM3大模型本地化部署、应用开发与微调的全面解析

前言 大模型领域既是繁星点点的未知宇宙,也是蕴含无数可能的广阔天地,正是这一独特的魅力,令无数的探索者为之倾倒,为之奋斗。随着大模型应用逐渐走入人们的日常生活,支撑它的深度学习技术也开始登上更为广阔和深远的…

【C++】日期类基础题

个人主页:CSDN_小八哥向前冲~ 所属专栏:C入门 一些C基础题目,帮你巩固一下! 目录 关于内存问题 栈和堆基础问题 计算日期到天数的转换 日期差值 日期累加 打印日期 关于内存问题 答案:D B 第一题&#xff…

java重点学习-JVM类加载器+垃圾回收

12.7类加载器 JVM只会运行二进制文件,类加载器的作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来。 类加载器有哪些 启动类加载器(BootStrap ClassLoader):加载JAVA HOME/jre/lib目录下的库扩展类加载器(ExtClassLoader):主要加载JAVA HOME…

Tensorflow—第五讲卷积神经网络

本讲概述 卷积实际上就是特征提取。本讲我们先了解学习卷积神经网络基础知识,再一步步地学习搭建卷积神经网络,最后会运用卷积神经网络对cifar10 数据集分类。在本讲的最后附上几个经典卷积神经网络:LeNet、AlexNet、VGGNet、InceptionNet和…

开发小程序

由于之前购入的阿里云ECS放着落灰,碰巧又看到个有趣的项目,于是就做了个生成头像的小程序…由于第一次完整发布小程序,记录一下遇到的问题 小程序名称:靓仔创意头像 😂 关于小程序 接口请求,在开发过程中…

少儿编程小游戏 | Scratch 射击游戏《开枪!》

在线玩:Scratch射击游戏 : “开枪!” 免费下载-小虎鲸Scratch资源站 随着科技的飞速发展,编程已经成为孩子们未来必备的技能之一。而Scratch作为一款专为少儿设计的编程工具,通过可视化的编程方式,让孩子们在玩游戏的过…

JAVA-集合相关

HashMap如何解决哈希冲突的? 计算hash值,基于hashCode计算冲突之后,先是使用链式寻址法当链表长度大于8,且hash表的容量大于60的时候,再添加元素则转化成红黑树 为什么计算hash值是,是将hash地址的值右移1…

代码随想录训练营 Day62打卡 图论part11 Floyd 算法 A * 算法

代码随想录训练营 Day62打卡 图论part11 Floyd 算法 例题:卡码97. 小明逛公园 题目描述 小明喜欢去公园散步,公园内布置了许多的景点,相互之间通过小路连接,小明希望在观看景点的同时,能够节省体力,走最短…

C++速通LeetCode中等第3题-字母异位词分组

双指针法:两个指针分别指向左右边界,记录最大面积,由于面积由短板决定,两个指针中较短的短指针向内移动一格,再次记录最大面积, 直到两指针相遇,得出答案。 class Solution { public:int maxAr…

PyQt / PySide + Pywin32 + ctypes 自定义标题栏窗口 + 完全还原 Windows 原生窗口边框特效项目

项目地址: GitHub - github201014/PyQt-NativeWindow: A class of window include nativeEvent, use PySide or PyQt and Pywin32 and ctypesA class of window include nativeEvent, use PySide or PyQt and Pywin32 and ctypes - github201014/PyQt-NativeWindow…

切换淘宝最新npm镜像源

文章目录 一、前言二、切换淘宝最新npm镜像源2.1 查询最新镜像源2.2 两种方式切换npm镜像源2.2.1 通过npm配置2.2.1 通过cnpm配置 三、总结 一、前言 NPM(Node Package Manager),是NodeJs的模块依赖管理工具,用于nodejs模块的安装…

java多线程模拟多个售票员从同一个票池售票

程序功能 这段代码模拟了多个售票员从一个有限的票池中售票的过程。主要功能如下: 票池共有50张票,多个售票员(线程)并发进行售票。 使用同步机制确保线程安全,避免多个售票员同时出售同一张票。 每个售票员不断检查票…

5.内容创作的未来:ChatGPT如何辅助写作(5/10)

引言 在信息爆炸的时代,内容创作已成为连接品牌与受众、传递信息与知识、以及塑造文化与观念的重要手段。随着数字媒体的兴起,内容创作的需求日益增长,对创作者的写作速度和质量提出了更高的要求。人工智能(AI)技术的…