HAL库—SDIO读取SD卡

1. SDIO相关HAL库驱动

驱动函数

关联寄存器

功能描述

__HAL_RCC_SDIO_CLK_ENABLE

AHBENR/APB2ENR

SDIO时钟使能

HAL_SD_Init

SDIO_CLKCR/CMD/ARG/RESP

初始化SD卡

HAL_SD_MspInit

初始化回调函数

初始化SDIO的底层硬件

HAL_SD_ConfigWideBusOperation

SDIO_CLKCR/CMD/ARG/RESP

配置总线宽度

HAL_SD_ReadBlocks

SDIO_DCTRL/CMD/ARG/RES

读取块数据

HAL_SD_WriterBlocks

SDIO_DCTRL/CMD/ARG/RES

写入块数据

用于发送SDIO_SendCommand函数,用于接收响应SDIO_GetResponse

HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, 	/* 句柄结构体指针变量 */
								      uint8_t *pData,			/* 接收数据的缓冲地址 */
								      uint32_t BlockAdd,		/* 要读取的扇区地址 */
								      uint32_t NumberOfBlocks,/* 要读取的扇区数 */
								      uint32_t Timeout		/* 传输过程超时时间 */
HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd ,	/* 句柄结构体指针变量 */
								      uint8_t *pData,			/* 写入数据的缓冲地址 */ 
								      uint32_t BlockAdd, 		/* 要写入的扇区地址 */
								      uint32_t NumberOfBlocks,/* 要写入的扇区数 */
								       uint32_t Timeout		/* 传输过程超时时间 */

2. SDIO相关结构体

SD_HandleTypeDef(SD_InitTypeDef) //外设相关结构体

SDIO_CmdInitTypeDef //命令相关结构体

SDIO_DataInitTypeDef //数据相关结构体

HAL_SD_CardInfoTypeDef //卡信息相关结构体

{
  SD_TypeDef                   *Instance;        /*!< SD registers base address           */
  
  SD_InitTypeDef               Init;             /*!< SD required parameters              */
  
  HAL_LockTypeDef              Lock;             /*!< SD locking object                   */
  
  uint8_t                      *pTxBuffPtr;      /*!< Pointer to SD Tx transfer Buffer    */

  uint32_t                     TxXferSize;       /*!< SD Tx Transfer size                 */

  uint8_t                      *pRxBuffPtr;      /*!< Pointer to SD Rx transfer Buffer    */

  uint32_t                     RxXferSize;       /*!< SD Rx Transfer size                 */
  
  __IO uint32_t                Context;          /*!< SD transfer context                 */
 
  __IO HAL_SD_StateTypeDef     State;            /*!< SD card State                       */
  
  __IO uint32_t                ErrorCode;        /*!< SD Card Error codes                 */  
 
  DMA_HandleTypeDef            *hdmatx;          /*!< SD Tx DMA handle parameters         */

  DMA_HandleTypeDef            *hdmarx;          /*!< SD Rx DMA handle parameters         */
  
  HAL_SD_CardInfoTypeDef       SdCard;           /*!< SD Card information                 */
  
  uint32_t                     CSD[4];           /*!< SD card specific data table         */
  
  uint32_t                     CID[4];           /*!< SD card identification number table */
  
}SD_HandleTypeDef;
typedef struct
{
  uint32_t ClockEdge;            /*!< 数据或指令变化的时钟沿
                                     通常上升沿*/

  uint32_t ClockBypass;          /*!< 是否设置旁路分频器
                                      enabled or disabled.
                                      不使用旁路分频*/

  uint32_t ClockPowerSave;       /*!< 空闲状态是否输出时钟
                                      disabled when the bus is idle.
                                      默认disable*/

  uint32_t BusWide;              /*!< 设置SDIO总线位宽
                                      1B or 4B*/

  uint32_t HardwareFlowControl;  /*!< 用于使能硬件流控制
                                     enable 避免常见的上溢和下溢*/

  uint32_t ClockDiv;             /*!< 设置SDIO时钟分频
                                      Min_Data = 0 and Max_Data = 255 */  
  
}SDIO_InitTypeDef;

attention:SDIO初始化最大时钟频率:400KHz

SDIO数据传输最大时钟频率:25HMz

typedef struct                                                                                            
{
  uint32_t Argument;            /*!< 命令参数 */

  uint32_t CmdIndex;            /*!< 命令索引 */

  uint32_t Response;            /*!< 响应类型:
                                   无响应	长响应	短响应                 
                                    */

  uint32_t WaitForInterrupt;    /*!<等待中断请求
                                    等待类型选择,三种状态
                                    通常无等待
                                    无等待,使用超时检测	等待中断  等待传输完成
                                    SDIO_WAIT_NO	SDIO_WAIT_IT	SDIO_WAIT_PEND*/

  uint32_t CPSM;                /*!< 是否使用命令通道状态机
                                    enabled 通常使能.
                                */
}SDIO_CmdInitTypeDef;
typedef struct
{
  uint32_t DataTimeOut;         /*!< 数据超时时间*/

  uint32_t DataLength;          /*!< 数据长度
                                    数据块长度*多少个块(5个)
                                                */
 
  uint32_t DataBlockSize;       /*!< 数据块大小
                                     512B*/
 
  uint32_t TransferDir;         /*!< 传输方向(读/写)
                                     TO_CAAD 写	
                                     */
 
  uint32_t TransferMode;        /*!< 传输模式(块/流)
                                     SD卡使用块 MMC卡使用数据流类型
                                  */
 
  uint32_t DPSM;                /*!< 是否使用数据通道状态机
                                enabled
                                 */
}SDIO_DataInitTypeDef;

