STM32直接存储器存取DMA

2024-04-20 05:28

本文主要是介绍STM32直接存储器存取DMA,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前提知识:

1、STM32F103内部存储器结构以及映射

        STM32F103的程序存储器、数据存储器、寄存器和IO端口被组织在同一个4GB的线性地址空间内。数据字节以小端模式存放在存储器中。即低地址中存放的是字数据的低字节,高地址中存放的是字数据的高字节

         可访问 的存储器空间被分成 8个主要块 每个块为512MB 。 其他所有没有分配给片上存储器和外设的存储器空间都是保留的地址空间
第一块(0x0000 0000 ~ 0x1FFF FFFF,512MB):
启动空间(0x0000 0000 ~ 0x0800 0000,128MB): 代码区始终从0x0000 0000开始,通过ICode和DCode总线访问。
启动之后, CPU从地址0x0000 0000获取堆栈顶SP的地址,并从存储器的0x0000 0004指示的地址(程序计数器指针PC)执行代码
        之所以产生上述步骤,则因为不同厂商可能会把0x0000 0000以及0x0000 0004地址映射到其他地址。因此,根据映射到不同地址分为不同的启动方式(由BOOT引脚决定)
        在系统复位后,SYSCLK 的第4个上升沿,BOOT 引脚的值将被锁存。用户可以通过设置 BOOT1 和BOOT0 引脚的状态,来选择在复位后的启动模式
启动模式1:从Flash开始启动,正常的下载启动程序
启动模式2:从系统存储器( 存储BOOTLoader程序,用于串口下载,将下载好的程序刷新到Flash位置)开始启动,由于系统存储器存储串口下载程序,通过这种启动方式可以通过串口将程序下载到Flash。 串口程序下载完成后,需要设置为从Flash启动,这样复位后才能正常运行程序(只能通过USART1下载)
启动模式3:SRAM用来 存储程序运行过程中的临时变量,不能存储程序,所以该方式只用于调试程序
启动文件的执行流程:
复位中断函数:主要用来执行SystemInit()和main()
Flash(0x0800 0000 ~ 0x0801 FFFF,128KB): 存储编译后的程序代码
系统存储区 (0x1FFF F000 ~ 0x1FFF F800,8KB):存储用于串口下载程序
        系统存储器, 存储BOOTLoader程序,用于串口下载,将下载好的程序刷新到Flash位置。当从该位置启动, 其实是 执行串口下载程序,BOOTLoder会将下载的程序存放进Flash 。串口程序下载完成后,需要设置为 从Flash启动,这样复位后才能正常运行程序
选项字节 (0x1FFF F800 ~ 0x1FFF F80F,16B):存储一些独立于程序代码的配置参数
        读保护字节、看门狗、停机或待机是否产生复位、用户字节数据(0x1FFF F804 ~ 0x1FFF F806 )(这两字节可供用户独立使用)、写保护字节(Flash的每几页)
第二块(0x2000 0000 ~ 0x3FFF FFFF,512MB):
       SRAM(0x2000 0000 ~ 0x2000 4FFF,20KB): 存储程序运行过程中的临时变量
作用:
(1)选项字节中的数据不随程序的更新而改变,可以存放一些
(2)用上位机可以很方便修改,可以用在产品中可供用户配置的参数
第三块(0x4000 0000 ~ 0x5FFF FFFF,512MB):
外设(0x4000 0000 ~ 0x4002 3FFF):外设寄存器空间地址
第八块(0xE000 0000 ~ 0xFFFF FFFF,512MB):
Cortex_M3内核外设(0xE000 0000 ~ 0xE010 0000)
其他存储器区域均保留

一、DMA简介

DMA( Direct Memory Access直接存储器存取/直接存储器访问, 可以提供外设与外设之间、外设与存储器之间、存储器和存储器之间的高速数据传输,无须CPU 干预,节省了 CPU 的资源
        在DMA传输前,CPU把总线控制权交给DMA控制器,在结束DMA传输后,DMA控制器立即把总线控制权交回CPU
DMA过程:DMA请求、DMA响应、DMA传输、DMA结束
12个独立可配置的通道: DMA1 7 个通道), DMA2 5 个通道)
每个通道都支持软件触发和特定的硬件触发
STM32F103C8T6 DMA 资源: DMA17个通道)

二、DMA结构

(1)每个通道都直接连接 专用的硬件DMA请求,每个通道都 同样支持软件触发。这些功能通过
软件来配置。
(2)在同一个 DMA 模块上,多个请求间的 优先权可以通过软件编程 设置 ( 共有四级:很高、高、
中等和低 ) 优先权相等时由硬件决定 ( 请求 0 优先于请求 1 ,依此类推 )
(3)独立数据源和目标数据区的传输宽度 ( 字节、半字、全字 ) ,模拟打包和拆包的过程。源和目
标地址必须按数据传输宽度对齐。
(4)循环模式/非循环模式
(5)每个通道都有 3 个事件标志 (DMA 半传输、 DMA 传输完成和 DMA 传输出错 ) ,这 3 个事件标志
逻辑或成为一个单独的中断请求。
(6)可编程的数据传输数目: 最大为65535
        DMA是AHB总线上的外设,有两个AHB端口:一个是从端口,用于配置DMA;另一个是主端口,用于设备间的数据传输。所以,DMA既是总线矩阵的主动单元,可以读写各种存储器;又是AHB总线上的被动单元,可被CPU进行配置
        STM32的Cortex-M3内核和DMA控制器通过总线矩阵连接到Flash控制总线、SRAM总线和AHB总线,进而通过AHB总线连接到AHB总线服务外设

