【STM32】标准库-SDIO-SDHC

移植官方文件

en.stsw-stm32065_v1-9-0\STM32F4xx_DSP_StdPeriph_Lib_V1.9.0\Utilities\STM32_EVAL\STM324x9I_EVAL
我们需要 stm324x9i_eval_sdio_sd.c 和 stm324x9i_eval_sdio_sd.h 两个文件的完整内容。另外还需要 stm324x9i_eval.c 和 stm324x9i_eval.h 两个文件的部分代码内容
在这里插入图片描述

GPIO 初始化和 DMA 配置这部分代码从 stm324x9i_eval.c 和 stm324x9i_eval.h 两个文件中移植而来。移植到 stm324x9i_eval_sdio_sd.c 中


/* start: 自定义配置 */
/* start: 从 stm324x9i_eval.h 文件拷贝移植的代码 */
/** @addtogroup STM324x9I_EVAL_LOW_LEVEL_SD_FLASH
  * @{
  */
/**
  * @brief  SD FLASH SDIO Interface
  */

#define SDIO_FIFO_ADDRESS                ((uint32_t)0x40012C80)
/**
  * @brief  SDIO Intialization Frequency (400KHz max)
  */
#define SDIO_INIT_CLK_DIV                ((uint8_t)0x76)
/**
  * @brief  SDIO Data Transfer Frequency (25MHz max)
  */
#define SDIO_TRANSFER_CLK_DIV            ((uint8_t)0x0)
/* SDIO使用的DMA */
#define SD_SDIO_DMA                   DMA2
#define SD_SDIO_DMA_CLK               RCC_AHB1Periph_DMA2
/* SDIO使用的DMA流 */
#define SD_SDIO_DMA_STREAM3	          3

#ifdef SD_SDIO_DMA_STREAM3
    #define SD_SDIO_DMA_STREAM            DMA2_Stream3
    #define SD_SDIO_DMA_CHANNEL           DMA_Channel_4
    #define SD_SDIO_DMA_FLAG_FEIF         DMA_FLAG_FEIF3
    #define SD_SDIO_DMA_FLAG_DMEIF        DMA_FLAG_DMEIF3
    #define SD_SDIO_DMA_FLAG_TEIF         DMA_FLAG_TEIF3
    #define SD_SDIO_DMA_FLAG_HTIF         DMA_FLAG_HTIF3
    #define SD_SDIO_DMA_FLAG_TCIF         DMA_FLAG_TCIF3
    #define SD_SDIO_DMA_IRQn              DMA2_Stream3_IRQn
    #define SD_SDIO_DMA_IRQHANDLER        DMA2_Stream3_IRQHandler
#elif defined SD_SDIO_DMA_STREAM6
    #define SD_SDIO_DMA_STREAM            DMA2_Stream6
    #define SD_SDIO_DMA_CHANNEL           DMA_Channel_4
    #define SD_SDIO_DMA_FLAG_FEIF         DMA_FLAG_FEIF6
    #define SD_SDIO_DMA_FLAG_DMEIF        DMA_FLAG_DMEIF6
    #define SD_SDIO_DMA_FLAG_TEIF         DMA_FLAG_TEIF6
    #define SD_SDIO_DMA_FLAG_HTIF         DMA_FLAG_HTIF6
    #define SD_SDIO_DMA_FLAG_TCIF         DMA_FLAG_TCIF6
    #define SD_SDIO_DMA_IRQn              DMA2_Stream6_IRQn
    #define SD_SDIO_DMA_IRQHANDLER        DMA2_Stream6_IRQHandler
#endif /* SD_SDIO_DMA_STREAM3 */

/**
  * @}
  */
/* end: 从 stm324x9i_eval.h 文件拷贝移植的代码 */
/* end: 自定义配置 */


/* start: 自定义配置 */
/* start: 从 stm324x9i_eval.c 文件拷贝移植的代码 */


/**
  * @brief  DeInitializes the SDIO interface.
  * @param  None
  * @retval None
  */
