一、编程要点
1、初始化DMA结构体
数据从哪里来到哪里去
传输数目 传输单位
什么时候传输结束
2、清楚相应标志位
3、DMA传输使能
二、结构体&库函数
1、DMA_InitTypeDef
DMA_ InitTypeDef 初始化结构体
typedef struct
{
uint32_t DMA_PeripheralBaseAddr; // 外设地址
uint32_t DMA_MemoryBaseAddr; // 存储器地址
uint32_t DMA_DIR; // 传输方向
// 数据从哪里来到哪里去
uint32_t DMA_BufferSize; // 传输数目
uint32_t DMA_PeripheralInc; // 外设地址增量模式
uint32_t DMA_MemoryInc; // 存储器地址增量模式
uint32_t DMA_PeripheralDataSize; // 外设数据宽度
uint32_t DMA_MemoryDataSize; // 存储器数据宽度
//传输数目 传输单位
uint32_t DMA_Mode; // 模式选择
uint32_t DMA_Priority; // 通道优先级
uint32_t DMA_M2M; // 存储器到存储器模式
} DMA_InitTypeDef;
2、DMA标志位清楚函数
DMA_ClearFlag(uint32_t DMAy_FLAG)
DMA_ClearFlag(DMA1_FLAG_TC2)
@brief 清楚相应DMAx通道相应标志位
@param1:DMA标志位
DMA_FLAG | 描述 |
DMA_FLAG_GL1 | 通道 1 全局标志位 |
DMA_FLAG_TC1 | 通道 1 传输完成标志位 |
DMA_FLAG_HT1 | 通道 1 传输过半标志位 |
DMA_FLAG_TE1 | 通道 1 传输错误标志位 |
3、检测传输是否完成
FlagStatus DMA_GetFlagStatus(u32 DMA_FLAG)
while(DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET)//等待数据传输完成
@brief 检测DMAx通道相应标志位
@param1:待检查的DMA标志位
三、程序源码
1、dma_mtm.c文件
#include "dma_mtm.h"
//填充储存器地址
const uint32_t aSRC_Const_Buffer[32]=
{ 0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40,
0x41424344,0x45464748,0x494A4B4C,0x4D4E4F50,
0x51525354,0x55565758,0x595A5B5C,0x5D5E5F60,
0x61626364,0x65666768,0x696A6B6C,0x6D6E6F70,
0x71727374,0x75767778,0x797A7B7C,0x7D7E7F80
};
uint32_t aDST_Buffer[32];
void DMA_mtm_Config(void)
{
DMA_InitTypeDef DMA_InitStructure; //定义结构体
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //开启DMA时钟
//决定数据从哪里来到哪里去
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)aSRC_Const_Buffer; //外设地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)aDST_Buffer; //储存器地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传输方向
//数据要传多少,传的单位是什么
DMA_InitStructure.DMA_BufferSize = 32; //传输数目
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; //外设地址递增模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //储存器地址递增模式
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //外设数据宽度
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //储存器数据宽度
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ; //传输模式是否循环
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //通道优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; //储存器到储存器模式
DMA_Init(DMA1_Channel2, &DMA_InitStructure); //调用库函数将值写入
DMA_ClearFlag(DMA1_FLAG_TC2); //清楚标志位
DMA_Cmd(DMA1_Channel2, ENABLE); //DMA使能
}
uint32_t DMA_MTM_compare(void) //数据对比函数
{
uint32_t i,x=0,y=0;
for(i=0;i<32;i++) //32个数据依次对比
{
if(aSRC_Const_Buffer[x]==aDST_Buffer[y])
x++,y++;
else
return 0; //有不相同数据 返回0
}
return 1; //对比完全 返回1
}
2、
dma_mtm.h文件
#ifndef __DMA_MTM_H
#define __DMA_MTM_H
#include "stm32f10x.h"
void DMA_mtm_Config(void);
uint32_t DMA_MTM_compare(void);
#endif //__DMA_MTM_H
3、main.c文件
#include "stm32f10x.h" // 相当于51单片机中的 #include <reg51.h>
#include "bsp_led.h"
#include "dma_mtm.h"
extern const uint32_t aSRC_Const_Buffer[32]; //声明外部文件变量
extern uint32_t aDST_Buffer[32];
void Delay (uint32_t i)
{
while(i--);
}
int main(void)
{
// 来到这里的时候,系统的时钟已经被配置成72M。
LED_GPIO_Config();
LDE_blue();
Delay (0xffffff);
DMA_mtm_Config(); //DMA初始化
while(DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET);//等待数据传输完成
if(DMA_MTM_compare()==1)
{
LDE_gerren(); //数据对比正确蓝灯亮
}
else
LDE_red(); //数据对比出错 红灯亮
while(1);
}
DMA通道