DMA的工作流程:

(1)DMA传送
当外设发送DMA请求,DMA控制器根据通道的优先权来处理请求。当DMA控制器开始访问外设时,DMA控制器首先向外设发送一个应答信号,外设得到应答信号后立即撤销请求,DMA控制器同时撤销应答信号
(2)仲裁器
根据优先级管理各通道的请求以及启动外设/存储器访问的顺序
软件:最高、高、中等、低
硬件:如果两个通道请求的优先级相同,则 低编号的通道有高优先级
(3)DMA通道
每个通道可以实现固定地址的外设寄存器和存储器地址之间的DMA传输。DMA传输的数据量是可编程的,最大达到65535,在 每次传输后递减
(4)地址自增
外设和存储器的指针可以设置为在每次传输结束后自增
(5)中断
        3个事件标志 (DMA 半传输、 DMA 传输完成和 DMA 传输出错 ) ,这 3 个事件标志逻辑或成为一个单独的中断请求
(6)循环模式
数据传输数目变为0时,将自动恢复为设置的初始值,DMA操作继续。循环模式用于处理循环缓冲区和连续的数据传输,例如,ADC的扫描模式
(7)存储器到存储器模式: 不可以与循环模式同时使用
(8)DMA请求映射
从外设产生的7个请求,通过逻辑或输入到DMA控制器,这意味着 某一时刻只有一个DMA请求有效(分时复用)
MEM2MEN(Memory to Memory,存储器到存储器),当此位为1时,由软件触发,不可以和循环模式同时使用
可编程的数据传输宽度、对齐方式和数据大小端
         当源数据宽度 = 目标数据宽度,正常传输
        当源数据宽度 < 目标数据宽度,高位补0
        当源数据宽度 > 目标数据宽度,高位舍弃,只保留低位

三、DMA相关库函数

(1)初始化:DMA_Init()

(2)设置计数器:DMA_SetCurrDataCounter()
可以单独设置DMA_BufferSize的值,即传输计数器的值

四、DMA配置

(1)开启DMA时钟(AHB总线)
(2)配置DMA,完成初始化
	DMA_InitTypeDef DMA_InitStruct;DMA_InitStruct.DMA_PeripheralBaseAddr = source;  //外设基地址DMA_InitStruct.DMA_MemoryBaseAddr = destination;	 //内存基地址DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Enable;  //外设基地址是否递增:DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;	//内存基地址是否递增:DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;	//外设数据宽度:一字节DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;	//内存数据宽度:一字节DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;	//外设作为数据来源or数据目的地:数据来源DMA_InitStruct.DMA_BufferSize = number;  //DMA缓存数据的大小:传输计数器的大小DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;	 //工作模式  是否循环:不循环DMA_InitStruct.DMA_Priority = DMA_Priority_High;	  //优先级:高优先级DMA_InitStruct.DMA_M2M = DMA_M2M_Enable;  //内存到内存:使能DMA_Init(DMA1_Channel1, &DMA_InitStruct);
(3)使能DMA
DMA工作的三个条件:
DMA使能,打开开关
②传输计数器必须 大于0
必须有触发源
注:在写传输计数器的值时,必须 关闭DMA

这篇关于STM32直接存储器存取DMA的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/919374

相关文章

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

STM32 ADC+DMA导致写FLASH失败

最近用STM32G070系列的ADC+DMA采样时,遇到了一些小坑记录一下; 一、ADC+DMA采样时进入死循环; 解决方法:ADC-dma死循环问题_stm32 adc dma死机-CSDN博客 将ADC的DMA中断调整为最高,且增大ADCHAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_Buffer_Size); 的ADC_Bu

[项目][CMP][直接向堆申请页为单位的大块内存]详细讲解

目录 1.系统调用 1.系统调用 Windows和Linux下如何直接向堆申请页为单位的大块内存: VirtualAllocbrk和mmap // 直接去堆上按页申请空间static inline void *SystemAlloc(size_t kpage){#ifdef _WIN32void *ptr = VirtualAlloc(0, kpage << 13,

基于stm32的河流检测系统-单片机毕业设计

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品

STM32的使用方法一

注:我采用的是STM32F103RC芯片、相应的电路图和STM32CubeIDE软件这是在STM32CubeIDE软件定义芯片后,所给的必要的代码逻辑,加上了注释 #include "main.h"/* Private variables ---------------------------------------------------------*//* Private function

STM32 HAL CAN通讯 实操

1、简介 相比于串口通讯,对于刚接触CAN通讯的小白来说,CAN通讯相对复杂,看各种视频、帖子理论,总是一知半解。本次通过傻瓜式操作,先实现CAN通讯的交互,以提高小白的信心,也便于自己复习观看。本次以STM32CubeMX进行初始化配置,通过Keil 5软件进行软件设计,通过CAN盒实现进行数据的交互。该流程实际以STM32F0、F1、F3、F4、F7实测好用(理论上都适用),这三种型号单片机