DMA的补充笔记

2023-05-16

DMA有两个总线:

1、DMA存储器总线:DMA通过该总线来执行存储器数据的传入和传出。

2、DMA外设总线:DMA通过该总线访问AHB外设(AHB主要是针对高效率、高频宽以及快速系统模块所设计的,主要有Flash 存储器、复位和时钟控制、CRC、以太网、SDIO)或者执行存储器件的数据传输。

FIFO(4级32位存储器缓冲区):源数据传输到目标地址前的临时存储区。当设置为FIFO模式的时候,可以通过软件设置阈值,达到阈值即传输;也可以设置直接模式,立即启动对存储器的传输。 

STM32F1的DMA外设请求映像图如图所示,DMA1有7个通道,DMA2有5个通道,这些请求通过逻辑或输入到DMA1控制器,这意味着同时只能有一个请求有效。

 

 ----------------------------------------------------------------------------------

DMAMUX(DMA请求复用器)

首先介绍关于DMA控制器前一级的多路选择器:

1、外设的DMA请求,以H1为例有107个外设请求,剩下8个用于DMA发生器;

2、通道选择:用于选择DMA具体的选择通道,通道0~7是DMA1的通道0~7,通道8~15是DMA2的通道0~7;

3、同步控制:用于同步DMA请求,可以关闭;

4、请求信号:输出给DMA控制器。

-------------------------------------------------------------------------------------

对于上次的结构体,我们有了新的补充:

DMA_HandleTypeDef g_dma_handler.Init.FIFOMode:是否选用FIFO模式(以下三个成员只有在FIFO模式启动的时候才会生效);

DMA_HandleTypeDef g_dma_handler.Init.FIFOThreshold:FIFO模式的阈值;

DMA_HandleTypeDef g_dma_handler.Init.MemBurst:存储器突发传输;

DMA_HandleTypeDef g_dma_handler.Init.PeriphBurst:外设突发传输。

对于函数我们也有所补充:

HAL_DMA_Start_IT():开始DMA传输;

__HAL_LINKDMA():用于连接DMA和外设句柄;

HAL_UART_Transmit_DMA():使能DMA发送,启动传输;

__HAL_DMA_GET_FLAG():查询DMA传输通道的状态;

__HAL_DMA_ENABLE():使能DMA外设;

__HAL_DMA_DISABLE():失能DMA外设;

HAL_UART_DMAStop():停止DMA传输。

-------------------------------------------------------------------------------------

本次实验直接采用完整的HAL库。

接下来编写主函数代码main.c:

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#Include "./BSP/MPU/mpu.h"
#Include "./BSP/LED/led.h"
#Include "./BSP/LCD/lcd.h"
#Include "./BSP/KEY/key.h"
#Include "./BSP/DMA/dma.h"

const uint8_t TEXT_TO_SEND[] = {"DMA test!!!"};

#define SEND_BUF_SIZE (sizeof(TEXT_TO_SEND) + 2) * 200  //发送数据长度是200条相应数据的长度

uint8_t g_sendbuf[SEND_BUF_SIZE];

int main(void){

    uint8_t key = 0;
    uint16_t i, k;
    uint16_t len;
    uint8_t mask = 0;
    float pro = 0;

    sys_cache_enable();
    HAL_Init();
    sys_stm32_clock_init(RCC_PLL_MUL9);
    delay_init(72);
    led_init();
    mpu_memory_protection();
    lcd_init();
    key_init();
    usart_init(115200);
    LED0(0);

    dma_init(DMA2_Stream7, DMA_REQUEST_USART1_TX);

    lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "DMA TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "AUTO@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "KEY0:Start", RED);

    len = sizeof(TEXT_TO_SEND);
    k = 0;

    for(i = 0; i < SEND_BUF_SIZE; i++){

        if(k >= len){ //输出换行符
            if(mask){
                g_sendbuf[i] = 0x0a;
                k = 0;
            }
            else{
                g_sendbuf[i] = 0x0d;
                mask++;
            }
        }
        else{
            mask = 0;
            g_sendbuf[i] = TEXT_TO_SEND[k];
            k++;
        }
    }

    i = 0;

    while(1){
        key = key_scan(0);

        if(key == KEY0_PRES){
            printf("DMA DATA:\n");
            lcd_show_string(30, 130, 200, 16, 16, "Start Transmit...", BLUE);
            lcd_show_string(30, 150, 200, 16, 16, "   %", BLUE);

            HAL_USART_Transmit_DMA(&g_uart1_handle, g_sendbuf, SEND_BUF_SIZE);

            while(1){
                if(__HAL_DMA_GET_FLAG(&g_dma_handle, DMA_FLAG_TCIF3_7)){ //等待DMA2_Stream7反馈传输状态(数据流3)
                    __HAL_DMA_CLEAR_FLAG(&g_dma_handle, DMA_FALG_TCIF3_7);
                    HAL_UART_DMAStop(&g_uart1_handle);
                    break;
                }

                pro = __HAL_DMA_GET_COUNTER(&g_dma_handle);
                len = SEND_BUF_SIZE;
                pro = 1 - (pro / len);
                pro *= 100;
                lcd_show_num(30, 150, pro, 3, 16, BLUE);
            }

            lcd_show_num(30, 150, 100, 3, 16, BLUE); //显示100%
            lcd_show_string(30, 130, 200, 16, 16, "Transmit Finished!", BLUE);
        }

        i++;
        delay_ms(10);
        
        if(i == 20){
            i = 0;
            LED0_TOGGLE();
        }
    }

}

