STM32_HAL_DMA

发布于:2024-05-31 ⋅ 阅读:(88) ⋅ 点赞:(0)

STM32的存储结构

(图由哔哩哔哩大佬的视频里截的图,如有侵权请联系我)

STM32的DMA(Direct Memory Access,直接存储器访问)

是一种硬件机制,允许在微控制器的外设和存储器之间进行高效的数据传输,而不需要CPU的干预。这种机制可以显著提高数据传输的效率,减轻CPU的负担,从而提高系统的整体性能。

STM32微控制器中的DMA控制器具有以下特点:

  1. 通道数量:STM32的DMA控制器通常有多个通道(例如STM32F4系列有7个通道),每个通道可以独立配置,用于不同外设的数据传输。

  2. 数据传输类型:DMA支持多种数据传输类型,包括字节(8位)、半字(16位)和字(32位)。

  3. 传输模式:DMA支持单次传输模式和循环传输模式。在循环传输模式下,DMA会在完成一次传输后自动重新开始,这对于连续的数据流传输非常有用。

  4. 增量模式:DMA可以配置为增量模式,其中源地址和/或目标地址在每次传输后自动增加,也可以配置为非增量模式,地址保持不变。

  5. 优先级:DMA通道可以配置不同的优先级,以控制通道之间的访问顺序。

  6. 中断和事件:DMA传输可以配置为在传输完成、半传输完成、传输错误等情况时产生中断,以便于软件进行相应的处理。

  7. 数据流控制:DMA可以与各种外设接口,如ADC、DAC、SPI、I2C、UART等,以及内部Flash和SRAM进行数据传输。

在使用STM32的DMA时,通常需要进行以下步骤:

  • 配置DMA通道:设置传输的数据宽度、增量模式、传输模式、优先级等。
  • 设置源地址和目标地址:指定数据传输的起始地址。
  • 设置数据传输量:指定要传输的数据量。
  • 启动DMA传输:配置完成后,启动DMA传输。
  • 处理中断:如果启用了中断,需要在中断服务函数中处理传输完成等事件。

重点

(uint32_t)&变量     可以得出变量的地址         //

变量存储在SRAM中

常量存储在闪存中     //c中  在变量前面加(const)括号内的单词即为常量不可改变的量

STM32cude 设置

关于STM32_DMA_的函数

  1. HAL_DMA_Init: 初始化DMA句柄,配置DMA通道的参数,如方向、增量模式、数据对齐方式、传输模式和优先级等

  2. HAL_DMA_DeInit: 反初始化DMA句柄,将DMA通道的配置恢复到默认状态。

  3. HAL_DMA_Start: 启动DMA传输

  4. HAL_DMA_Start_IT: 启动DMA传输,并启用中断。当DMA传输完成或发生错误时,会产生中断。

  5. HAL_DMA_Stop: 停止DMA传输。

  6. HAL_DMA_Abort: 中止DMA传输

  7. HAL_DMA_PollForTransfer: 轮询DMA传输完成状态。

  8. HAL_DMA_GetState: 获取DMA传输的状态。

  9. HAL_DMA_GetError: 获取DMA传输的错误码。

  10. HAL_DMA_IRQHandler: DMA中断处理函数。在这个函数中,你需要根据DMA中断状态来处理传输完成、半传输完成、传输错误等情况。

  11. HAL_DMA_RegisterCallback: 注册DMA回调函数,以便在DMA传输完成或发生错误时调用。

  12. HAL_DMA_UnRegisterCallback: 注销DMA回调函数。

main.h源码

将数组的值写到另一个数组中在打印

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
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();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
//定义数组
uint32_t srcArray[10]={1,2,3,4,5,6,7,8,9,10};//源数据
uint32_t decArray[10];//要写入的地方
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		//开启DMA  1:DMA指针 2:源地址 3:写入的地址 4:长度
		HAL_DMA_Start(&hdma_memtomem_dma1_channel1,(uint32_t)srcArray,(uint32_t)decArray,10);
		//重点HAL_DMA_PollForTransfer不然数据会错   HAL_DMA_FULL_TRANSFER表示传输完成  HAL_MAX_DELAY无限时间
		if (HAL_DMA_PollForTransfer(&hdma_memtomem_dma1_channel1, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY) == HAL_OK)
    {
        // 存储数据
        char data_char[48];
        // 转换类型
        sprintf(data_char, "数据为: %d  %d  %d  %d  %d  %d  %d  %d  %d  %d",
                decArray[0], decArray[1], decArray[2], decArray[3], decArray[4], decArray[5], decArray[6], decArray[7], decArray[8], decArray[9]);
        // 打印数据
        HAL_UART_Transmit(&huart1, (uint8_t*)data_char, 47, 30);
    }
		for(int i=0;i<10;i++){
			srcArray[i]=srcArray[i]+1;
		}
		HAL_Delay(3000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */


网站公告

今日签到

点亮在社区的每一天
去签到