STM32——DMA实验

main.c

/*********************************************************
**  FileName: 		  DMA传输速度比较
**  Description: 
分别使用CPU和DMA传输数据,对其计时,使用串口返回时间,对时间进行比较。
 
**  Author:		      老猫
**  Date:   		  2019/10/7
**  Others:	  
*********************************************************/
#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "stdio.h"
#include "string.h"
#define BufferSize 32
vu16 CurrDataCounter=0;
vu32 Tick=0;
uc32 SRC_Const_Buffer[BufferSize ] = 
{
    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
};
u32 DST_Buffer[BufferSize];
void RCC_Configuration(void);
void NVIC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void DMA_Configuration(void);
void Systick_Configuration(void);
int main (void){//主程序
	u8 i=0;
	u8 TickCntCPU=0;
	u8 TickCntDMA=0;
	RCC_Configuration(); //时钟设置
	NVIC_Configuration();
	GPIO_Configuration();
	USART_Configuration();
	DMA_Configuration();
  Systick_Configuration();
	
	//使用CPU搬运并计时
	Tick=0;
	for(i=0;i<BufferSize;i++)
	{
		DST_Buffer[i]=SRC_Const_Buffer[i];
	}
	TickCntCPU=Tick;
	for(i=0;i<BufferSize;i++)
	{
		DST_Buffer[i]=0;
	}
	//使用DMA搬运并计时
	Tick=0;
	DMA_Cmd(DMA1_Channel6,ENABLE);
	while(CurrDataCounter!=0);
	TickCntDMA=Tick;
	//实验结果
	if(strncmp((const char *)SRC_Const_Buffer,(const char *)DST_Buffer,BufferSize)==0)
	{
		printf("\r\nTransmit Success!\r\n");
	}
	else 
	{
		printf("\r\nTransmit Fault!\r\n");
	}
    printf("\r\nThe CPU transfer, time consume: %dus!\n\r", TickCntCPU);
    printf("\r\nThe DMA transfer, time consume: %dus!\n\r", TickCntDMA);
	while(1);
}
void GPIO_Configuration(void)
{
    /* 定义 GPIO 初始化结构体 GPIO_InitStructure */
    GPIO_InitTypeDef GPIO_InitStructure;   
    /* 设置 USART1 的Tx脚(PA.9)为第二功能推挽输出功能 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA , &GPIO_InitStructure);    
    /* 设置 USART1 的Rx脚(PA.10)为浮空输入脚 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA , &GPIO_InitStructure);
}

void NVIC_Configuration(void)
{
    /* 定义NVIC初始化结构体 NVIC_InitStructure */
    NVIC_InitTypeDef NVIC_InitStructure; 
    /* #ifdef...#else...#endif结构的作用是根据预编译条件决定中断向量表起始地址*/   
#ifdef  VECT_TAB_RAM  
    /*中断向量表起始地址从 0x20000000 开始*/
    NVIC_SetVectorTable(NVIC_VectTab_RAM , 0x0); 
#else /* VECT_TAB_FLASH */
    /* 中断向量表起始地址从 0x80000000 开始 */ 
    NVIC_SetVectorTable(NVIC_VectTab_FLASH , 0x0);   
#endif
    /* 选择优先级分组0  */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);	
    
    /* 开启DMA16通道中断控制,0级先占优先级,0级次占优先级*/
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
void DMA_Configuration(void)
{
	  DMA_InitTypeDef DMA_InitStructure;
    DMA_DeInit(DMA1_Channel6);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_Const_Buffer;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DST_Buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = BufferSize;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_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_Channel6, &DMA_InitStructure);
    DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
    CurrDataCounter= DMA_GetCurrDataCounter(DMA1_Channel6);
}
void Systick_Configuration(void)
{
  	/* 主频为72MHz,配置计数值除以1000可以得到1us定时间隔 */
 	SysTick_Config(SystemCoreClock / 1000000); 
}
void USART_Configuration(void)
{
    /* 定义 USART 初始化结构体 USART_InitStructure */
    USART_InitTypeDef USART_InitStructure;
    
    /*	
    *	波特率为115200bps;
    *	8位数据长度;
    *	1个停止位,无校验;
    *	禁用硬件流控制;
    *	禁止USART时钟;
    *	时钟极性低;
    *	在第2个边沿捕获数据
    *	最后一位数据的时钟脉冲不从 SCLK 输出; 
    */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No ;
    USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1 , &USART_InitStructure);   
    /* 使能 USART1 */
    USART_Cmd(USART1 , ENABLE);
}

/******************************************************************************
* 函数名  		: fputc
* 函数描述    	: 将printf函数重定位到USATR1
* 输入参数    	: 无
* 输出结果    	: 无
* 返回值			: 无
******************************************************************************/
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (u8) ch);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    return ch;
}

在SYS.C中
开启DMA USART1 和GPIOA时钟
stm32f10x_it.c

#include "stm32f10x_it.h"
extern vu16 CurrDataCounter;
extern vu32 Tick;
void SysTick_Handler(void)
{
	Tick++;
}
void DMA1_Channel6_IRQHandler(void)
{
	  CurrDataCounter= DMA_GetCurrDataCounter(DMA1_Channel6);
    DMA_ClearITPendingBit(DMA1_IT_GL6);	
}

结果
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王蒟蒻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值