打印
[其他ST产品]

stm32cube中文教程:stm32cube中使用DMA配置方法和例子

[复制链接]
383|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
麻花油条|  楼主 | 2022-12-7 09:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本实验只是独立测试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 /

使用特权

评论回复
沙发
MessageRing| | 2022-12-7 15:53 | 只看该作者
优先级可以不分配吗?

使用特权

评论回复
板凳
Uriah| | 2024-10-16 07:31 | 只看该作者

环氧树脂由于硬度的原因不能用于应力敏感和含有贴片元件的模块灌封,在模块电源中基本被淘汰

使用特权

评论回复
地板
帛灿灿| | 2024-10-16 09:27 | 只看该作者

产生一个充电放电的过程

使用特权

评论回复
5
Bblythe| | 2024-10-16 10:30 | 只看该作者

齐纳二极管作为ESD保护与单向TVS原理相同

使用特权

评论回复
6
周半梅| | 2024-10-16 12:26 | 只看该作者

之所以称为ESD静电保护器

使用特权

评论回复
7
Pulitzer| | 2024-10-16 13:29 | 只看该作者

钳位二极管最常用于集成电路中

使用特权

评论回复
8
童雨竹| | 2024-10-16 15:25 | 只看该作者

它迅速由高阻态变为低阻态

使用特权

评论回复
9
Wordsworth| | 2024-10-16 16:28 | 只看该作者

减少反射,避免振荡,方便调试

使用特权

评论回复
10
Clyde011| | 2024-10-16 17:31 | 只看该作者

大于1的定义为极高导热的性能,而对于模块电源此水平的导热系数是无法达到其散热功能的需求

使用特权

评论回复
11
公羊子丹| | 2024-10-16 18:24 | 只看该作者

得到正常工作状态下的输出电压和电流。

使用特权

评论回复
12
万图| | 2024-10-16 19:27 | 只看该作者

在电路中有部分电子元器件比较“脆弱”

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

278

主题

1439

帖子

2

粉丝