我是靠谱客的博主 怕孤单黄蜂,最近开发中收集的这篇文章主要介绍设计分享 | STM32F103RCT6实现DMA数据转运wechat:嵌入式工程师成长日记具体功能实现STM32F103RCT6原理图器件前后展示图DMA转运前:DMA转运后知识介绍DMA介绍数据选择器仲裁器循环模式和存储器模式DMA寄存器存储器、寄存器地址M2Mconst存储器映像主函数代码(C语言)KEIL5实现WeChat:嵌入式工程师成长日记,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

wechat:嵌入式工程师成长日记

https://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484202&idx=1&sn=d971dc5e34e9dc3365cc3aeae44dac58&chksm=cf430672f8348f644e4a76094b8c27b389f18c2586b020740f9a2c2837aaabe34194b6bb8404&token=1206186946&lang=zh_CN#rdicon-default.png?t=M85Bhttps://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484202&idx=1&sn=d971dc5e34e9dc3365cc3aeae44dac58&chksm=cf430672f8348f644e4a76094b8c27b389f18c2586b020740f9a2c2837aaabe34194b6bb8404&token=1206186946&lang=zh_CN#rd

具体功能实现

打开开关后,OLED屏上显示数组DataA和DataB的数据。DataA是源地址数据,DataB是目的地址数据,将DataA中的数据每隔一秒自增加一然后通过DMA控制器传输至DataB。为了加强效果,DataA中数据自增一后需要间隔一秒才会在DataB数组中的显示

STM32F103RCT6原理图

器件

STM32F103RCT6,OLED屏,四根杜邦线

前后展示图

DMA转运前:

此时是转运前,DataA中的数据自增一,此时还没有开始转运,所以DataB中的数据还是原来的。

DMA转运后

此时是转运后,DataA中的数据已经传给了DataB

知识介绍

DMA介绍

全称是直接存储器存取,用来提供外设和存储器之间或存储器和存储器之间的高速数据传输。它的作用是不需要经过CPU进行数据传输,换句话说就是替CPU分担任务。同时,DMA可以将数据从源地址中的数据转移到目的地址而不经过CPU的干预。

12个独立可配置通道:DMA1(7个通道)和DMA2(5个通道)

最常用的用途:配合ADC的扫描模式,因为ADC有个最大的缺点是数据覆盖,如果不适用DMA则ADC的功能会受到很大的限制

需要配置的内容:方向,传输计数器,选择硬件触发还是软件触发,自动重装器,M2M(是否为存储器到存储器模式),使能开关DMA

数据选择器

数据选择器是经过选择,把多个通道的数据传送到唯一的公共数据通道上去,实现数据选择功能的逻辑电路,有时也叫多路选择器或多路调制器

仲裁器

根据通道的优先级来启动外设/存储器的访问。配置通道的优先级,决定哪个通道先执行,哪个通道后执行

循环模式和存储器模式

循环模式:用于处理循环缓存区和连续的数据传输(如ADC的扫描模式)。当启动扫描模式后,数据传输的数目变为0,将会自动恢复成配置通道时设定的初值,DMA将继续执行操作。

存储器模式:DMA在没有外设请求下,这种操作方式就是存储器到存储器模式。(不能和循环模式同时使用)

DMA寄存器

①DMA中断状态寄存器(DMA_ISR)

②DMA中断标志清除寄存器(DMA_IFCR)

③DMA通道配置寄存器(DMA_CCR)

④DMA通道传输数量寄存器(DMA_CNDTR)

⑤DMA通道外设地址寄存器(DMA_CPAR)

⑥DMA通道存储器地址寄存器(DMA_CMAR)

存储器、寄存器地址

0x08 程序存储器FLASH

0x20 运行内存SRAM

0x40 外设寄存器

0xE0 内核外设寄存器

M2M

全称:memory to memory

模式:存储器到存储器模式

触发方式:软件触发

总线:AHB,所以开启的是AHB总线时钟——RCC_AHBPeriphClockCmd()

const

定义数组可以将数据存储在Flash,将变量变为常量,const定义的变量的值是不允许被更改的

存储器映像

重要:存储器Flash和运行内存SRAM

Flash用来存储C语言编译后的程序代码

SRAM用来存储运行中的临时变量

主函数代码(C语言)KEIL5实现

