一、DMA存储器存取功能
1.1 DMA简介
二、DMA数据转运&AD多通道+DMA
2.1 DMA相关函数介绍
//将DMA恢复成缺省配置
void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx);
//DMA初始化函数
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);
//将DMA初始化函数中的结构体参数初始化
void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct);
——————————————————————————————————————————————————————————————————————————————————————
//DMA使能
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);
//用于开启DMA的中断输出
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);
//给DMA中的传输计数器赋值
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber);
//获取DMA中的传输计数器的值
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);
——————————————————————————————————————————————————————————————————————————————————————
//获取标志位状态
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
//清除标志位状态
void DMA_ClearFlag(uint32_t DMAy_FLAG);
//获取中断状态
ITStatus DMA_GetITStatus(uint32_t DMAy_IT);
//清除中断挂起标志位
void DMA_ClearITPendingBit(uint32_t DMAy_IT);
2.2 DMA数据转运
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_BufferSize = Size; //转运次数
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //选择外设站点是源端还是目的地
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; //选择硬件触发还是软件触发
//存储器站点
DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //地址是否自增
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //设置是否开启重装计数器(重装计数器和软件触发不可同时开启)
//外设站点
DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; //地址是否自增
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //设置通道优先级
DMA_Init(DMA1_Channel1, &DMA_InitStructure); //DMA初始化函数
DMA_Cmd(DMA1_Channel1 ,DISABLE);
}
//设置转运计数器时先关闭DMA
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);
}
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "MyDMA.h"
#include "OLED.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); //显示数组A的首地址
OLED_ShowHexNum(3, 8, (uint32_t)DataB, 8); //显示数组B的首地址
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);
while(1)
{
DataA[0]++;
DataA[1]++;
DataA[2]++;
DataA[3]++;
//转运前的数组A、B
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();
//转运后的数组A、B
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);
}
}