打印

STM32H7的SDIO中断实现方式比较特殊,需要在中断里面调用阻塞函数Wait_SDCARD_Ready查询

[复制链接]
438|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
还是DMA方式更加实用。

官方对此有配套一个例子:SD_ReadWrite_IT



实现的测试代码:

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define DATA_SIZE              ((uint32_t)0x06400000U) /* Data Size 100Mo */

/* ------ Buffer Size ------ */
#define BUFFER_SIZE            ((uint32_t)0x00040000U) /* 256Ko */

#define NB_BUFFER              DATA_SIZE / BUFFER_SIZE
#define NB_BLOCK_BUFFER        BUFFER_SIZE / BLOCKSIZE /* Number of Block (512o) by Buffer */
#define BUFFER_WORD_SIZE       (BUFFER_SIZE>>2)        /* Buffer size in Word */


#define SD_TIMEOUT             ((uint32_t)0x00100000U)
#define ADDRESS                ((uint32_t)0x00000400U) /* SD Address to write/read data */
#define DATA_PATTERN           ((uint32_t)0xB5F3A5F3U) /* Data pattern to write */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
SD_HandleTypeDef SDHandle;
__IO uint8_t RxCplt, TxCplt;

/******** SD Transmission Buffer definition *******/
#if defined ( __ICCARM__ )
#pragma location = 0x24000000
#elif defined ( __CC_ARM )
__attribute__((section (".RAM_D1")))
#elif defined ( __GNUC__ )
__attribute__((section (".RAM_D1")))
#endif
uint8_t aTxBuffer[BUFFER_WORD_SIZE*4];
/**************************************************/

/******** SD Receive Buffer definition *******/
#if defined ( __ICCARM__ )
#pragma location = 0x24040000
#elif defined ( __CC_ARM )
__attribute__((section (".RAM_D1")))
#elif defined ( __GNUC__ )
__attribute__((section (".RAM_D1")))
#endif
uint8_t aRxBuffer[BUFFER_WORD_SIZE*4];
/**************************************************/
/* UART handler declaration, used for printf */
UART_HandleTypeDef UartHandle;

__IO uint8_t step = 0;
uint32_t start_time = 0;
uint32_t stop_time = 0;

/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Error_Handler(void);
static void CPU_CACHE_Enable(void);
static void UART_Config(void);
static uint8_t Wait_SDCARD_Ready(void);

#ifdef __GNUC__ /* __GNUC__ */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */


