硬汉嵌入式论坛

 找回密码
 立即注册
查看: 791|回复: 9
收起左侧

[SD/SDIO] STM32H750VBT6 SD卡 DMA读写BUG

[复制链接]

5

主题

16

回帖

31

积分

新手上路

积分
31
发表于 2025-3-6 16:48:03 | 显示全部楼层 |阅读模式
使用CUBEMX生成STM32H750VBT6工程,使用了USART2 作为串口输出,使用SDMMC1读写SD卡



使用轮询模式的时候,串口可以正常输出数据,
[C] 纯文本查看 复制代码
  for(int i = 0; i < 512; i++)
  {
    wBuff[i] = 0xAA;
  }

  if( HAL_SD_WriteBlocks(&hsd1, wBuff, 0X0, 1, 0Xffff)){
    while (1);
  }


  if( HAL_SD_ReadBlocks(&hsd1, rBuff, 0X0, 1, 0Xffff)){
    while (1);
  }



但是使用DMA模式的时候出现了读出来的数据为0x00的bug,
[C] 纯文本查看 复制代码
  for(int i = 0; i < 512; i++)
  {
    wBuff[i] = 0xAA;
  }
  
  if( HAL_SD_WriteBlocks_DMA(&hsd1, wBuff, 0X0, 1)){
    while (1);
  }
  
  while(HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER);

  if( HAL_SD_ReadBlocks_DMA(&hsd1, rBuff, 0X0, 1) != HAL_OK){
    while (1);
  }


请问有人遇到过这样的问题吗?
回复

使用道具 举报

1

主题

5

回帖

8

积分

新手上路

积分
8
发表于 2025-3-6 17:40:52 | 显示全部楼层
读之前清cache  SCB_CleanDCache()
回复

使用道具 举报

5

主题

16

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2025-3-6 17:48:13 | 显示全部楼层
本帖最后由 ylun 于 2025-3-6 19:22 编辑

[C] 纯文本查看 复制代码
  char message[] = "Hello World!\n";

  for (int i = 0; i < 512; i++)
  {
    wBuff[i] = 0xAA;
  }


  while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER);
  if (HAL_SD_WriteBlocks_DMA(&hsd1, wBuff, 0X0, 1))
  {
    while (1);
  }
  //检测发送完成标志是否被置位
  while(TxcpIt != 1);
  TxcpIt = 0;

  while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER);
  if (HAL_SD_ReadBlocks_DMA(&hsd1, rBuff, 0X0, 1) != HAL_OK)[/i]
[i]
  {
    while (1);
  }
  while(RxcpIt != 1);
  RxcpIt = 0;


[C] 纯文本查看 复制代码
/* USER CODE BEGIN 4 */
// 当SD卡写完成时,调用此函数
void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
{
  TxcpIt = 1;
}
// 当SD卡读完成时,调用此函数
void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
{
  RxcpIt = 1;
}
// 当SD卡出现错误时,调用此函数
void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
{
  Errorf = 1;
}
// 当SD卡中断时,调用此函数
void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
{
  Abortf = 1;
}

/* USER CODE END 4 */

目前加上这两段可以正常读写,有没有人解释一下为什么会出现这种情况?


回复

使用道具 举报

5

主题

16

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2025-3-6 19:20:58 | 显示全部楼层
liozhu 发表于 2025-3-6 17:40
读之前清cache  SCB_CleanDCache()