void SD_LowLevel_DeInit(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    
    /*!< Disable SDIO Clock */
    SDIO_ClockCmd(DISABLE);
    
    /*!< Set Power State to OFF */
    SDIO_SetPowerState(SDIO_PowerState_OFF);
    
    /*!< DeInitializes the SDIO peripheral */
    SDIO_DeInit();
    
    /* Disable the SDIO APB2 Clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, DISABLE);
    
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_MCO);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_MCO);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_MCO);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_MCO);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_MCO);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_MCO);
    
    /* Configure PC.08, PC.09, PC.10, PC.11 pins: D0, D1, D2, D3 pins */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    /* Configure PD.02 CMD line */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    
    /* Configure PC.12 pin: CLK pin */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/**
  * @brief  Initializes the SD Card and put it into StandBy State (Ready for
  *         data transfer).
  * @param  None
  * @retval None
  */
void SD_LowLevel_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    
    /* GPIOC and GPIOD Periph clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);
    
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SDIO);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_SDIO);
    
    /* Configure PC.08, PC.09, PC.10, PC.11 pins: D0, D1, D2, D3 pins */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    /* Configure PD.02 CMD line */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    
    /* Configure PC.12 pin: CLK pin */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    /* Enable the SDIO APB2 Clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE);
    
    /* Enable the DMA2 Clock */
    RCC_AHB1PeriphClockCmd(SD_SDIO_DMA_CLK, ENABLE);
}

/**
  * @brief  Configures the DMA2 Channel4 for SDIO Tx request.
  * @param  BufferSRC: pointer to the source buffer
  * @param  BufferSize: buffer size
  * @retval None
  */
void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize)
{
    DMA_InitTypeDef SDDMA_InitStructure;
    
    DMA_ClearFlag(SD_SDIO_DMA_STREAM, SD_SDIO_DMA_FLAG_FEIF | SD_SDIO_DMA_FLAG_DMEIF | SD_SDIO_DMA_FLAG_TEIF | SD_SDIO_DMA_FLAG_HTIF | SD_SDIO_DMA_FLAG_TCIF);
    
    /* DMA2 Stream3  or Stream6 disable */
    DMA_Cmd(SD_SDIO_DMA_STREAM, DISABLE);
    
    /* DMA2 Stream3  or Stream6 Config */
    DMA_DeInit(SD_SDIO_DMA_STREAM);
    
    SDDMA_InitStructure.DMA_Channel = SD_SDIO_DMA_CHANNEL;
    SDDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;
    SDDMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)BufferSRC;
    SDDMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
    SDDMA_InitStructure.DMA_BufferSize = 1;
    SDDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    SDDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    SDDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    SDDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
    SDDMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    SDDMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    SDDMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
    SDDMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    SDDMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
    SDDMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;
    DMA_Init(SD_SDIO_DMA_STREAM, &SDDMA_InitStructure);
    DMA_ITConfig(SD_SDIO_DMA_STREAM, DMA_IT_TC, ENABLE);
    DMA_FlowControllerConfig(SD_SDIO_DMA_STREAM, DMA_FlowCtrl_Peripheral);
    
    /* DMA2 Stream3  or Stream6 enable */
    DMA_Cmd(SD_SDIO_DMA_STREAM, ENABLE);
    
}

/**
  * @brief  Configures the DMA2 Channel4 for SDIO Rx request.
  * @param  BufferDST: pointer to the destination buffer
  * @param  BufferSize: buffer size
  * @retval None
  */