SDIO_DataInitTypeDef关联的函数SDIO_ConfigData,发送/接收数据块会使用到。

attention:SD卡操作使用数据块类型,MMC卡才是用数据流类型

typedef struct
{
  uint32_t CardType;                     /*!<卡类型*/
  
  uint32_t CardVersion;                  /*!<卡版本*/

  uint32_t Class;                        /*!<卡类型*/

  uint32_t RelCardAdd;                   /*!<卡相对位置*/
  
  uint32_t BlockNbr;                     /*!<整张卡的块数*/

  uint32_t BlockSize;                    /*!<每个块的字节数*/
  
  uint32_t LogBlockNbr;                  /*!<每张卡的逻辑块数*/

  uint32_t LogBlockSize;                 /*!<逻辑块大小*/

}HAL_SD_CardInfoTypeDef;	//与SD卡的CSD寄存器相关(通过长响应获得)

3. HAL库初始化流程

通过HAL_SD_GetCardInfo函数获取卡信息

  1. 初始化GPIO功能,SDIO时钟不超过400KHz
  2. 初始化SDIO外设接口(默认配置)
  3. 开启SDIO电源,为卡提供时钟,并延时两毫秒
  4. 发送CMD0复位命令,让卡到空闲状态
  5. 发送CMD8主机支持电压,并询问卡是否支持
  6. 根据响应判断SD卡版本
  7. 反复发送ACMD41,等待OCR回应,卡上电完成和卡容量类型
  8. 检查电源状态,进入准备状态
  9. 发送CMD2,获得卡信息(CID)
  10. 发送CMD3,获得卡的相对地址(RCA)
  11. 发送CMD9,获得卡的数据(CSD)
  12. 发送CMD7,选择卡,切换到传输状态

4. Cube配置

5. 补写函数

#include "bsp_sd.h"
#include "sdio.h"

//显示SD卡信息函数
void Show_SDMMC_Info(void){
  HAL_SD_CardCIDTypeDef SDCard_CID;
  HAL_SD_CardInfoTypeDef SDCard_INFO;
  uint64_t CardCap;           //SD卡容量
  HAL_SD_GetCardCID(&hsd,&SDCard_CID);  //获取CID
  HAL_SD_GetCardInfo(&hsd,&SDCard_INFO);  //获取SD卡信息
  switch(SDCard_INFO.CardType)      //SD卡类型
  {
    case CARD_SDSC:
      if(SDCard_INFO.CardVersion == CARD_V1_X){
        printf("Card Type: SDSC V1\r\n");
      }
      else if(SDCard_INFO.CardVersion == CARD_V2_X){
        printf("Card Type: SDSC V2\r\n");
      }
      break;
    case CARD_SDHC_SDXC:
      printf("Card Type: SDHC\r\n");
      break;
  }

  CardCap = (uint64_t)(SDCard_INFO.LogBlockNbr)*(uint64_t)(SDCard_INFO.LogBlockSize)/1024/1024; //计算SD卡容量
  printf("Card ManufacturerID:%d\r\n",SDCard_CID.ManufacturerID); //制造商ID
  printf("Card RCA:%d\r\n",SDCard_INFO.RelCardAdd);   //卡相对地址
  printf("LogBlockNbr:%d\r\n",SDCard_INFO.LogBlockNbr); //逻辑块数量
  printf("LogBlockSize:%d\r\n",SDCard_INFO.LogBlockSize); //逻辑块大小
  printf("Card Capacity:%d MB\r\n",(uint32_t)CardCap);  //显示容量
  printf("Card BlockSize:%d\r\n",SDCard_INFO.BlockSize);  //块大小
}

uint8_t bsp_sd_rease(void)
{
	 if(HAL_SD_Erase(&hsd,0,1) == HAL_OK){
        while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER);
        printf("\r\nErase Block Success!\r\n");
   }
	 return 0;
}

uint8_t Buffer_Tx[512],Buffer_Rx[512] = {0};

uint8_t bsp_sd_readblocks(void)
{
  if(HAL_SD_ReadBlocks(&hsd,Buffer_Rx,0,1,0xffffffff) == HAL_OK){
          while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER);
          printf("\r\nRead Block Success!\r\n");
          for(int i=0;i<sizeof(Buffer_Rx);i++)
            printf("%02x ",Buffer_Rx[i]);
          printf("\r\n");
  }else{
     printf("\r\nWrite Block Failed!\r\n");
  }
  return 0;
}


uint8_t bsp_sd_writeblocks(void)
{
	 memset(Buffer_Tx,0x15,sizeof(Buffer_Tx)); 
  if(HAL_SD_WriteBlocks(&hsd,Buffer_Tx,0,1,0xffffffff) == HAL_OK){
        while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER);
        printf("\r\nWrite Block Success!\r\n");
        for(int i=0;i<sizeof(Buffer_Tx);i++)
          printf("0x%02x:%02x ",i,Buffer_Tx[i]);
        printf("\r\n");
      }else{
        printf("\r\nWrite Block Failed!\r\n");
      }
	return 0;
}

SD卡HAL库驱动文件:stm32f1xx_hal_sd.c和stm32f1xx_ll_sdmmc.c 

6. 工程源码

通过百度网盘分享的文件:SD_Test.rar

链接:百度网盘 请输入提取码

提取码:xaod

--来自百度网盘超级会员V6的分享

参考链接:

【STM32+HAL】利用SDIO将大量数据存入SD卡,并根据需要读出_stm32f407 sdio-CSDN博客

https://blog.51cto.com/u_15467009/4876827

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值