//main.c

#include "stm32f10x.h"  

#include "Delay.h"

#include "OLED.h"

#include "MyDMA.h"

uint8_t DataA[] = {0x01,0x02,0x03,0x04};//源

uint8_t DataB[]={0,0,0,0};//目的

int main(void)

{

OLED_Init();

MyDMA_Init((uint32_t)DataA,(uint32_t)DataB,4);

OLED_ShowString(1,1,"DataA:");

OLED_ShowString(3,1,"DataB:");

OLED_ShowHexNum(1,8,(uint32_t)DataA,8);

OLED_ShowHexNum(3,8,(uint32_t)DataB,8);

while(1)

{

DataA[0]++;

DataA[1]++;

DataA[2]++;

DataA[3]++;

OLED_ShowHexNum(2,1,DataA[0],2);

OLED_ShowHexNum(2,4,DataA[1],2);

OLED_ShowHexNum(2,7,DataA[2],2);

OLED_ShowHexNum(2,10,DataA[3],2);

OLED_ShowHexNum(4,1,DataB[0],2);

OLED_ShowHexNum(4,4,DataB[1],2);

OLED_ShowHexNum(4,7,DataB[2],2);

OLED_ShowHexNum(4,10,DataB[3],2);

Delay_ms(1000);

MyDMA_Transfer();//开始转换

OLED_ShowHexNum(2,1,DataA[0],2);

OLED_ShowHexNum(2,4,DataA[1],2);

OLED_ShowHexNum(2,7,DataA[2],2);

OLED_ShowHexNum(2,10,DataA[3],2);

OLED_ShowHexNum(4,1,DataB[0],2);

OLED_ShowHexNum(4,4,DataB[1],2);

OLED_ShowHexNum(4,7,DataB[2],2);

OLED_ShowHexNum(4,10,DataB[3],2);

Delay_ms(1000);

}

}

//AD.c

#include "stm32f10x.h"  

uint16_t MyDMA_Size;

void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)

{

MyDMA_Size = Size;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

DMA_InitTypeDef DMA_InitStructure;

DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;

DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_BufferSize = Size;

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;

DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;

DMA_Init(DMA1_Channel1, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel1, DISABLE);

}

void MyDMA_Transfer(void)

{

DMA_Cmd(DMA1_Channel1, DISABLE);

DMA_SetCurrDataCounter(DMA1_Channel1,MyDMA_Size);

DMA_Cmd(DMA1_Channel1, ENABLE);

while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);

DMA_ClearFlag(DMA1_FLAG_TC1);

}

 

WeChat:嵌入式工程师成长日记

https://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484202&idx=1&sn=d971dc5e34e9dc3365cc3aeae44dac58&chksm=cf430672f8348f644e4a76094b8c27b389f18c2586b020740f9a2c2837aaabe34194b6bb8404&token=1206186946&lang=zh_CN#rdicon-default.png?t=M85Bhttps://mp.weixin.qq.com/s?__biz=Mzg4Mzc3NDUxOQ==&mid=2247484202&idx=1&sn=d971dc5e34e9dc3365cc3aeae44dac58&chksm=cf430672f8348f644e4a76094b8c27b389f18c2586b020740f9a2c2837aaabe34194b6bb8404&token=1206186946&lang=zh_CN#rd

最后

以上就是怕孤单黄蜂为你收集整理的设计分享 | STM32F103RCT6实现DMA数据转运wechat:嵌入式工程师成长日记具体功能实现STM32F103RCT6原理图器件前后展示图DMA转运前:DMA转运后知识介绍DMA介绍数据选择器仲裁器循环模式和存储器模式DMA寄存器存储器、寄存器地址M2Mconst存储器映像主函数代码(C语言)KEIL5实现WeChat:嵌入式工程师成长日记的全部内容,希望文章能够帮你解决设计分享 | STM32F103RCT6实现DMA数据转运wechat:嵌入式工程师成长日记具体功能实现STM32F103RCT6原理图器件前后展示图DMA转运前:DMA转运后知识介绍DMA介绍数据选择器仲裁器循环模式和存储器模式DMA寄存器存储器、寄存器地址M2Mconst存储器映像主函数代码(C语言)KEIL5实现WeChat:嵌入式工程师成长日记所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部