/* Private functions ---------------------------------------------------------*/
void Fill_Buffer(uint32_t *pBuffer, uint16_t BufferLength, uint32_t Offset);

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  uint32_t index = 0;

  /* Enable the CPU Cache */
  CPU_CACHE_Enable();
  HAL_SD_CardCIDTypedef pCID;
  HAL_SD_CardCSDTypedef pCSD;

  /* STM32H7xx HAL library initialization:
       - Configure the Systick to generate an interrupt each 1 msec
       - Set NVIC Group Priority to 4
       - Low Level Initialization
     */
  HAL_Init();

  /* Configure the system clock to 400 MHz */
  SystemClock_Config();

  /*##-1- Initialize LEDs mounted on STM32H743I-EVAL board #####################*/
  BSP_LED_Init(LED_GREEN);
  BSP_LED_Init(LED_ORANGE);
  BSP_LED_Init(LED_RED);
  
  /*##-2- Configure USART for printf messages #####################*/
  UART_Config();
  
  /*##-2- Initialize IO functionalities (MFX) #####################*/
  BSP_IO_Init();
  
  /* Initialise Transciver MFXPIN to enable 1.8V Switch mode */
  BSP_IO_ConfigPin(SD_LDO_SEL_PIN, IO_MODE_OUTPUT_PP_PU);
  
  /*##-3- Initialize SD instance #####################*/
  SDHandle.Instance = SDMMC1;
  HAL_SD_DeInit(&SDHandle);
   
  /* SDMMC IP clock 200Mhz, SDCard clock 100Mhz  */
  SDHandle.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
  SDHandle.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  SDHandle.Init.BusWide             = SDMMC_BUS_WIDE_4B;
  SDHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  SDHandle.Init.ClockDiv            = 1;
  
  if(HAL_SD_Init(&SDHandle) != HAL_OK)
  {
    Error_Handler();
  }
  
  if(HAL_SD_Erase(&SDHandle, ADDRESS, ADDRESS+BUFFERSIZE) != HAL_OK)
  {
    Error_Handler();
  }
  if(Wait_SDCARD_Ready() != HAL_OK)
  {
    Error_Handler();
  }
  
  HAL_SD_GetCardCID(&SDHandle, &pCID);
  HAL_SD_GetCardCSD(&SDHandle, &pCSD);
  
  while(1)
  {
    switch(step)
    {
      case 0:
      {
        /*##- 4 - Initialize Transmission buffer #####################*/
        for (index = 0; index < BUFFERSIZE; index++)
        {
          aTxBuffer[index] = DATA_PATTERN + index;
        }
        printf(" ****************** Start Write test *******************
");
        printf(" - Buffer size to write: %lu MB   
", (DATA_SIZE>>20));
        index = 0;
        start_time = HAL_GetTick();
        step++;
      }
      break;
      case 1:
      {
        TxCplt = 0;
        /*##- 5 - Start Transmission buffer #####################*/
        if(HAL_SD_WriteBlocks_IT(&SDHandle, aTxBuffer, ADDRESS, NB_BLOCK_BUFFER) != HAL_OK)
        {
          Error_Handler();
        }
        step++;
      }
      break;
      case 2:
      {
        if(TxCplt != 0)
        {
          /* Toogle Led Orange, Transfer of Buffer OK */
          BSP_LED_Toggle(LED_ORANGE);
         
          /* Transfer of Buffer completed */
          index++;
          if(index<NB_BUFFER)
          {
            /* More data need to be trasnfered */
            step--;
          }
          else
          {
            stop_time = HAL_GetTick();
            printf(" - Write Time(ms): %lu  -  Write Speed: %02.2f MB/s  
", stop_time - start_time, (float)((float)(DATA_SIZE>>10)/(float)(stop_time - start_time)));
            /* All data are transfered */
            step++;
          }
        }
      }
      break;
      case 3:
      {
        /*##- 6 - Initialize Reception buffer #####################*/
        for (index = 0; index < BUFFERSIZE; index++)
        {
          aRxBuffer[index] = 0;
        }
        printf(" ******************* Start Read test *******************
");
        printf(" - Buffer size to read: %lu MB   
", (DATA_SIZE>>20));
        start_time = HAL_GetTick();
        index = 0;
        step++;
      }
      break;
      case 4:
      {
        /*##- 7 - Initialize Reception buffer #####################*/
        RxCplt = 0;
        if(HAL_SD_ReadBlocks_IT(&SDHandle, aRxBuffer, ADDRESS, NB_BLOCK_BUFFER) != HAL_OK)
        {
          Error_Handler();
        }
        step++;
      }
      break;
      case 5:
      {
        if(RxCplt != 0)
        {
          /* Toogle Led Orange, Transfer of Buffer OK */
          BSP_LED_Toggle(LED_ORANGE);
          /* Transfer of Buffer completed */
          index++;
          if(index<NB_BUFFER)
          {
            /* More data need to be trasnfered */
            step--;
          }
          else
          {
            stop_time = HAL_GetTick();
            printf(" - Read Time(ms): %lu  -  Read Speed: %02.2f MB/s  
", stop_time - start_time, (float)((float)(DATA_SIZE>>10)/(float)(stop_time - start_time)));
            /* All data are transfered */
            step++;
          }
        }
      }
      break;
      case 6:
      {
        /*##- 8 - Check Reception buffer #####################*/
        index=0;
        printf(" ********************* Check data **********************
");
        while((index<BUFFERSIZE) && (aRxBuffer[index] == aTxBuffer[index]))
        {
          index++;
        }
        
        if(index != BUFFERSIZE)
        {
          printf(" - Check data Error !!!!   
");
          Error_Handler();
        }
        printf(" - Check data OK  
");
        /* Toogle Green LED, Check Transfer OK */
        BSP_LED_Toggle(LED_GREEN);
        step = 0;
      }
      break;
      default :
        Error_Handler();
    }
  }
}


/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow :
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 400000000 (CPU Clock)
  *            HCLK(Hz)                       = 200000000 (AXI and AHBs Clock)
  *            AHB Prescaler                  = 2
  *            D1 APB3 Prescaler              = 2 (APB3 Clock  100MHz)
  *            D2 APB1 Prescaler              = 2 (APB1 Clock  100MHz)
  *            D2 APB2 Prescaler              = 2 (APB2 Clock  100MHz)
  *            D3 APB4 Prescaler              = 2 (APB4 Clock  100MHz)
  *            HSE Frequency(Hz)              = 25000000
  *            PLL_M                          = 5
  *            PLL_N                          = 160
  *            PLL_P                          = 2
  *            PLL_Q                          = 4
  *            PLL_R                          = 2
  *            VDD(V)                         = 3.3
  *            Flash Latency(WS)              = 4
  * @param  None
  * @retval None
  */
static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
  HAL_StatusTypeDef ret = HAL_OK;

  /*!< Supply configuration update enable */
  MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0);

  /* The voltage scaling allows optimizing the power consumption when the device is
     clocked below the maximum system frequency, to update the voltage scaling value
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
  RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

  RCC_OscInitStruct.PLL.PLLM = 5;
  RCC_OscInitStruct.PLL.PLLN = 160;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLQ = 4;

  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
  ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
  if(ret != HAL_OK)
  {
    Error_Handler();
  }
  
/* Select PLL as system clock source and configure  bus clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 |
                                  RCC_CLOCKTYPE_PCLK2  | RCC_CLOCKTYPE_D3PCLK1);
  
  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;
  ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
  if(ret != HAL_OK)
  {
    Error_Handler();
  }

  
  /*activate CSI clock mondatory for I/O Compensation Cell*/  
  __HAL_RCC_CSI_ENABLE() ;
   
  /* Enable SYSCFG clock mondatory for I/O Compensation Cell */
  __HAL_RCC_SYSCFG_CLK_ENABLE() ;
  
  /* Enables the I/O Compensation Cell */   
  HAL_EnableCompensationCell();
}

/**
  * @brief  Enable the SD Transciver 1.8V Mode Callback.
  * @param  None
  * @retval None
  */
void HAL_SD_DriveTransciver_1_8V_Callback(FlagStatus status)
{
  if(status == SET)
  {
    BSP_IO_WritePin(IO_PIN_13, BSP_IO_PIN_SET);  
  }
  else
  {
    BSP_IO_WritePin(IO_PIN_13, BSP_IO_PIN_RESET);
  }
}

/**
  * @brief Rx Transfer completed callbacks
  * @param hsd: SD handle
  * @retval None
  */
void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
{
  if(Wait_SDCARD_Ready() != HAL_OK)
  {
    Error_Handler();
  }
  RxCplt=1;
}

/**
  * @brief Tx Transfer completed callbacks
  * @param hsd: SD handle
  * @retval None
  */
void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
{
  if(Wait_SDCARD_Ready() != HAL_OK)
  {
    Error_Handler();
  }
  TxCplt=1;
}

/**
  * @brief SD error callbacks
  * @param hsd: SD handle
  * @retval None
  */
void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
{
  Error_Handler();
}

使用特权

评论回复

相关帖子

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

本版积分规则

370

主题

370

帖子

0

粉丝