到这里我们的实验代码就编写完了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DMA的补充笔记 的相关文章

  • ADC与DMA回顾

    12位ADC是一种逐次逼近型模拟数字转换器 它有多达18个通道 xff0c 可测量16个外部和2个内部信号源 各通道的A D转换可以单次 连续 扫描或间断模式执行 ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中 ADC 的输入时
  • DMA原理,步骤超细详解,一文看懂DMA

    文章目录 什么是DMA DMA的基本定义 DMA定义 xff1a DMA传输方式DMA传输参数DMA的主要特征STM32少个DMA资源 xff1f DMA工作系统框图DMA传输方式仲裁器DMA数据流 xff08 仅存在于STM32F4 M4
  • 【STM32】DMA原理,配置步骤超详细,一文搞懂DMA

    目录 DMA xff08 Direct Memory Access xff09 简介 DMA传输方式 DMA功能框图 DMA请求映像 DMA1控制器 DMA2控制器 通道 仲裁器 DMA主要特性 DMA处理 DMA数据配置 从哪里来到哪里去
  • CubeMX 配置PWM使用DMA,生成Dshot600的协议

    看到电调支持Dshot125 600的协议 xff0c 想自己做一个支持Dshot协议的驱动 xff0c 所以研究了一下 xff0c 如何利用精确的PWM产生Dshot协议 先看结果 xff01 图中为油门值为1500的时候的输出的Dsho
  • HAL库 串口空闲中断+DMA接收不定长数据 详解及踩坑

    文章目录 前言一 串口及DMA基础配置二 HAL UARTEx ReceiveToIdle DMA 函数功能三 使用HAL UARTEx ReceiveToIdle DMA 函数1 重新实现回调函数HAL UARTEx RxEventCal
  • 串口通信的三种方式(查询、中断、DMA)

    PC机串口定义如下图 xff1a 一般的单片机串口应用只需3根信号线 xff1a 3脚TXD xff08 发送数据 xff09 2脚RXD xff08 接收数据 xff09 5脚SG xff08 信号地 xff09 其中单片机的TXD对应连
  • stm32---DMA

    DMA 全称Direct Memory Access xff08 直接存储器访问 xff09 xff0c 把一个地址空间的值 复制 到另一个地址空间 xff0c 使用DMA传输方式无需CPU直接控制传输 xff0c 通过硬件为RAM和IO设
  • STM32 USART 串口DMA收发注意事项

    正常情况这里不介绍 目录 1 低波特率情况 xff0c 接收信号可能会出现干扰 2 波特率300时 xff0c DMA接收无法工作 3 波特率1200时DMA发送 4 具体现象如下 环境 xff1a 主频72M STM32F103C8 注意
  • I/O的控制方式——查询,中断,dma

    早期 xff0c I O串行 xff0c 查询方式 发展 xff0c I O并行 xff0c 两种方式其一是中断方式 xff0c 其二是dma方式 xff0c 使得外部设备能直接与主存储器信息交换 xff0c 减轻了cpu的工作量 技术继续
  • (转)stm32F4-----DMA的FIFO作用和用法

    在STM32F4系列中DMA增加了个FIFO 这个FIFO的作用是什么 xff1f 当我使能这个FIFO时 xff08 DMA InitStructure DMA FIFOMode 61 DMA FIFOMode Enable xff09
  • STM32使用DMA接收串口数据

    目录 01 概述 02 DMA接收 03 中断 04 代码 01 概述 在之前的文章里 STM32串口详解 和 STM32 DMA详解 文章中 xff0c 详细讲解了STM32的串口和DMA外设 xff0c 本篇文章将不在细述串口和DMA的
  • 2.14 STM32 串口传输最佳处理方式 FreeRTOS+队列+DMA+IDLE (二)

    紧接着上一篇文章 如何合理处理多个串口接收大量数据 此种方法 很厉害 很NB 首先 利用DMA 可节省大量CUP资源 其次 利用IDLE空闲中断来接收位置个数的数据 最后利用串口DMA环形数据的偏移量 长度 入队 出队处理数据 保证了任务的
  • stm32HAL库 串口接收不定长数据(DMA传输)

    相信大家很多初学者都会遇到串口接收不定长数据的情况 对于初学者可能看着有点难理解 xff0c 多看几遍就好 xff0c 亲测能用 话不多说上菜上菜 xff01 xff01 xff01 xff01 此代码是本人在具体工程应用 xff0c 实测
  • 16. GD32F103C8T6入门教程-adc 使用教程2-dma+连续扫描方式采集数据

    adc 使用教程2 dma 连续扫描方式采集数据 adc 的扫描模式就是把配置了规则或注入通道按照配置的顺序采集一轮 adc 的连续转换模式就是把配置了规则或注入通道按照配置的顺序采集N轮 注意 dma使用时存在一个外设映射到一个dam外设
  • STM32L051测试 (五、串口测试 — 与Enocean模块通讯问题)

    STM32L051测试 第五课 串口的使用 by 矜辰所致 添加目录栏目 2021 9 30 调整文章格式 增加串口接收卡死处理说明 2022 7 18 目录 前言 一 串口接收处理的几种方式 1 1 串口接收发送不定长度的数据 非DMA方
  • STM32F103 UART4串口使用DMA接收不定长数据和DMA中断发送

    一 前言 使用DMA通信的好处是 不占用单片机资源 不像普通串口中断 发送一个字节触发一次中断 发送100个字节触发100次中断 接收一个字节触发一次中断 接收200个字节触发200次中断 数据接收完毕触发一次DMA中断 发送数据完毕触发一
  • DMA基本概念与常见寄存器设置

    什么是DMA DMA Direct Memory Access 即直接存储访问 DMA传输方式无需CPU直接控制传输 通过硬件为RAM I O设备开辟一条直接传输数据的通路 能使CPU的效率大为提高 每一种体系结构DMA传输不同 编程接口也
  • STM32F031串口(RS485)中断+DMA发送(预备知识)

    STM32F031串口 RS485 中断 DMA发送 前言 GPIO移植过程 与F1系列的一些区别 串口 DMA 前言 最近在搞STM32F031的项目 F0系列与常用的F1系列有一定区别 在开发过程中遇到一些问题 而且花了好长花间在搜寻解
  • 启用 DMA 的 UART Tx 模式

    我已经为 UART 在传输模式下编写了一个简单的设备驱动程序 并启用了 DMA 和中断 我使用的硬件是 omap 4460 pandaboard 其中加载了 Linux 3 4 下面我分享一下相关部分的代码 在开放阶段 dma map io
  • DMA 与中断驱动的 I/O

    我不太清楚 DMA 和中断 I O 之间的区别 当前正在阅读操作系统概念 第 7 版 具体来说 我不确定在这两种情况下何时会发生中断 以及在这两种情况下 CPU 在什么时候可以自由地执行其他工作 我一直在读但不一定能调和的东西 中断驱动 通