好像不行,没有报错,但是直接进这个函数里面了
[C] 纯文本查看 复制代码
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-3-7 06:39:40 | 显示全部楼层
ylun 发表于 2025-3-6 19:20
好像不行,没有报错,但是直接进这个函数里面了
[mw_shl_code=c,true]void HardFault_Handler(void)
{
...

方便的话,贴个稍完整的代码看下。
回复

使用道具 举报

5

主题

16

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2025-3-7 09:06:05 | 显示全部楼层
eric2013 发表于 2025-3-7 06:39
方便的话,贴个稍完整的代码看下。

[C] 纯文本查看 复制代码
/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2025 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"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* 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 ---------------------------------------------------------*/

SD_HandleTypeDef hsd1;

UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MPU_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDMMC1_SD_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t rBuff[512];
uint8_t wBuff[512];
volatile uint8_t RxcpIt; // 接收完成标志
volatile uint8_t TxcpIt; // 发送完成标志
volatile uint8_t Errorf; // 错误标志
volatile uint8_t Abortf; // 中断标志

/* USER CODE END 0 */

/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* 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_SDMMC1_SD_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  char message[] = "Hello World!\n";

  for (int i = 0; i < 512; i++)
  {
    wBuff[i] = 0xAA;
  }


  while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER);
  if (HAL_SD_WriteBlocks_DMA(&hsd1, wBuff, 0X0, 1))
  {
    while (1);
  }
  //检测发送完成标志是否被置位
  while(TxcpIt != 1);
  TxcpIt = 0;

  while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER);
  if (HAL_SD_ReadBlocks_DMA(&hsd1, rBuff, 0X0, 1) != HAL_OK)
  {
    while (1);
  }
  while(RxcpIt != 1);
  RxcpIt = 0;
  // if( HAL_SD_ReadBlocks(&hsd1, rBuff, 0X0, 1, 0Xffff)){
  //   while (1);
  // }
  // for(int i = 0; i < 512; i++)
  // {
  //   wBuff[i] = 0xAA;
  // }

  // if( HAL_SD_WriteBlocks(&hsd1, wBuff, 0X0, 1, 0Xffff)){
  //   while (1);
  // }

  // if( HAL_SD_ReadBlocks(&hsd1, rBuff, 0X0, 1, 0Xffff)){
  //   while (1);
  // }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    HAL_UART_Transmit(&huart2, rBuff, 512, HAL_MAX_DELAY);
    HAL_Delay(1000);
    HAL_UART_Transmit(&huart2, (uint8_t *)message, sizeof(message), HAL_MAX_DELAY);
    HAL_Delay(1000);
    // HAL_UART_Transmit(&huart2, cBuff, 512, HAL_MAX_DELAY);
    // HAL_Delay(1000);
    /* 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};

  /** Supply configuration update enable
   */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

  /** Configure the main internal regulator output voltage
   */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

  while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY))
  {
  }

  /** Initializes the RCC Oscillators according to the specified parameters
   * in the RCC_OscInitTypeDef structure.
   */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 60;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  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_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

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

/**
 * @brief SDMMC1 Initialization Function
 * @param None
 * @retval None
 */
static void MX_SDMMC1_SD_Init(void)
{

  /* USER CODE BEGIN SDMMC1_Init 0 */

  /* USER CODE END SDMMC1_Init 0 */

  /* USER CODE BEGIN SDMMC1_Init 1 */

  /* USER CODE END SDMMC1_Init 1 */
  hsd1.Instance = SDMMC1;
  hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
  hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd1.Init.ClockDiv = 5;
  if (HAL_SD_Init(&hsd1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SDMMC1_Init 2 */

  /* USER CODE END SDMMC1_Init 2 */
}

/**
 * @brief USART2 Initialization Function
 * @param None
 * @retval None
 */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */
}

/**
 * @brief GPIO Initialization Function
 * @param None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
  /* USER CODE BEGIN MX_GPIO_Init_1 */

  /* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /* USER CODE BEGIN MX_GPIO_Init_2 */

  /* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */
// 当SD卡写完成时,调用此函数
void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
{
  TxcpIt = 1;
}
// 当SD卡读完成时,调用此函数
void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
{
  RxcpIt = 1;
}
// 当SD卡出现错误时,调用此函数
void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
{
  Errorf = 1;
}
// 当SD卡中断时,调用此函数
void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
{
  Abortf = 1;
}

/* USER CODE END 4 */

/* MPU Configuration */

void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};

  /* Disables the MPU */
  HAL_MPU_Disable();

  /** Initializes and configures the Region and the memory to be protected
   */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x0;
  MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
  MPU_InitStruct.SubRegionDisable = 0x87;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

/**
 * @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 */






目前这段代码是能进行DMA读取的。然后如果不加这段代码
[C] 纯文本查看 复制代码
  //检测发送完成标志是否被置位
  while(TxcpIt != 1);
  TxcpIt = 0;
就不能成功读取。


然后如果加上 SCB_CleanDCache();不知道是不是我加的方式有问题,代码如下:
[C] 纯文本查看 复制代码
/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2025 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"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* 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 ---------------------------------------------------------*/

SD_HandleTypeDef hsd1;

UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MPU_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDMMC1_SD_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t rBuff[512];
uint8_t wBuff[512];
volatile uint8_t RxcpIt; // 接收完成标志
volatile uint8_t TxcpIt; // 发送完成标志
volatile uint8_t Errorf; // 错误标志
volatile uint8_t Abortf; // 中断标志

/* USER CODE END 0 */

