DMA的三种传输功能

①内存到内存

#include "dma.h"
#include "stdio.h"#define BUF_SIZE 16uint32_t src_buf[BUF_SIZE] ={0x00000000,0x11111111,0x22222222,0x33333333,0x44444444,0x55555555,0x66666666,0x77777777,0x88888888,0x99999999,0xAAAAAAAA,0xBBBBBBBB,0xCCCCCCCC,0xDDDDDDDD,0xEEEEEEEE,0xFFFFFFFF};
uint32_t dst_buf[BUF_SIZE]={0};DMA_HandleTypeDef dma_handle={0};  void dma_init()
{__HAL_RCC_DMA1_CLK_ENABLE(); dma_handle.Instance = DMA1_Channel1;                               //基地址 dma_handle.Init.Direction= DMA_MEMORY_TO_MEMORY;                   //方向是什么 是存储器到外设  还是外设到存储器  文中代码为内存到内存      DMA_MEMORY_TO_PERIPH(此为内存到外设)//内存相关的配置 dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE ;          //数据对齐的模式   这里选择的是字节对齐的模式dma_handle.Init.MemInc=DMA_MINC_ENABLE;                          //数据增长的方式(偏移)//外设相关的配置dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;       //外设数据对齐的模式dma_handle.Init.PeriphInc =DMA_PINC_ENABLE ;                 //外设数据增长的方式   dma_handle.Init.Priority = DMA_PRIORITY_MEDIUM;                  //优先级(中等)dma_handle.Init.Mode = DMA_NORMAL;                              //模式选择(循环模式还是非循环模式)  内存到内存只支持正常模式 不支持循环模式HAL_DMA_Init(&dma_handle);}void dma_transmit(void)
{HAL_DMA_Start(&dma_handle,(uint32_t)src_buf,(uint32_t)dst_buf,sizeof(uint32_t)* BUF_SIZE);              //包含三个参数 源 目标 数据长度 和handle  其中 DMA 配置为 字节传输(8 位),DataLength 的单位是 字节数  因此16个数据 每个数据4个字节while(__HAL_DMA_GET_FLAG(%dma_handle,DMA_FLAG_TC1) == RESET);               ///RESET为0 SER为1   int i =0;for(i=0;i<BUF_SIZE;i++)printf("buf[%d] =%X\r\n",i,dst_buf[i]);}

输出结果如下

②外设到内存

编程步骤如下

dma.c代码如下

#include "dma.h"
#include "stdio.h"#define BUF_SIZE 16DMA_HandleTypeDef dma_handle={0};  
extern UART_HandleTypeDef uart1_handle;void dma_init()
{__HAL_RCC_DMA1_CLK_ENABLE(); dma_handle.Instance = DMA1_Channel4;                               //基地址 dma_handle.Init.Direction= DMA_MEMORY_TO_PERIPH;                   //方向是什么 是存储器到外设  还是外设到存储器  文中代码为内存到内存      DMA_MEMORY_TO_PERIPH(此为内存到外设)//内存相关的配置 dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE ;          //数据对齐的模式   这里选择的是字节对齐的模式dma_handle.Init.MemInc=DMA_MINC_ENABLE;                          //数据增长的方式(偏移)//外设相关的配置dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;       //外设数据对齐的模式dma_handle.Init.PeriphInc =DMA_PINC_DISABLE ;                 //外设数据增长的方式     内存到外设的目标不能递增 dma_handle.Init.Priority = DMA_PRIORITY_MEDIUM;                  //优先级(中等)dma_handle.Init.Mode = DMA_NORMAL;                              //模式选择(循环模式还是非循环模式)  内存到内存只支持正常模式 不支持循环模式HAL_DMA_Init(&dma_handle);__HAL_LINKDMA(&uart1_handle,hdmatx,dma_handle);                //第一个数据为外设句柄  第二个为出口发送数据(tx) 第三个为DMA的句柄}

uart.c文件

void USART1_IRQHandler(void)
{uint8_t receive_data = 0;   if(__HAL_UART_GET_FLAG(&uart1_handle, UART_FLAG_RXNE) != RESET){        /* 获取接收RXNE标志位是否被置位 */if(uart1_rx_len >= sizeof(uart1_rx_buf))                            /* 如果接收的字符数大于接收缓冲区大小, */uart1_rx_len = 0;                                               /* 则将接收计数器清零 */HAL_UART_Receive(&uart1_handle, &receive_data, 1, 1000);            /* 接收一个字符 */uart1_rx_buf[uart1_rx_len++] = receive_data;                        /* 将接收到的字符保存在接收缓冲区 */}if (__HAL_UART_GET_FLAG(&uart1_handle, UART_FLAG_IDLE) != RESET)        /* 获取接收空闲中断标志位是否被置位 */{
//        printf("recv: %s\r\n", uart1_rx_buf);                               /* 将接收到的数据打印出来 */
//        uart1_rx_clear();
//        __HAL_UART_CLEAR_IDLEFLAG(&uart1_handle);                           /* 清除UART总线空闲中断 *///清除空闲中断__HAL_UART_CLEAR_IDLEFLAG(&uart1_handle);//停止DMA传输,防止干扰HAL_UART_DMAStop(&uart1_handle);//获取接收到的数据长度uart1_rx_len=UART1_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(&dma_handle);              //总共接受的减去剩余的即为获取接收到的数据长度//打印接收到的内容printf("recv:%s,recv_len:%d\r\n",uart1_rx_buf,uart1_rx_len);//清空接收缓冲uart1_rx_clear();//重新开启串口DMA传输HAL_UART_Receive_DMA(&uart1_handle,uart1_rx_buf,UART1_RX_BUF_SIZE);}
}

结果输出如下

利用空闲中断 和DMA传输储存在缓冲区 

③外设到内存

dma.c的代码如下

#include "dma.h"
#include "stdio.h"#define BUF_SIZE 16DMA_HandleTypeDef dma_handle={0};  
extern UART_HandleTypeDef uart1_handle;void dma_init()
{__HAL_RCC_DMA1_CLK_ENABLE(); dma_handle.Instance = DMA1_Channel4;                               //基地址 dma_handle.Init.Direction= DMA_MEMORY_TO_PERIPH;                   //方向是什么 是存储器到外设  还是外设到存储器  文中代码为内存到内存      DMA_MEMORY_TO_PERIPH(此为内存到外设)//内存相关的配置 dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE ;          //数据对齐的模式   这里选择的是字节对齐的模式dma_handle.Init.MemInc=DMA_MINC_ENABLE;                          //数据增长的方式(偏移)//外设相关的配置dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;       //外设数据对齐的模式dma_handle.Init.PeriphInc =DMA_PINC_DISABLE ;                 //外设数据增长的方式     内存到外设的目标不能递增 dma_handle.Init.Priority = DMA_PRIORITY_MEDIUM;                  //优先级(中等)dma_handle.Init.Mode = DMA_NORMAL;                              //模式选择(循环模式还是非循环模式)  内存到内存只支持正常模式 不支持循环模式HAL_DMA_Init(&dma_handle);__HAL_LINKDMA(&uart1_handle,hdmatx,dma_handle);                //第一个数据为外设句柄  第二个为出口发送数据(tx) 第三个为DMA的句柄}

main.c代码如下

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"
#include "dma.h"uint8_t send_buf[1000] ={0};
extern UART_HandleTypeDef uart1_handle;int main(void)
{HAL_Init();                         /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */led_init();uart1_init(115200);dma_init();//printf("hello world!\r\n");int i =0;for(i=0;i<1000;i++)send_buf[i]='A';HAL_UART_Transmit_DMA(&uart1_handle,send_buf,1000);while(1){ led1_on();led2_off();delay_ms(500);led1_toggle();led2_toggle();delay_ms(500);}
}

结果如下

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

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

相关文章

【MySQL】MySQL 表的增删改查(CRUD)—— 下篇(内含聚合查询、group by和having子句、联合查询、插入查询结果)

目录 1. 插入查询结果 2 聚合查询 &#xff08;行与行之间运算&#xff09; count 计算查询结果的行数 sum 求和 avg 求平均值 max 最大值 min 最小值 【小结】 3. group by 子句 分组 where 条件 having 条件 4. 联合查询&#xff08;多表查询&#xff09; 内连接…

“思考更长时间”而非“模型更大”是提升模型在复杂软件工程任务中表现的有效途径 | 学术研究系列

作者&#xff1a;明巍/临城/水德 还在为部署动辄数百 GB 显存的庞大模型而烦恼吗&#xff1f;还在担心私有代码库的安全和成本问题吗&#xff1f;通义灵码团队最新研究《Thinking Longer, Not Larger: Enhancing Software Engineering Agents via Scaling Test-Time Compute》…

电脑屏幕录制软件Captura源码编译(Win10,VS2022)

屏幕录像的意义&#xff1a; 教育教学方面 制作教学资源&#xff1a;教师可以通过录制屏幕来制作教学视频&#xff0c;演示软件操作、讲解复杂的知识点等。学生可以随时观看这些视频&#xff0c;便于复习和巩固知识&#xff0c;尤其对于一些抽象的概念或难以在课堂上一次性掌握…

记一次调用大华抓拍SDK并发优化

目录 一、问题分析 二、解决思路 三、贴代码 四、总结 一、问题分析 按惯例上问题&#xff1a; 设备告警采用高电平持续模式&#xff1a;一次开&#xff0c;不主动关就一直处于告警状态。 并发时多个请求下发 setDVRAlarmOutConfig&#xff0c;导致状态混乱。 “开 -&g…

Python图像变清晰与锐化,调整对比度,高斯滤波除躁,卷积锐化,中值滤波钝化,神经网络变清晰

本次使用图片来源于百度 import cv2 import time import numpy as np import pywtfrom PIL import Image, ImageEnhance#-i https://pypi.mirrors.ustc.edu.cn/simpledef super_resolution(input_path, output_path, model_path, scale4):# 初始化超分辨率模型sr cv2.dnn_su…

12个HPC教程汇总!从入门到实战,覆盖分子模拟/材料计算/生物信息分析等多个领域

在科学研究、工程仿真、人工智能和大数据分析等领域&#xff0c;高性能计算 (High Performance Computing, HPC) 正扮演着越来越重要的角色。它通过并行处理、大规模计算资源的整合&#xff0c;极大提升了计算效率&#xff0c;使原本耗时数日的任务能够在数小时内完成。 随着计…

使用Autocannon.js进行HTTP压测

目录 一、为什么选择Autocannon&#xff1f; 二、五分钟快速上手 1. 环境准备 2. 发起首个压测 3. 解读测试报告 三、高阶场景实战 场景1&#xff1a;POST请求压测 场景2&#xff1a;阶梯式压力测试 场景3&#xff1a;编程式集成测试 四、结果深度分析指南 1. 延迟分…

pnpm install报错:此系统上禁止运行脚本

依赖安装 报错信息&#xff1a; pnpm : 无法加载文件 C:\Users\XXX\AppData\Roaming\npm\pnpm.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about_Execution_Policies。 所在位置 行:1 …

第9章 多模态大语言模型

​​​​​​第1章 对大型语言模型的介绍第2章 分词和嵌入第3章 解析大型语言模型的内部机制第4章 文本分类第5章 文本聚类与主题建模第6章 提示工程第7章 高级文本生成技术与工具第8章 语义搜索与检索增强生成第10章 构建文本嵌入模型第11章 面向分类任务的表示模型微调第12章…

Python 绘图代码解析:用 Turtle 和 Colorsys 打造绚丽图案

注:本文为作者原创文章,未经许可禁止转载。 Python 绘图代码解析:用 Turtle 和 Colorsys 打造绚丽图案 在 Python 的世界里,有许多有趣的库可以用来创造精美的图形。今天,我们就来详细剖析一段使用turtle库和colorsys库的代码,看看它是如何绘制出独特图案的。 一、库的导…

RTMP 入门指南

1. RTMP 基础概念​​ ​​核心角色​​&#xff1a; ​​推流端&#xff08;Publisher&#xff09;​​&#xff1a;将音视频数据推送到服务器的设备&#xff08;如OBS、手机APP&#xff09;。​​服务器&#xff08;RTMP Server&#xff09;​​&#xff1a;接收推流并分发给…

Java Stream流 常用方法

Map 修改 用于修改集合里的值 public void findData(){ArrayList<String> list new ArrayList<>();list.add("张三");list.add("李四");List<String> collect list.stream().map(s -> s "a").collect(Collectors.toLi…

巧记英语四级单词 Unit5-上【晓艳老师版】

count 数&#xff0c; counter n.计算器&#xff0c;柜台 a.相反的 数数的东西就是计算器&#xff0c;在哪数&#xff0c;在柜台里面数&#xff1b;你和售货员的关系就是相反的(一个买货&#xff0c;一个卖货account n.账户&#xff0c;账号 一再的数accountant n.会计 一再的…

Git多人协作与企业级开发模型

目录 1.多人协作一 2.多人协作二 3.远程分⽀删除后&#xff0c;本地gitbranch-a依然能看到的解决办法 4.企业级开发模型 4.1.Git的重要性 4.2.系统开发环境 4.3.Git 分⽀设计规范 1.多人协作一 ⽬前&#xff0c;我们所完成的⼯作如下&#xff1a; 基本完成Git的所有本…

大众点评 mtgsig1.2 分析 mtgsig

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向过程 部分代码 params[yodaRead…

(三) Trae 调试C++ 基本概念

调试C基本概念 一、调试基础概念1.1 调试信息格式1.2 DWARF格式和PDB格式生成(图解)1.3.典型工具链和调试信息 二、各工具链深度解析1. Clang 与 G 的 DWARF 差异 三 调试工具3.1 调试工具3.2 调试插件(Trae) 一、调试基础概念 1.1 调试信息格式 格式类型适用系统存在形式DWA…

Flink部署与应用——部署方式介绍

引入 我们通过Flink相关论文的介绍&#xff0c;对于Flink已经有了初步理解&#xff0c;这里简单的梳理一下Flink常见的部署方式。 Flink 的部署方式 StandAlone模式 介绍 StandAlone模式是Flink框架自带的分布式部署模式&#xff0c;不依赖其他的资源调度框架&#xff0c…

【智慧城市】新中地GIS开发实训:基于 Vue 框架的武汉智慧旅游系统

首页 地球自转页 控制台页 景点信息页 天气预报页 路线规划页 查询页 AI问答页 热力图页 测量页 来源&#xff1a; 【智慧城市】新中地GIS开发实训&#xff1a;优秀学生项目作品&#xff08;58&#xff09;基于 Vue 框架的武汉智慧旅游系统

C++入侵检测与网络攻防之网络嗅探以及ARP攻击

目录 1.tcpdump基本使用 2.tcpdump条件过滤 3.wireshark介绍 4.wireshark的介绍 5.tcp握手挥手分析 6.telnet服务的介绍和部署 7.复习 8.telnet服务的报文嗅探 9.网络嗅探基础 10.arp协议的解析 11.arp攻击原理以及试验环境 12.arp实验以及防御方式 1.tcpdump基本使…

【数据可视化-28】2017-2025 年每月产品零售价数据可视化分析

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…