❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括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,进行存储器到存储器的数据转运,也就是把一个数组里面的数据,复制到另一个数组里;
程序现象:
OLED显示屏上,
- 第一行是DateA数组,右面是该数组的地址
- 第二行是DataA的数据源,每隔两秒变一次
- 第三行是DataB数组,右边是该数组的地址
- 最后一行是DataB的目的地数据
可以看到,DataA每变一次,Delay一秒后,将数据就转运到了DataB,这个转运过程就是由DMA来完成的;如下图所示:
目标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 headeruint16_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);}
}