/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* 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_SDMMC1_SD_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  char message[] = "Hello World!\n";

  for (int i = 0; i < 512; i++)
  {
    wBuff[i] = 0xA0;
  }


  while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER);
  if (HAL_SD_WriteBlocks_DMA(&hsd1, wBuff, 0X0, 1))
  {
    while (1);
  }

  SCB_CleanDCache();


  //检测发送完成标志是否被置位
  // while(TxcpIt != 1);
  // TxcpIt = 0;

  while (HAL_SD_GetCardState(&hsd1) != HAL_SD_CARD_TRANSFER);
  if (HAL_SD_ReadBlocks_DMA(&hsd1, rBuff, 0X0, 1) != HAL_OK)
  {
    while (1);
  }
  // while(RxcpIt != 1);
  // RxcpIt = 0;


  
  // if( HAL_SD_ReadBlocks(&hsd1, rBuff, 0X0, 1, 0Xffff)){
  //   while (1);
  // }
  // for(int i = 0; i < 512; i++)
  // {
  //   wBuff[i] = 0xAA;
  // }

  // if( HAL_SD_WriteBlocks(&hsd1, wBuff, 0X0, 1, 0Xffff)){
  //   while (1);
  // }

  // if( HAL_SD_ReadBlocks(&hsd1, rBuff, 0X0, 1, 0Xffff)){
  //   while (1);
  // }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    HAL_UART_Transmit(&huart2, rBuff, 512, HAL_MAX_DELAY);
    HAL_Delay(1000);
    HAL_UART_Transmit(&huart2, (uint8_t *)message, sizeof(message), HAL_MAX_DELAY);
    HAL_Delay(1000);
    // HAL_UART_Transmit(&huart2, cBuff, 512, HAL_MAX_DELAY);
    // HAL_Delay(1000);
    /* 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};

  /** Supply configuration update enable
   */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

  /** Configure the main internal regulator output voltage
   */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

  while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY))
  {
  }

  /** Initializes the RCC Oscillators according to the specified parameters
   * in the RCC_OscInitTypeDef structure.
   */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 60;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  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_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

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

/**
 * @brief SDMMC1 Initialization Function
 * @param None
 * @retval None
 */
static void MX_SDMMC1_SD_Init(void)
{

  /* USER CODE BEGIN SDMMC1_Init 0 */

  /* USER CODE END SDMMC1_Init 0 */

  /* USER CODE BEGIN SDMMC1_Init 1 */

  /* USER CODE END SDMMC1_Init 1 */
  hsd1.Instance = SDMMC1;
  hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
  hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd1.Init.ClockDiv = 5;
  if (HAL_SD_Init(&hsd1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SDMMC1_Init 2 */

  /* USER CODE END SDMMC1_Init 2 */
}

/**
 * @brief USART2 Initialization Function
 * @param None
 * @retval None
 */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */
}

/**
 * @brief GPIO Initialization Function
 * @param None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
  /* USER CODE BEGIN MX_GPIO_Init_1 */

  /* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /* USER CODE BEGIN MX_GPIO_Init_2 */

  /* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */
// 当SD卡写完成时,调用此函数
void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
{
  TxcpIt = 1;
}
// 当SD卡读完成时,调用此函数
void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
{
  RxcpIt = 1;
}
// 当SD卡出现错误时,调用此函数
void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
{
  Errorf = 1;
}
// 当SD卡中断时,调用此函数
void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
{
  Abortf = 1;
}

/* USER CODE END 4 */

/* MPU Configuration */

void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};

  /* Disables the MPU */
  HAL_MPU_Disable();

  /** Initializes and configures the Region and the memory to be protected
   */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x0;
  MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
  MPU_InitStruct.SubRegionDisable = 0x87;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

/**
 * @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 */

串口就不会发送消息了,然后调试模式显示进入stm32h7xx_it.c中的
[C] 纯文本查看 复制代码
/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

我的理解就是,SCB_CleanDCache();执行出错了。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-3-8 08:34:34 | 显示全部楼层
ylun 发表于 2025-3-7 09:06
[mw_shl_code=c,true]/* USER CODE BEGIN Header */
/**
****************************************** ...

看了你的代码,才搞清楚你的问题。

看下你的缓冲地址是不是被安排到0x2000 0000的DTCM空间了,这个空间不支持SDMMC1的DMA。
回复

使用道具 举报

5

主题

16

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2025-3-8 12:35:47 | 显示全部楼层
eric2013 发表于 2025-3-8 08:34
看了你的代码,才搞清楚你的问题。

看下你的缓冲地址是不是被安排到0x2000 0000的DTCM空间了,这个空 ...

感谢回复,不知道你说的缓冲地址是不是这个Memory 1的地址,Memory 1的地址如图所示。
好像并不是因为被安排到DTCM空间的问题。

另外,我通过在读取函数后面加上一个1s的延时啊,rBuff的内容就正常了。


您在我的另外一篇帖子回复我:
中断函数和DMA函数是非阻塞方式的,将数据丢到缓冲里面,此函数就立即返回了。
下次启动传输前,一定要判断上次完成。

是不是因为这个原因呢?
Memory1.png
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-3-9 09:29:12 | 显示全部楼层
ylun 发表于 2025-3-8 12:35
感谢回复,不知道你说的缓冲地址是不是这个Memory 1的地址,Memory 1的地址如图所示。
好像并不是因为被 ...

对,要保证上次传输完毕才可以开启新的传输。
回复

使用道具 举报

5

主题

16

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2025-3-9 11:55:57 | 显示全部楼层
eric2013 发表于 2025-3-9 09:29
对,要保证上次传输完毕才可以开启新的传输。

谢谢大佬
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-13 05:47 , Processed in 0.050574 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表