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的补充笔记 的相关文章

  • 关于RS485的DMA发送,以及EN使能脚的自动切换

    一 电路设计 1 低成本非隔离 xff1a 3 3v系统同样 xff0c 将5V改为3 3即可 同时采用TX连接三极管 xff0c 实现三极管驱动RS485芯片的EN使能脚 xff0c 从而省下一个IO口控制 隔离只需要将两个信号线用光耦隔
  • Stm32CubeMx通过DMA获取多路ADC采集的数据(踩到坑的来看看,我也是一步步踩坑到实现的)

    用stm32CubeMX 可以轻松配置模拟电压数值采集 由于使用直接存储器DMA进行ADC数据采集无需一直占用着CPU线程 所以我们一般在需要多通道采集的情况下才使用DMA 多路ADC采集在工业生产测量方面也很常用到 所以这个内容我们还是得
  • STM32_串口的DMA接收

    STM32使用DMA在串口接收数据的方法如下 xff1a span class token macro property span class token directive hash span span class token direc
  • ((硬件spi+dma)+模拟spi)驱动LCD5110

    span class hljs preprocessor ifndef spi dma h span span class hljs preprocessor define spi dma h span span class hljs pr
  • 串口通信的三种方式(查询、中断、DMA)

    PC机串口定义如下图 xff1a 一般的单片机串口应用只需3根信号线 xff1a 3脚TXD xff08 发送数据 xff09 2脚RXD xff08 接收数据 xff09 5脚SG xff08 信号地 xff09 其中单片机的TXD对应连
  • Xilinx的Zynq系列,ARM和PL通过DMA通信时如何保证DDR数据的正确性。

    使用ZYNQ或者MPSoC的好处是可以通过PL逻辑设计硬件加速器 xff0c 对功能进行硬件加速 加速器和ARM之间的交互信息一般包含自定义加速指令传递 待计算数据以及计算结果 这三种交互信息为了实现高性能往往需要使用DMA进行通信 考虑两
  • 中断与DMA

    中断 Cortex M3256 个优先级和 128 个抢占级悬起pending 中断中断的类型中断结构 DMA通道映射源传输和目标传输寄存器中断状态寄存器和中断标志清除寄存器通道x配置DMA stream x configuration r
  • 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 注意
  • FIFO和DMA

    FIFO SPI端口增加了FIFO xff0c 使得传输数据有了缓冲区间 FIFO存储器是一个先入先出的双口缓冲器 xff0c 即第一个进入其内的数据第一个被移出 xff0c 其中一个存储器的输入口 xff0c 另一个口是存储器的输出口 主
  • 2.14 STM32 串口传输最佳处理方式 FreeRTOS+队列+DMA+IDLE (二)

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

    ZYNQ系列 xff08 十二 xff09 linux的DMA使用 文章目录 ZYNQ系列 xff08 十二 xff09 linux的DMA使用前言开发环境准备工作petalinux工程建立建立工程配置内核1 配置DMA2 配置CMA 修改
  • STM32L051测试 (五、串口测试 — 与Enocean模块通讯问题)

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

    FreeRTOS例程4 串口DMA收发不定长数据 知乎 zhihu com
  • STM32F103ZET6 之 ADC+TIM+DMA+USART 综合实验

    1 实验目的 1 使用 TIM1 触发 ADC ADC 采集的数据通过DMA 传至内存 然后通过串口打印出采集的数据 2 学会 DMA 传输数据并将数据进行保存 3 验证ADC 的采样率与实际设置的是否相符 2 硬件资源 1 指示灯 2 A
  • 基于32单片机的16通道ADC的数据采集

    基于32单片机的16通道ADC的数据采集 这个部分的内容 是作为外部模拟量部分的采集工作 按照任务要求 所设计的方案 需要完成以下指标 ADC必须能采集16通道的模拟量 ADC的分辨率是16bit 采样率不小于20khz 由此分析可以得出
  • STM32F1应用DMA——串口收发不定长数据

    STM32F1应用DMA 串口收发不定长数据 使用STM32自带DMA传输数据 可以减轻CPU负担 只需设置一些参数即可发送想要发送的数据 以下是STM32F1系列芯片测试过的部分代码 可实现DMA串口收发数据 下图来自STM32官网的手册
  • STM32F031串口(RS485)中断+DMA发送(预备知识)

    STM32F031串口 RS485 中断 DMA发送 前言 GPIO移植过程 与F1系列的一些区别 串口 DMA 前言 最近在搞STM32F031的项目 F0系列与常用的F1系列有一定区别 在开发过程中遇到一些问题 而且花了好长花间在搜寻解
  • 多核架构中的 CPU 和内存访问

    我想知道如果 例如 CPU 的 2 个核心尝试同时访问内存 通过内存控制器 一般 如何处理内存访问 实际上 当内核和启用 DMA 的 IO 设备尝试以相同方式访问时 同样适用 I think 内存控制器足够智能 可以利用地址总线并同时处理这
  • 从哪里开始学习 Linux DMA/设备驱动/内存分配

    我正在移植 调试设备驱动程序 由另一个内核模块使用 并面临死胡同 因为 dma sync single for device 因内核错误而失败 我不知道这个函数应该做什么 而且谷歌搜索也没有什么帮助 所以我可能需要了解更多关于这个东西的知识

随机推荐

  • 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主要是针对高效率 高频宽以及快速系统模块所设计的