本实验只是独立测试DMA的运作,没有实现其他功能,DMA可以添加到UART,I2C等接口的驱动中使用。
程序代码由软件stm32cubemx点击设置自动完成,除了main中添加了数据表,调用了反馈函数,
其他都未曾改动,初步测试DMA可使用。
下面是软件操作:
第一步,配置了高速时钟管脚,点击了PIN的相应脚。
第二步,配置时钟,配置P,M,Q,系统为168M频率。
第三步,点击DMA的配置按钮,选择了DMA2,0通道,M2M模式,高速,data宽度为word
其他未变,选择默认。
第四步,配置NVIC,选择优先级分组3,设置DMA的中断优先级为1,0
滴答时钟的优先级不变。
然后导出了代码,用keil打开。
main文件中,在main()中的 MX_DMA_Init();下面直接添加了代码:
hdma_memtomem_dma2_stream0.XferCpltCallback = TransferCompletecc;
hdma_memtomem_dma2_stream0.XferErrorCallback = TransferErrorcc;
意思是,正常传输的话调用名字为TransferCompletecc的函数,错误传输的话调用TransferErrorcc的函数。
然后继续添加:
if(HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream0, (uint32_t)&aSRC_Const_Buffer, (uint32_t)&aDST_Buffer, BUFFER_SIZE) != HAL_OK)
{
/ Transfer Error /
HAL_GPIO_WritePin (GPIOF,GPIO_PIN_6,GPIO_PIN_SET );
while(1);
}
意思是:开启DMA的全部中断,顺便传输数据,aSRC_Const_Buffer和aDST_Buffer是前面定义的数据表。
注意:外围添加TransferCompletecc的函数和TransferErrorcc的函数
,然后直接编译,烧录,测试通过,观察aSRC_Const_Buffer和aDST_Buffer的数据是否一样,
相同的话说明DMA传输正确。
ok,下面上完整的main文件代码。其他文件自动生成后不需改动。
#include "stm32f4xx_hal.h"
/ Private variables ---------------------------------------------------------/
DMA_HandleTypeDef hdma_memtomem_dma2_stream0;
/ USER CODE BEGIN 0 /
#define BUFFER_SIZE 32
static const uint32_t aSRC_Const_Buffer[BUFFER_SIZE]= {
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};
static uint32_t aDST_Buffer[BUFFER_SIZE];
static void TransferCompletecc(DMA_HandleTypeDef *DmaHandle);
static void TransferErrorcc(DMA_HandleTypeDef *DmaHandle);
/ USER CODE END 0 /
/ Private function prototypes -----------------------------------------------/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
int main(void)
{
/ USER CODE BEGIN 1 /
/ USER CODE END 1 /
/ MCU Configuration----------------------------------------------------------/
/ Reset of all peripherals, Initializes the Flash interface and the Systick. /
HAL_Init();
/ Configure the system clock /
SystemClock_Config();
/ System interrupt init/
/ Sets the priority grouping field /
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_1);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/ Initialize all configured peripherals /
MX_GPIO_Init();
MX_DMA_Init();
/ USER CODE BEGIN 2 /
hdma_memtomem_dma2_stream0.XferCpltCallback = TransferCompletecc;
hdma_memtomem_dma2_stream0.XferErrorCallback = TransferErrorcc;
//if(HAL_DMA_GetState != HAL_OK )
//{ HAL_GPIO_WritePin (GPIOF,GPIO_PIN_6,GPIO_PIN_SET ); while(1); }
if(HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream0, (uint32_t)&aSRC_Const_Buffer, (uint32_t)&aDST_Buffer, BUFFER_SIZE) != HAL_OK)
{
/ Transfer Error /
HAL_GPIO_WritePin (GPIOF,GPIO_PIN_6,GPIO_PIN_SET );
while(1);
}
/ USER CODE END 2 /
/ USER CODE BEGIN 3 /
/ Infinite loop /
while (1)
{
// HAL_GPIO_TogglePin (GPIOF,GPIO_PIN_6 );
// HAL_Delay (1000);
}
/ USER CODE END 3 /
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
/**
* Enable DMA controller clock
* Configure DMA for memory to memory transfers
* hdma_memtomem_dma2_stream0
*/
void MX_DMA_Init(void)
{
/ DMA controller clock enable /
__DMA2_CLK_ENABLE();
/ Configure DMA request hdma_memtomem_dma2_stream0 on DMA2_Stream0 /
hdma_memtomem_dma2_stream0.Instance = DMA2_Stream0;
hdma_memtomem_dma2_stream0.Init.Channel = DMA_CHANNEL_0;
hdma_memtomem_dma2_stream0.Init.Direction = DMA_MEMORY_TO_MEMORY;
hdma_memtomem_dma2_stream0.Init.PeriphInc = DMA_PINC_ENABLE;
hdma_memtomem_dma2_stream0.Init.MemInc = DMA_MINC_ENABLE;
hdma_memtomem_dma2_stream0.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_memtomem_dma2_stream0.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_memtomem_dma2_stream0.Init.Mode = DMA_NORMAL;
hdma_memtomem_dma2_stream0.Init.Priority = DMA_PRIORITY_HIGH;
hdma_memtomem_dma2_stream0.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_memtomem_dma2_stream0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_memtomem_dma2_stream0.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_memtomem_dma2_stream0.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init(&hdma_memtomem_dma2_stream0);
/ DMA interrupt init /
/ Sets the priority grouping field /
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_1);
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/ GPIO Ports Clock Enable /
__GPIOF_CLK_ENABLE();
__GPIOH_CLK_ENABLE();
/Configure GPIO pin : PF6 /
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
}
/ USER CODE BEGIN 4 /
static void TransferCompletecc(DMA_HandleTypeDef *DmaHandle)
{
/ Turn LED1 on: Transfer correct /
while(1){
HAL_GPIO_TogglePin (GPIOF,GPIO_PIN_6 );
HAL_Delay (3000);
}
}
/**
* @brief DMA conversion error callback
* @NOTE This function is executed when the transfer error interrupt
* is generated during DMA transfer
* @retval None
*/
static void TransferErrorcc(DMA_HandleTypeDef *DmaHandle)
{
/ Turn LED2 on: Transfer Error /
while(1){
HAL_GPIO_TogglePin (GPIOF,GPIO_PIN_6 );
HAL_Delay (100);
}
}
/ USER CODE END 4 /
|
|