stm32f407 6个串口dma_stm32之DMA

  一. 对于大容量的STM32芯片有2个DMA控制器,控制器1有7个通道,控制器2有5个通道

  每个通道都可以配置一些外设的地址。

v2-02ece89d98e790c7c4facd29ae8ae429_b.jpg

v2-9262545aa85826c0bf448e7fae282b67_b.jpg

  二. 通道的配置过程:

v2-32d1a5fbbb3cfcad9705b3340f09e4a0_b.jpg

  1. 首先设置CPARx寄存器和CMARx寄存器。

  通过DMA控制器把一个地址的值复制到另外一个地址,通过DMA控制器自动开启一条通道完成。

  CPARx寄存器存放的是外设的地址

  CMARx寄存器存储的是存储器的地址

  2. 设置数据传输方向,是否循环模式,是不是开启外设和存储器的增量模式,还有数据宽度,是8位,16位还是32位。

  比如设置成存储器的地址增量,那么传输一个数据过去后它的地址自动递增。

  3. 设置要传输的数据量

  4. 设置通道的优先级

  5. 全部设置好后就可以启动DMA通道。

  启动后数据就开始传输,传输的过程中可以读CNDTRx寄存器,可知道当前还剩多少个数据。数据传输到一半或全部传输完毕后有响应的标志位置1,如果开启了中断,可以进入相应的中断程序。

  一。常用的DMA函数

v2-3eed43dc9c6e359c33c2bb5816b2b165_b.jpg

  1.DMA初始化函数

  void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx); //设置要开启的通道,还有一些参数,包括外设基地址,存储器基地址,传输的数据量,增量模式,数据宽度等。

  2.DMA使能函数

  void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState  NewState);

  3.开启相应中断的函数

  void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT,  FunctionalState NewState);

  4.设置CNDTRx和读CNDTRx函数

  void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t  DataNumber);uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);

  二。常用的外设DMA使能函数

  需要开启外设的DMA使能才能够使用DMA功能。

  这些函数分布在外设各自的头文件中。

v2-94f145e8aceca46c6c191d1b6cb05336_b.jpg

  三。DMA初始化函数

v2-ccf5a23db9cbc9cfcb195d7235929d35_b.jpg

  对应下面的代码学习:

  u16 DMA1_MEM_LEN; //保存DMA每次数据传送的长度//DMA1的各通道配置//这里的传输形式是固定的,这点要根据不同的情况来修改//从存储器->外设模式/8位数据宽度/存储器增量模式//DMA_CHx:DMA通道CHx//cpar:外设地址//cmar:存储器地址//cndtr:数据传输量void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16  cndtr){RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值DMA1_MEM_LEN=cndtr;DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;  //数据宽度为8位DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器}

  四。DMA配置的一般过程

