STM32中的DMA控制器的使用

想学习单片机的同学可以关注、私信我或者在评论区回复我要入门。对于大容量的STM32芯片有2个DMA控制器,其中一个控制器有7个通道,另一个控制器2有5个通道

通道的配置过程:

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

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

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

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

2.设置数据传输方向,是否循环模式,是不是开启外设和存储器的增量模式,还有数据宽度,是8位,16位还是32位。比如设置成存储器的地址增量,那么传输一个数据过去后它的地址自动递增。

3.设置要传输的数据量

4.设置通道的优先级

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

启动后数据就开始传输,传输的过程中可以读CNDTRx寄存器,这个寄存器是告诉我们还有多少个数据需要传输。数据传输到一半或全部传输完毕后有响应的标志位置1,如果开启了中断,可以进入相应的中断程序。

一。常用的DMA函数

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功能。

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

三。DMA初始化函数

对应下面的代码学习:

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配置的一般过程

五。实验

使用串口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_CHx

void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx);//使能DMA1_CHx

#endif

dma.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,不能自动换行,可以换其他串口助手观察。

本期先分享到这里,想要进群学习单片机编程的同学可以私信我,回复“我要入门”,与我们一起成长,喜欢的可以点个赞关注我们!

STM32中的DMA控制器的使用相关推荐

  1. STM32学习笔记——DMA控制器(向原子哥学习)

    一.DMA简介 DMA,全称为:Direct Memory Access,即直接存储器访问,DMA 用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输.当 CPU 初始化这个传输动作,传输 ...

  2. dpdk报文收发流程--理解dma控制器、UIO驱动、描述符空间、mbuf空间、KNI

    1. dpdk报文收发流程 1.1 报文接收流程 传统方式接收报文时,当网卡接收到报文后会产生硬件中断,进而报文会通过协议栈,最后到达应用层,这个过程需要内核协议栈的处理. 和传统报文接收不同,当应用 ...

  3. 7.STM32中对DMA_Config()函数的理解(自定义)测试DMA传输数据时CPU还可继续工作其他的事

    STM32中对DMA_Config()函数的理解(自定义):

  4. 关于RS485通讯中使用STM32串口以DMA方式发送数据丢失字节的问题

    1.开发平台 计算机操作系统:WIN7 64位: 开发环境:Keil MDK 5.14: MCU:STM32F407ZET6: STM32F4xx固件库:STM32F4xx_DSP_StdPeriph ...

  5. STM32单片机实现DMA+ADC+UART功能

    突然想测试一下STM32单片机ADC采样速率问题,按照常规方法,可以通过ADC采样,然后将采样值打印出来.但是这种方法在处理和打印数据的时候会占用很多时间,导致处理数据的时间超过了ADC的采样时间.于 ...

  6. 嵌入式作业STM32采用串口DMA方式发送数据

    目录 前言 要求 一.DMA的基本介绍 DMA的基本定义 DMA的主要特征 STM32F411x系列芯片DMA控制器 二.通过CubeMX配置项目 1.创建项目 2.选择芯片STM32F103C8T6 ...

  7. STM32采用串口DMA方式实现发送数据

    文章目录 一.实验工具 二.DMA介绍 三.配置工程 1.新建工程 2.引脚配置 3.设置RCC 4.设置串口 5.DMA设置 6.时钟源设置 7.项目文件设置 8.创建代码 四.Keil中修改代码 ...

  8. 【嵌入式基础】STM32中断及DMA通信原理编程

    本文主要学习stm32中断.DMA通信原理和编程方法.使用stm32tubemx和HAL库分别完成中断模式编程和串口通信中断实验. 目录 一.STM32中断,DMA通信原理编程 1.STM32中断 ( ...

  9. STM32中断与DMA通信编程

    文章目录 一.中断与DMA通信原理 1.中断 2.DMA通信原理 二.中断控制LED灯点亮熄灭 1.新建工程 2.配置外部中断 3.配置中断优先级 4.完成创建 5.编写中断函数 6.程序烧录 7.运 ...

  10. STM32中的通信协议

    STM32中的通信协议 通讯协议是指在嵌入式开发中,不同的硬件系统或者操作系统之间进行数据交换的方式,是一种数据通讯的规约. 通讯协议有很多种,而我今天要说的是串口通讯协议,而且是基于STM32来说的 ...

最新文章

  1. 云计算重构渠道商的价值基础,推动渠道商向服务商转型
  2. mysql 3.6.4_TOMCAT5+MYSQL5+JIRA3.6.4配置说明
  3. SpringBoot: SpringBoot里面创建导出Excel的接口(亲测)
  4. 重大福利!优云UEM重磅上线!
  5. 聊聊六位半万用表电路(一)——保护
  6. 《软件管理沉思录》读书笔记
  7. Weka下载安装详解
  8. zscore标准化步骤_几种常用数据标准化方法
  9. 【微信小程序】协同工作和发布 数据绑定
  10. BZOJ_4199_[Noi2015]品酒大会_后缀自动机
  11. 蘑菇街服务器信息,蘑菇街开放平台
  12. JavaScript根据用户输入动态计算周数
  13. python脚本案例-python+adb命令实现自动刷视频脚本案例
  14. html转pdf页面缩小,缩小HTML页面并转换为A4尺寸pdf
  15. E12:后台管理系统开发-修改文章功能
  16. stm32 u8g2移植笔记
  17. 安卓8.X解包打包工具和教程,windows平台一键打包解包工具
  18. Kafka集群搭建实战
  19. 宁高宁:五个环节让你看懂中国企业
  20. 211已经毕业工作一年了,腾讯试水一面连环50问,瞬间傻眼了,太难了。

热门文章

  1. ipod nano7安装linux,怎么用ipod nano看视频?
  2. ArcGIS Server 基于Token密匙
  3. 《巴菲特致股东的信》十年期固定行使价格期权对公司的侵蚀-计算过程演示
  4. 使用 ONLYOFFICE 宏监测空气质量数据
  5. Toast调整显示位置
  6. 奥克兰大学计算机专业好找工作吗,留学选择奥克兰大学的计算机专业肯定不会后悔...
  7. 使用ROS提取udacity .bag文件中的压缩图片
  8. 昭通脱贫致富-农业大健康·林裕豪:从玉农业谋定“责任”
  9. python幂次_python n次幂
  10. Godaddy网站SSL证书安装