stm_DMA

代码:

#include "stm32f10x.h"                  // Device headeruint16_t MyDMA_Size;void MyDMA_Init(uint32_t AddrA,uint32_t AddrB,uint16_t Size)//函数初始化DMA
{MyDMA_Size = Size;
//第一步,RCC开启DMA的时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//DMA是AHB总线的设备,所以要用AHB开启时钟的函数,第一个参数在函数中的定义是:对于互联型设备,这个参数可以是下面这些值的组合;对于其他设备是这下面的组合。互联型是STM32F105/107的型号,F103的在其它设备下面的参数表里选RCC_AHBPeriph_DMA1。第二个参数ENABLE,开启DMA1的时钟。//第二步,参数初始化配置。直接调用DMA_Init,初始化各个参数,包括外设和存储器站点的起始地址、数据宽度、地址是否自增、方向、传输计数器、是否需要自动重装、选择触发源、通道优先级。这些所有的参数,通过一个结构体,就可以配置好了。DMA_InitTypeDef DMA_InitStructure;//外设站点的:DMA_InitStructure.DMA_PeripheralBaseAddr=AddrA;//起始地址,外设站点的基地址,这在里要写一个32位的地址,比如 0x20000000 这样的地址,对于SRAM的数组,他的地址是编译器分配的,并不是固定的。所以一般不会写绝对地址,而是通过数组名来获取地址。在这里就把这个地址提取成初始化函数的参数,这样在初始化的时候,想转运哪个数组就把哪个数组的地址传进来就行了,所以这里函数void MyDMA_Init(void),改成void MyDMA_Init(uint32_t AddrA),然后把AddrA放在这个参数这里。这样外设站点的地址就完成了。DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;//数据宽度,函数定义中介绍是,指定数据宽度的参数可以是以下值:
//DMA_PeripheralDataSize_Byte       Byte,字节,就是uint8_t  
//DMA_PeripheralDataSize_HalfWord   HalfWord,半字,就是uint16_t
//DMA_PeripheralDataSize_Word        Word,字,就是uint32_t
//这里需要以字节的方式传输,所以就填入DMA_PeripheralDataSize_ByteDMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Enable;//是否自增,定义解释是,指定外设地址是自增或者不是,参数取值:
//DMA_PeripheralInc_Enable  自增
//DMA_PeripheralInc_Disable   不自增
//数组之间的转运,地址需要自增,所以这里选择DMA_PeripheralInc_Enable//存储器站点的:DMA_InitStructure.DMA_MemoryBaseAddr=AddrB;//起始地址,存储器站点的基地址,也把它提取成参数,在void MyDMA_Init(uint32_t AddrA)函数这里加一个参数变为void MyDMA_Init(uint32_t AddrA,uint32_t AddrB),然后参数这里放AddrB,作为存储器站点的起始地址。DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;//数据宽度,和外设站点一样也选择Byte参数,以字节传输。
//DMA_MemoryDataSize_Byte    	 Byte,字节,就是uint8_t  
//DMA_MemoryDataSize_HalfWord	 HalfWord,半字,就是uint16_t
//DMA_MemoryDataSize_Word    	  Word,字,就是uint32_tDMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//是否自增,和外设站点一样也选择地址自增。
//	DMA_MemoryInc_Enable   自增
//  DMA_MemoryInc_Disable   不自增
//这样外设站点和存储器站点的参数就配置好了。DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//传输方向,函数定义解释是,指定外设站点是源端还是目的地。
//DMA_DIR_PeripheralDST  外设站点作为DST,destination,目的地,外设站点作为目的地,其实就是传输方向是存储器站点到外设站点。  
//DMA_DIR_PeripheralSRC   外设站点作为SRC,source,源头,也就是外设站点到存储器站点的传输方向。
//函数设计将DataA放在外设站点,DataB放在存储器站点。传输方向就是外设站点到存储器站点,所以这里选择 DMA_DIR_PeripheralSRC参数,外设站点作为数据源。DMA_InitStructure.DMA_BufferSize=Size;//缓存区大小,其实就是传输计数器。函数定义解释是,以数据单元指定缓存区大小,数据单元等于外设数据宽度或者存储器数据宽度,数据宽度取决于传输方向。以数据单元指定缓存区大小,就是说需要传送几个数据单元,这个数据单元等于传输源站点的DataSize,简单理解就是,DMA_BufferSize就是传输计数器,指定传输几次。可以查看DMA_Init函数的源码,DMA_BufferSize参数其实就是直接赋值给了传输计数器的寄存器,它的取值是0~65535.这里把DMA_BufferSize参数也提取到函数的参数里来,然后把Size放到DMA_BufferSize参数这里,这样传输次数就完成了。DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;//传输模式,其实就是指定传输计数器是否使用自动重装。函数定义解释,指定操作方式有对应参数取值列表。还有一个注意事项,写的是循环模式,也就是自动重装,不能应用在存储器到存储器的情况下。也就是之前博文说的,自动重装和软件触发不能同时使用,如果同时使用,DMA就会连续触发,永远也不会停下来。
//DMA_Mode_Circular  循环模式,就是传输计数器自动重装  
//DMA_Mode_Normal  正常模式,就是传输计数器不自动重装,自减到0后停下来。
//这里转运数组,是存储器到存储器的传输,转运一次停下来就行了。选择正常模式DMA_Mode_NormalDMA_InitStructure.DMA_M2M=DMA_M2M_Enable;//选择是否存储到存储器,其实就是选择硬件触发还是软件触发。函数定义解释是,DMA是否应用于存储器到存储器的转运,存储器到存储器的模式就是软件触发。
//DMA_M2M_Enable     使用软件触发   
//DMA_M2M_Disable   不使用软件触发,也就是使用硬件触发。 
//这里转运数组,所以选择DMA_M2M_EnableDMA_InitStructure.DMA_Priority=DMA_Priority_Medium;//优先级,按照参数要求,给一个优先级。函数定义解释,指定通道的软件优先级。
// DMA_Priority_VeryHigh    非常高  
// DMA_Priority_High     高
// DMA_Priority_Medium    中等   
// DMA_Priority_Low     低
//如果有多个通道,可以指定一下优先级,确保紧急的转运有更高的优先级。这里只有一个通道,那优先级可以任意。//这些参数可以对应结构图来看,每一个参数都是可以配置的DMA_Init(DMA1_Channel1,&DMA_InitStructure);//第一个参数:DMAy_Channelx,y可以是1或2,用来选择是哪个DMA;对于DMA1,x可以是1~7,或者对于DMA2,x可以是1~5.用来选择是哪一个通道。所以DMA_Init函数的第一个参数,既选择了是哪个DMA,也选择了是DMA的哪个通道。
//DMAy_Channelx,这里y写为1,选择DMA1;x选择通道,这里因为是存储器到存储器的转运,用的是软件触发,所以通道可以任意选择。这里x给1,通道1.
//把结构体的地址放在第二个参数的位置,这样就是把结构体指定的参数,配置到DMA1的通道1里面去。
//以上DMA的参数就配置完成了。参数虽然比较多,但是对照框图来理解的话,就比较清晰。
//到目前为止,DMA还不能工作。DMA转运有三个条件:第一个条件,传输计数器大于0;第二个条件,触发源有触发信号;第三个条件,DMA使能。三个条件缺一不可,目前如果传一个大于0的Size的话,第一个条件满足。触发源为软件触发,所以一直都有触发信号,第二个条件满足。最后一个条件,DMA还没有使能,第三个条件不满足。所以到目前为止DMA还不会工作。如果想在初始化之后就立刻工作的话,可以在最后加上DMA_Cmd函数
//第三步,开关控制,调用DMA_Cmd函数,给指定的通道使能,就完成了。	DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA之后,三个条件满足,DMA就会进行数据转运了。转运一次,传输计数器自减一次,当传输计数器减到0之后,转运完成。转运完成的同时第一个条件就不满足了,转运停止。这样就完成了一次数组之间的数据转运。
//	DMA_Cmd(DMA1_Channel1,DISABLE);//这里先给DISABLE,不让DMA初始化之后,就立刻进行转运。而是等调用了Transfer函数之后,再进行转运。调用一次,转运一次,这样来工作。}void MyDMA_Transfer(void)//调用一次这个函数,就再启动一次DMA转运。
{//函数里面需要重新给传输计数器赋值,传输计数器赋值,必须要先给DMA失能,所以这里,调用DMA_Cmd函数,DMA_Cmd(DMA1_Channel1,DISABLE);//第二个参数给DISABLE。然后就可以给传输计数器赋值了。DMA_SetCurrDataCounter(DMA1_Channel1,MyDMA_Size);//第一个参数,选择DMA和通道。第二个参数是指定要给传输计数器写入的值,这里需要获取一下初始化这里的Size参数,但是这俩参数不在一个函数,不能直接传递过来。可以在代码块最前面定义一个全局变量MyDMA_Size,初始化的时候把Size往这个全局变量里也存一份,之后在这个函数块里,就可以使用全局变量的MyDMA_Size了。这样就可以重新给传输计数器赋值了。//最后,再次调用DMA_Cmd函数,DMA_Cmd(DMA1_Channel1,ENABLE);//第二个参数给ENABLE//这样DMA传输的3个条件又重新满足了。DMA就会再次开始转运
//转运开始之后还需要做一个工作,就是等待转运完成,因为转运也是要花一些时间的,等待转运完成调用 DMA_GetFlagStatus函数,查看标志位while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);
//总共四种标志位,以DMA1的通道1举例,其它所有的通道,都是这4种标志位。
//DMA1_FLAG_GL1:全局标志位
//DMA1_FLAG_TC1:转运完成标志位
//DMA1_FLAG_HT1:转运过半标志位
//DMA1_FLAG_TE1:转运错误标志位
//这里需要检查DMA1通道1转换完成的标志位,所以选择DMA1_FLAG_TC1参数。//转运完成之后,标志位置1,所以需要加一个while循环,等待这个标志位==RESET,如果没有完成,就一直循环等待,这样就实现了等待转运完成的效果了。标志位置1之后,不要忘记清除标志位,这个标志位需要手动清除。调用 DMA_ClearFlag函数DMA_ClearFlag(DMA1_FLAG_TC1);}

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

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

相关文章

yolo自动化项目实例解析(七)自建UI--工具栏选项

在上一章我们基本实现了关于预览窗口的显示&#xff0c;现在我们主要完善一下工具栏菜单按键 一、添加任务ui 先加个ui页面&#xff0c;不想看ui的复制完这个文件到ui目录下转下py直接从第二步开始看 vi ui/formpy.ui <?xml version"1.0" encoding"UTF-8&q…

Mysql数据库--删除和备份、约束类型

目录 1.删除操作 1.1表的删除操作 1.2数据库备份 2.约束 2.1基本概况 2.2not null约束演示 2.3unique约束演示 2.4default约束演示 2.5primary key约束演示 2.6foreign key约束演示 2.7check约束演示 1.删除操作 1.1表的删除操作 delete from 表名 where 条件…

kubeadm部署k8s

1.1 安装Docker [rootk8s-all ~]# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo [rootk8s-all ~]# sed -i sdownload.docker.commirrors.huaweicloud.com/docker-ce /etc/yum.repos.d/docker-ce.repo [ro…

数据结构双向链表和循环链表

目录 一、循环链表二、双向链表三、循环双向链表 一、循环链表 循环链表就是首尾相接的的链表&#xff0c;就是尾节点的指针域指向头节点使整个链表形成一个循环&#xff0c;这就弥补了以前单链表无法在后面某个节点找到前面的节点&#xff0c;可以从任意一个节点找到目标节点…

用HTML5+CSS+JavaScript庆祝国庆

用HTML5CSSJavaScript庆祝国庆 中华人民共和国的国庆日是每年的10月1日。 1949年10月1日&#xff0c;中华人民共和国中央人民政府成立&#xff0c;在首都北京天安门广场举行了开国大典&#xff0c;中央人民政府主席毛泽东庄严宣告中华人民共和国成立&#xff0c;并亲手升起了…

[单master节点k8s部署]31.ceph分布式存储(二)

Ceph配置 Ceph集群通常是一个独立的存储集群&#xff0c;可以部署在 Kubernetes 集群之外。Ceph 提供分布式存储服务&#xff0c;能够通过 RADOS、CephFS、RBD&#xff08;块存储&#xff09;、和 RGW&#xff08;对象存储&#xff09;等方式与 Kubernetes 集成。即使 Ceph 部…

王者农药更新版

一、启动文件配置 二、GPIO使用 2.1基本步骤 1.配置GPIO&#xff0c;所以RCC开启APB2时钟 2.GPIO初始化&#xff08;结构体&#xff09; 3.给GPIO引脚设置高/低电平&#xff08;WriteBit&#xff09; 2.2Led循环点亮&#xff08;GPIO输出&#xff09; 1.RCC开启APB2时钟。…

CSS | 响应式布局之媒体查询(media-query)详解

media type(媒体类型)是CSS 2中的一个非常有用的属性&#xff0c;通过media type我们可以对不同的设备指定特定的样式&#xff0c;从而实现更丰富的界面。media query(媒体查询)是对media type的一种增强&#xff0c;是CSS 3的重要内容之一。随着移动互联网的发展&#xff0c;m…

如何在算家云搭建CosyVoice(文生音频)

一、CosyVoice简介 CosyVoice 是一个开源的超强 TTS&#xff08;‌文本转语音&#xff09;‌模型&#xff0c;‌它支持多种生成模式&#xff0c;‌具有极强的语音自然可控性。‌ 具有以下特点&#xff1a; 语音合成 &#xff1a;能够将文本转换为自然流畅的语音输出。多语种…

CSS 盒子属性

1. 盒子模型组成 1.1 边框属性 1.1.1 四边分开写 1.1.2 合并线框 1.1.3 边框影响盒子大小 1.2 内边距 注意&#xff1a; 1.3 外边距 1.3.1 嵌套块元素垂直外边距的塌陷 1.4 清除内外边距 1.5 总结

k8s-集群部署1

k8s-集群部署1 一、基础环境准备二、docker环境准备三、k8s集群部署1.kubeadm创建集群2.使用kubeadm引导集群 总结 一、基础环境准备 首先&#xff0c;需要准备三个服务器实例&#xff0c;这里我使用了阿里云创建了三个实例&#xff0c;如果不想花钱&#xff0c;也可以在VM上创…

多输入多输出预测 | NGO-BP北方苍鹰算法优化BP神经网络多输入多输出预测(Matlab)

多输入多输出预测 | NGO-BP北方苍鹰算法优化BP神经网络多输入多输出预测&#xff08;Matlab&#xff09; 目录 多输入多输出预测 | NGO-BP北方苍鹰算法优化BP神经网络多输入多输出预测&#xff08;Matlab&#xff09;预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介…

SCUC博客摘录「 储能参与电能市场联合出清:SCUC和SCED模型应用于辅助服务调频市场(IEEE39节点系统)」2024年10月6日

2.1 SCUC模型在本方法中&#xff0c;首先利用SCUC模型确定机组出力计划和储能充放电计划。SCUC模型是电力系统经济调度的重要工具&#xff0c;通过优化发电机组出力计划和调度&#xff0c;实现电力系统的经济性和可靠性。在考虑储能的情况下&#xff0c;SCUC模型需要考虑储能的…

一个真实可用的登录界面!

需要工具&#xff1a; MySQL数据库、vscode上的php插件PHP Server等 项目结构&#xff1a; login | --backend | --database.sql |--login.php |--welcome.php |--index.html |--script.js |--style.css 项目开展 index.html&#xff1a; 首先需要一个静态网页&#x…

机器学习(5):机器学习项目步骤(二)——收集数据与预处理

1. 数据收集与预处理的任务&#xff1f; 为机器学习模型提供好的“燃料” 2. 数据收集与预处理的分步骤&#xff1f; 收集数据-->数据可视化-->数据清洗-->特征工程-->构建特征集和数据集-->拆分数据集、验证集和测试集 3. 数据可视化工作&#xff1f; a. 作用&…

基于SpringBoot+Vue的在线投票系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

JDBC 概述

JDBC 概述 JDBC的基本概念与功能JDBC的工作原理JDBC的组件与类JDBC的类型与特性JDBC的应用场景 JDBC&#xff08;Java Database Connectivity&#xff09;即Java数据库连接&#xff0c;是Java编程语言用于与数据库进行连接和操作的API&#xff08;应用程序编程接口&#xff09;…

C++面试速通宝典——7

150. 数据库连接池的作用 数据库连接池的作用包括以下几个方面&#xff1a; 资源重用&#xff1a;连接池允许多个客户端共享有限的数据库连接&#xff0c;减少频繁创建和销毁连接的开销&#xff0c;从而提高资源的利用率。 统一的连接管理&#xff1a;连接池集中管理数据库连…

python交互式命令时如何清除

在交互模式中使用Python&#xff0c;如果要清屏&#xff0c;可以import os&#xff0c;通过os.system()来调用系统命令clear或者cls来实现清屏。 [python] view plain copy print? >>> import os >>> os.system(clear) 但是此时shell中的状态是&#xff1a;…

Java 面向对象设计一口气讲完![]~( ̄▽ ̄)~*(上)

目录 Java 类实例 Java面向对象设计 - Java类实例 null引用类型 访问类的字段的点表示法 字段的默认初始化 Java 访问级别 Java面向对象设计 - Java访问级别 Java 导入 Java面向对象设计 - Java导入 单类型导入声明 按需导入声明 静态导入声明 例子 Java 方法 J…