随机推荐

  • Django HttpResponse与JsonResponse

    我们编写一些接口函数的时候 xff0c 经常需要给调用者返回json格式的数据 xff0c 那么如何返回可直接解析的json格式的数据呢 xff1f 首先先来第一种方式 xff1a from django shortcuts import
  • Ubuntu安装mysql

    首先执行下面三条命令 xff1a sudo apt get install mysql server sudo apt install mysql client sudo apt install libmysqlclient dev 安装成
  • 10种动态进度条用css3实现

    用css做的10种动态进度条 xff0c 喜欢可以直接去用话不多说先看效果图 xff1a 实现上图的 xff0c 最主要的就是应用了css动画属性 64 keyframes和animation属性结合应用 下面看看语法 xff1a 64 k
  • Yolo训练数据标注工具-Yolo_mark 使用教程

    一 安装与测试 环境 xff1a Ubuntu16 04 43 Opnecv 43 Cmake 项目地址 xff1a https github com AlexeyAB Yolo mark 下载 打开终端 xff0c 键入 xff1a gi
  • x86、ARM分属大小端

    小端模式 xff1a 一个数据的高位在大的地址端 xff0c 低位在小的地址端 xff0c x86也就是pc机就是小端的 xff1a include 34 stdio h 34 include 34 stdlib h 34 int main
  • 二叉树(C语言实现)——链式存储结构

    include lt stdio h gt include lt stdlib h gt include lt stdbool h gt define QueueSize 200 typedef char DataType typedef
  • 栈,堆,常量区都放什么

    1 寄存器 xff1a 最快的存储区 由编译器根据需求进行分配 我们在程序中无法控制 xff1b 1 栈 xff1a 存放基本类型的变量数据和对象的引用 xff0c 但对象本身不存放在栈中 xff0c 而是存放在堆 xff08 new 出来
  • Windows10安装Docker并创建本地Ubuntu环境

    安装Docker参考文章 xff1a https www cnblogs com Can daydayup p 15468591 html label0 安装本地Ubuntu环境 xff1a windows10下安装docker xff0c
  • 机器人操作系统ROS是什么?

    目录 1 什么是ROS 2 ROS的许可协议 3 ROS的主要发行版本 4 ROS的主要功能 5 ROS的应用 6 ROS开发的常用工具 7 ROS的优点 8 ROS的缺点 1 什么是ROS ROS是机器人操作系统 xff08 Robot
  • 【教程】如何移植FPGA关于HDMI例程

    教程 如何移植FPGA关于HDMI例程 时钟IP核约束条件 在完成EDA作业后 xff0c 抽空分享一下如何移植FPGA的例程 我EDA作业用的板子型号是Zybo Z7 xff0c 然后移植的是原子哥的HDMI实现方块移动例程 故本教程是基
  • 【MATLAB UAV Toolbox】使用指南(三)

    可视化自定义飞行日志 通过配置flightLogSignalMapping可从自定义的飞行日志中可视化数据 加载自定义的飞行日志 在本例中 xff0c 假设飞行数据已经被解析到MATLAB 中 xff0c 并存储为M文件 本示例重点介绍如何
  • matplotlib学习笔记

    matplotlib第一章 matplotlib通常有两种绘图接口 xff1a 显示创建figure和axes 依赖pyplot自动创建figure和axes 并绘图 matplotlib环境 本文是在jupyter notebook下运行
  • OPNET 修改节点图标大小

    老是记不住在哪修改图标 xff0c 有一天看急眼了 xff0c 经过半小时的斗争 xff0c 终于找到了 xff0c 这次一定要把它记下来 View gt Layout gt Scale Node icons Interactively
  • 自定义msg使用C++

    在之前创建talker的src文件夹中创建person cpp并编写如下 include 34 ros ros h 34 include 34 learning communication Person h 34 include lt ss
  • GPIO的八种模式分析

    GPIO是general purpose input output 即通用输入输出端口 xff0c 作用是负责外部器件的信息和控制外部器件工作 GPIO有如下几个特点 xff1a 1 不同型号的IO口数量不同 xff1b 2 xff0c 反
  • 关于STM32_IWDG独立看门狗的一些笔记

    独立看门狗 IWDG xff0c Independent watchdog xff0c 本质是一个可以定时产生系统复位信号 并且可以通过 喂狗 复位的计时器 它由独立的RC振荡器 低速时钟 LSI 驱动 xff0c 即使主时钟发生故障它也仍
  • 关于MPU的笔记

    MPU xff08 memory protection unit xff09 内存保护单元 这些系统必须提供一种机制来保证正在运行的任务不破坏其他任务的操作 即要防止系统资源和其他一些任务不受非法访问 嵌入式系统有专门的硬件来检测和限制系统
  • 关于OLED屏的笔记

    OLED即有机发光管 Organic Light Emitting Diode OLED OLED显示技术具有自发光 广视角 几乎无穷高的对比度 较低功耗 极高反应速度 可用于绕曲性面板 使用温度范围广 构造及制程简单等有点 xff0c 被
  • Ubuntu 上 Let‘s Encrypt 生成泛域名证书

    安装生成工具certbot xff1a apt install certbot 查看安装在哪 xff1a which certbot 使用certbot xff08 位置在 usr bin certbot xff09 生成证书 xff1a
  • DMA的补充笔记

    DMA有两个总线 xff1a 1 DMA存储器总线 xff1a DMA通过该总线来执行存储器数据的传入和传出 2 DMA外设总线 xff1a DMA通过该总线访问AHB外设 xff08 AHB主要是针对高效率 高频宽以及快速系统模块所设计的