STM32单片机(八)DMA直接存储器存取----第二节:DMA直接存储器存取练习(DMA数据转运和DMA+AD多通道)

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。
☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋。
专栏目标:实现从零基础入门51单片机和STM32单片机,力求在玩好单片机的同时,能够了解一些计算机的基本概念,了解电路及其元器件的基本理论等。

⭐️ 专栏主要内容: 主要学习STM32单片机的功能、各个模块、单片机的外设、驱动等,最终玩好单片机和单片机的外设,全程手敲代码,实现我们所要实现的功能。
专栏说明 :如果文章知识点有错误的地方,欢迎大家随时在文章下面评论,我会第一时间改正。让我们一起学习,一起进步。
专栏主页:http://t.csdn.cn/HCD8v

本学习过程参考:https://space.bilibili.com/383400717

STM3单片机安装软件、各种资料以及源码的路径:
链接:https://pan.baidu.com/s/1snD0uuTfMhchFqOMWvAiHA?pwd=asdf#list/path=%2F
提取码:asdf

链接里压缩包的解压密码:32

本大节主要学习DMA直接存储器存取的相关知识,包含两小节:
第一小节主要学习DMA直接存储器存取的理论基础知识,第二小节是对第一小节的内容写两个程序进行练习,分别是DMA数据转运和DMA+AD多通道;
最终附上所有的源代码;

本小节是对第一小节DMA直接存储器存取的内容写两个程序进行练习,分别是分别是DMA数据转运和DMA+AD多通道;

文章目录

  • 一、本节目标
    • 目标1:DMA数据转运
    • 目标2:DMA+AD多通道
  • 二、练习1:DMA数据转运
    • 2.1 接线图
    • 2.2 源码
  • 三、练习2:DMA+AD多通道
    • 3.1 接线图
    • 4.2 源码

一、本节目标

目标1:DMA数据转运

使用DMA,进行存储器到存储器的数据转运,也就是把一个数组里面的数据,复制到另一个数组里;

程序现象:
STM32单片机(八)DMA直接存储器存取----第二节:DMA直接存储器存取练习(DMA数据转运和DMA+AD多通道)_第1张图片
OLED显示屏上,

  • 第一行是DateA数组,右面是该数组的地址
  • 第二行是DataA的数据源,每隔两秒变一次
  • 第三行是DataB数组,右边是该数组的地址
  • 最后一行是DataB的目的地数据
    可以看到,DataA每变一次,Delay一秒后,将数据就转运到了DataB,这个转运过程就是由DMA来完成的;如下图所示:
    STM32单片机(八)DMA直接存储器存取----第二节:DMA直接存储器存取练习(DMA数据转运和DMA+AD多通道)_第2张图片

目标2:DMA+AD多通道

本节的现象跟AD那一节AD多通道式一模一样的,也是测量PA0~PA这4个通道的模拟量,只是在STM32端使用了扫描模式,并且加了DMA转运数据;

分别外接光敏电阻、热敏电阻和反射红外模块,把他们的AO、模拟电压输出端,分别接在A1、A2、A3引脚,加上目标1里的电位器,总共4个输出通道;然后测出来的4个AD数据分别显示在显示屏上:在这里插入图片描述

  • AD0表示电位器的AD数据;往左拧减小,往右拧增大;
  • AD1表示光敏电阻的AD数据,遮挡光敏电阻,光线减小,AD值增大;移开,光线增大,AD值减小;
  • AD2表示热敏电阻的AD数据;用手热一下热敏电阻,温度升高,AD值减小;移开,温度降低,AD值增大;
  • AD3表示反射红外传感器;手靠近,有反光,AD值减小;移开,没有反光,AD值增大;

二、练习1:DMA数据转运

2.1 接线图

在这里插入图片描述

  • 使用了4个AD通道,第一个通道还是电位器,接在PA0口,之后上面又接了3个传感器模块,分别是光敏传感器、热敏传感器、反射式红外传感器;他们的VCC和GND都分别接在面包板的正负极;然后AO是模拟量的输出引脚,三个模块的AO分别接在PA1、PA2和PA3口;

2.2 源码

代码路径:

  • STM32入门教程资料\程序源码\STM32Project\8-1 DMA数据转运\User
  • STM32入门教程资料\程序源码\STM32Project\8-1 DMA数据转运\Hardware
  • STM32入门教程资料\程序源码\STM32Project\8-1 DMA数据转运\System
#include "stm32f10x.h"                  // Device header
#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);
	}
}

MyDMA.c

#include "stm32f10x.h"                  // Device header

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);
}

三、练习2:DMA+AD多通道

3.1 接线图

在这里插入图片描述

  • 使用了4个AD通道,第一个通道还是电位器,接在PA0口,之后上面又接了3个传感器模块,分别是光敏传感器、热敏传感器、反射式红外传感器;他们的VCC和GND都分别接在面包板的正负极;然后AO是模拟量的输出引脚,三个模块的AO分别接在PA1、PA2和PA3口;

4.2 源码

代码路径:

  • STM32入门教程资料\程序源码\STM32Project\8-2 DMA+AD多通道\User
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"

int main(void)
{
	OLED_Init();
	AD_Init();
	
	OLED_ShowString(1, 1, "AD0:");
	OLED_ShowString(2, 1, "AD1:");
	OLED_ShowString(3, 1, "AD2:");
	OLED_ShowString(4, 1, "AD3:");
	
	while (1)
	{
		OLED_ShowNum(1, 5, AD_Value[0], 4);
		OLED_ShowNum(2, 5, AD_Value[1], 4);
		OLED_ShowNum(3, 5, AD_Value[2], 4);
		OLED_ShowNum(4, 5, AD_Value[3], 4);
		
		Delay_ms(100);
	}
}

你可能感兴趣的:(单片机,stm32,嵌入式硬件,程序人生)