void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize)
{
    DMA_InitTypeDef SDDMA_InitStructure;
    
    DMA_ClearFlag(SD_SDIO_DMA_STREAM, SD_SDIO_DMA_FLAG_FEIF | SD_SDIO_DMA_FLAG_DMEIF | SD_SDIO_DMA_FLAG_TEIF | SD_SDIO_DMA_FLAG_HTIF | SD_SDIO_DMA_FLAG_TCIF);
    
    /* DMA2 Stream3  or Stream6 disable */
    DMA_Cmd(SD_SDIO_DMA_STREAM, DISABLE);
    
    /* DMA2 Stream3 or Stream6 Config */
    DMA_DeInit(SD_SDIO_DMA_STREAM);
    
    SDDMA_InitStructure.DMA_Channel = SD_SDIO_DMA_CHANNEL;
    SDDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;
    SDDMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)BufferDST;
    SDDMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    SDDMA_InitStructure.DMA_BufferSize = 1;
    SDDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    SDDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    SDDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    SDDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
    SDDMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    SDDMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    SDDMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
    SDDMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    SDDMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
    SDDMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;
    DMA_Init(SD_SDIO_DMA_STREAM, &SDDMA_InitStructure);
    DMA_ITConfig(SD_SDIO_DMA_STREAM, DMA_IT_TC, ENABLE);
    DMA_FlowControllerConfig(SD_SDIO_DMA_STREAM, DMA_FlowCtrl_Peripheral);
    
    /* DMA2 Stream3 or Stream6 enable */
    DMA_Cmd(SD_SDIO_DMA_STREAM, ENABLE);
}

/* end: 从 stm324x9i_eval.c 文件拷贝移植的代码 */

/* end: 自定义配置 */

SD_Init()函数中添加中断使能代码,添加中断服务函数

/**
  * @brief  Initializes the SD Card and put it into StandBy State (Ready for data
  *         transfer).
  * @param  None
  * @retval SD_Error: SD Card Error code.
  */
SD_Error SD_Init(void)
{
    __IO SD_Error errorstatus = SD_OK;
    
    /* start: 自定义配置 */
    /**************配置SDIO中断 DMA中断**********************/
    NVIC_InitTypeDef NVIC_InitStructure = {0};
    
    // SDIO Interrupt ENABLE
    NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    // DMA2 STREAMx Interrupt ENABLE
    NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_Init(&NVIC_InitStructure);
    /**********************************************************/
    /* end: 自定义配置 */
    

SDIO与DMA的中断服务函数

/* start: 自定义配置 */
void SDIO_IRQHandler(void)
{
    SD_ProcessIRQSrc();
}
void SD_SDIO_DMA_IRQHANDLER(void)
{
    SD_ProcessDMAIRQ();
}
/* end: 自定义配置 */

去除SD_Detect()函数中的定义

定义了检测 SD 卡是否正确插入的宏,ST 官方的 SD 卡驱动是以一个输入引脚电平判断 SD
卡是否正确插入,这里我们不使用,把引脚定义去掉 (不然编译出错),保留 SD_PRESENT和 SD_NOT_PRESENT 两个宏定义

/**
 * @brief  Detect if SD card is correctly plugged in the memory slot.
 * @param  None
 * @retval Return if SD is detected or not
 */
uint8_t SD_Detect(void)
{
    __IO uint8_t status = SD_PRESENT;
    
/* start: 自定义配置 */
    //  /*!< Check GPIO to detect SD */
    //  if (IOE16_MonitorIOPin(SD_DETECT_PIN) != IOE16_BitReset)
    //  {
    //    status = SD_NOT_PRESENT;
    //  }
/* end: 自定义配置 */
    return status;
}

是否启动DMA传输数据
在这里插入图片描述

/* 选择/取消选择卡 */
SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16));
   /* 获取SD卡的信息 */
   extern SD_CardInfo SDCardInfo;
   SD_GetCardInfo(&SDCardInfo);
   
   USART1Printf("卡容量: %lluB, %.2fGB\r\n", SDCardInfo.CardCapacity, SDCardInfo.CardCapacity / 1024.0F / 1024 / 1024);
   USART1Printf("CardBlockSize: %llu\r\n", SDCardInfo.CardBlockSize);
   USART1Printf("卡相对地址: %X\r\n", SDCardInfo.RCA);
   USART1Printf("卡类型: %u\r\n", SDCardInfo.CardType);

工程文件下载链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值