v2-0ecc2dc973bc38df78de0b1ffd121203_b.jpg

  五。实验

  使用串口1发送DMA

  dma.h文件

  #ifndef __DMA_H#define __DMA_H#include "sys.h"void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16  cndtr);//配置DMA1_CHxvoid MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx);//使能DMA1_CHx#endifdma.c文件#include "dma.h"DMA_InitTypeDef DMA_InitStructure;u16 DMA1_MEM_LEN;//保存DMA每次数据传送的长度//DMA1的各通道配置//这里的传输形式是固定的,这点要根据不同的情况来修改//从存储器->外设模式/8位数据宽度/存储器增量模式//DMA_CHx:DMA通道CHx//cpar:外设地址//cmar:存储器地址//cndtr:数据传输量void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16  cndtr){RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输,DMA在AHB总线上DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值DMA1_MEM_LEN=cndtr;DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;  //数据宽度为8位DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道 USART1_Tx_DMA_Channel所标识的寄存器}//开启一次DMA传输void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx){DMA_Cmd(DMA_CHx, DISABLE ); //关闭USART1 TX DMA1 所指示的通道DMA_SetCurrDataCounter(DMA1_Channel4,DMA1_MEM_LEN);//DMA通道的DMA缓存的大小DMA_Cmd(DMA_CHx, ENABLE); //使能USART1 TX DMA1 所指示的通道}

  注:DMA每传输完成一次,要传输的数据量都要自动清零,因此每次开启都要重新设置要传输的数据量。

  主程序中:

  for(i=0;i{if(t>=j)//加入换行符{if(mask){SendBuff[i]=0x0a;t=0;}else{SendBuff[i]=0x0d;mask++;}}else//复制TEXT_TO_SEND语句{mask=0;SendBuff[i]=TEXT_TO_SEND[t];t++;}}

  这一段是 在每个字符串“ALIENTEK WarShip STM32F1 DMA 串口实验”后面添加0x0d和0x0a,也就是自动换行,这样在串口助手中接收到的数据就是ALIENTEK WarShip STM32F1 DMA 串口实验,然后自动换行,另外串口助手sscom程序有bug,不能自动换行,可以换其他串口助手观察。

资料分享便于后期的学习参考

(DMA专题讲解)

stm32 如何用DMA搬运数据

(stm32串口应用)
PWM脉宽调制技术

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

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

相关文章

立足当下,塑造未来

今天,以“5G与世界同行”为主题的2021全球移动宽带论坛(Global MBB Forum)在迪拜举行。期间,华为轮值董事长胡厚崑发表了题为“立足当下,塑造未来”的主题演讲。胡厚崑指出:“5G预商用五年以来,…

jfinal html5,Jfinal框架整合webSocket技术功能实现

技术难度:简单在这里我会用最简单的方法实现JFinal框架结合webSocket最基础的功能,以至于后续业务的拓展需要小伙伴们依据实际情况去实现相应的开发!废话不多说,直接上代码!1、编写webSocket类package morality.ws;imp…

行业实战 | 5G+边缘计算+“自由视角” 让体育赛事更畅快

简介: 世界本是多维的。进入5G时代,观众对多维度视觉体验的需求日益增长,5G MEC网络与边缘计算的结合,具备大带宽、低延迟特性,使视频多维视觉呈现成为现实。在第二十三届CUBA中国大学生篮球联赛期间,中国电…

华为汪涛:走向智能世界2030,无线网络未来十年十大产业趋势

2021全球移动宽带论坛(Global MBB Forum)期间,华为常务董事、ICT基础设施业务管理委员会主任汪涛发表了题为“走向智能世界2030,无线网络未来十年十大趋势”的主题演讲。汪涛表示:“未来十年,是走向智能世界…

python怎么输入一个数字并调用_Python3 实例(一)

原标题:Python3 实例(一) Python Hello World 实例 以下实例为学习Python的第一个实例,即如何输出"Hello World!": 实例 # -*- coding: UTF-8 -*- # Filename : helloworld.py # author by : www.runoob.com…

未来教育计算机书,未来教育.全国计算机等级考试

1册图书1张光盘,轻松应对2018年一级计算机基础及MS Office应用考试 n 1.历年真题精选,全方位把握真考动向,具有练习价值 n (1)新大纲、新题型、新题库,全方位解读无纸化考试,帮助考生轻松过关。 n (2)精选2017年~2016年…

python制作简单网页_python 跑服务器,访问自己制作的简单页面

1 python 跑服务器,访问自己制作的简单页面2 # winb出现一个网址http:/0.0.1:5000/复制到浏览器查看 # http://127.0.0.1:5000/home做这个首先要安装好python的flask,前面有详细的安装步骤 具体代码如下# coding:utf-8 # Flask构造函数,从fla…

华为云专属月·行业深耕专项行动正式开启

10月15日,以“云上共创 互联网新价值”为主题的“华为云专属月行业深耕”线上发布会圆满举办。会上,华为云宣布“华为云专属月行业深耕专项行动”正式启动,本次专属月期间,华为云将面向包括电商、游戏、移动出行三大行业在内的互联…

计算机电子工程专业就业前景,就业前景好的4大类专业,电气电子类上榜,有你喜欢的吗?...

原标题:就业前景好的4大类专业,电气电子类上榜,有你喜欢的吗?行业的发展和社会的发展是紧密相连的,所以为了推动社会各个行业的发展,在大学中就会设立很多类型的专业。下面来介绍一下就业前景好的4大类专业…

Nacos 2.0 性能提升十倍,贡献者 80% 以上来自阿里之外

简介: 3 月 20 日,Nacos 2.0 正式发布。Nacos 是阿里巴巴在 2018 年开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台,也可以理解为微服务的注册中心 配置中心。 来源 | 阿里巴巴云原生公众号 3 月 20 日&#xff0c…

以系统化视角反观产品运营,解读提升用户转化的“四部曲”

简介: 正常的活动运营通常会围绕公司经营目标,针对不同性质、不同类型的活动开展工作。这样的活动一般会分四个阶段:活动准备、活动策划、活动执行与活动复盘阶段。 作者:友盟数据大使 Suffering 如今,移动互联网的红…

移动云亮相 2021 IDC 年度盛典 共话变革与赋能

“过去一年,是考验各行业在面临多重挑战时保持数字弹性能力的一年。未来十年,是数字化转型成为企业主旋律、加速推进的十年。”10月15日,由IDC中国主办的“2021第六届IDC中国数字化转型年度盛典”在上海圆满落幕。盛典以“数字焕颜 科技有型”…

春色满园关不住,带你体验阿里云 Knative

简介: Knative 是基于 Kubernetes 的开源 Serverless 应用编排框架。阿里云 Knative 在社区Knative基础之上,与阿里云产品进行了深度的融合,给你带来最纯粹的容器化 Serverless 体验。 Knative 是基于 Kubernetes 的开源 Serverless 应用编排…

python选择排序算法图解_python基本算法之实现归并排序(Merge sort)

0、前言 评判一个算法的好坏的标准: 时间复杂度 空间复杂度 1、归并排序算法是什么? 冒泡排序(Bubble Sort)是一种建立在归并操作上面的一种有效的排序算法,由John von neumann于1945年发明。采用分治法(Divide and Conquer&#…

从前端智能化看“低代码/无代码”

简介: 什么是低代码/无代码开发?业界对于低代码/无代码开发是否存在其他不同的理解?低代码开发和无代码开发之间的区别是什么? 作者 | 甄子 来源 | 阿里技术公众号 一 概念 1 什么是低代码/无代码开发?业界对于低代码…

初二物理模型有哪些_暑假新初二、新初三的数学该怎么学,教辅怎么买,题该怎么刷?看这里~...

这个暑假对于新初二和新初三的孩子都非常关键,因为下一学期的数学难度都要上升一个台阶,自古相传一句老话“初二两极分化,初三天上地下”,其实引起这么大化学反应的原因就是在于数学和科学这两门理科在八上和九上有了一个质变。我…

低代码会让程序员更加内卷吗?

作者| Mr.K 编辑| Emma来源| 技术领导力(ID:jishulingdaoli)今天的主题呢主要是来源于最近的一个很火的话题——『低代码』。低代码会不会让程序员更加内卷?要回答这个问题,需要先弄清楚:低代码适合做什么,不适合做什…

技术干货 | 应用上线前的“体检”,你知道需要检测哪些指标吗?

简介: 应用上线前检测哪些项目?如何检测?检测数据指标包括哪些? 随着越来越多的企业基于 mPaaS 搭建并上线新的 App,App 的上线质量也成为各个客户关注的重点。上线前检测哪些项目?如何检测?检…

python 机器学习_基于 Python 语言的机器学习工具Sklearn

本篇介绍了Sklearn机器学习基础,从Sklearn的简介,模块以及与tensorflow的优劣势对比来了解基于Python语言的机器学习工具。01、Sklearn简介sklearn(scikit-learn)是Python重要的学习库,它封装了机器学习中常用的算法,包括监督学习…

那些你不知道的TCP冷门知识!

简介: 最近在做数据库相关的事情,碰到了很多TCP相关的问题,新的场景新的挑战,有很多之前并没有掌握透彻的点,大大开了一把眼界,选了几个案例分享一下。 最近在做数据库相关的事情,碰到了很多TC…