结构体
标准库函数对 SDIO 外设建立了三个初始化结构体,
- SDIO 初始化结构体 SDIO_InitTypeDef
- SDIO 命令初始化结构体 SDIO_CmdInitTypeDef
- SDIO 数据初始化结构体 SDIO_DataInitTypeDef。
SDIO初始化结构体
typedef struct
{
uint32_t SDIO_ClockEdge; // 时钟沿
uint32_t SDIO_ClockBypass; // 旁路时钟
uint32_t SDIO_ClockPowerSave; // 节能模式
uint32_t SDIO_BusWide; // 数据宽度
uint32_t SDIO_HardwareFlowControl; // 硬件流控制
uint8_t SDIO_ClockDiv; // 时钟分频
} SDIO_InitTypeDef;
SDIO_InitTypeDef成员介绍
- SDIO_ClockEdge:主时钟 SDIOCLK 产生 CLK 引脚时钟有效沿选择,可选上升沿或下降沿,它 设定 SDIO 时钟控制寄存器 (SDIO_CLKCR) 的 NEGEDGE 位的值,一般选择设置为高电平。
- SDIO_ClockBypass:时钟分频旁路使用,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 BYPASS 位。如果使能旁路,SDIOCLK 直接驱动 CLK 线输出时钟;如果禁用,使用 SDIO_CLKCR 寄存器的 CLKDIV 位值分频 SDIOCLK,然后输出到 CLK 线。一般选择禁用时钟分频旁路。
- SDIO_ClockPowerSave:节能模式选择,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 PWRSAV 位的值。如果使能节能模式,CLK 线只有在总线激活时才有时钟输出;如果禁用节能模式, 始终使能 CLK 线输出时钟。
- SDIO_BusWide:数据线宽度选择,可选 1 位数据总线、4 位数据总线或 8 为数据总线,系统默认 使用 1 位数据总线,操作 SD 卡时在数据传输模式下一般选择 4 位数据总线。它设定 SDIO_CLKCR 寄存器的 WIDBUS 位的值。
- SDIO_HardwareFlowControl:硬件流控制选择,可选使能或禁用,它设定 SDIO_CLKCR 寄存 器的 HWFC_EN 位的值。硬件流控制功能可以避免 FIFO 发送上溢和下溢错误。
- SDIO_ClockDiv:时钟分频系数,它设定 SDIO_CLKCR 寄存器的 CLKDIV 位的值,设置 SDIOCLK 与 CLK 线输出时钟分频系数: CLK 线时钟频率 =SDIOCLK/([CLKDIV+2])。
SDIO_InitTypeDef成员可选参数
// @defgroup SDIO_Clock_Edge
#define SDIO_ClockEdge_Rising ((uint32_t)0x00000000)
#define SDIO_ClockEdge_Falling ((uint32_t)0x00002000)
#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_ClockEdge_Rising) || \
((EDGE) == SDIO_ClockEdge_Falling))
// @defgroup SDIO_Clock_Bypass
#define SDIO_ClockBypass_Disable ((uint32_t)0x00000000)
#define SDIO_ClockBypass_Enable ((uint32_t)0x00000400)
#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_ClockBypass_Disable) || \
((BYPASS) == SDIO_ClockBypass_Enable))
// @defgroup SDIO_Clock_Power_Save
#define SDIO_ClockPowerSave_Disable ((uint32_t)0x00000000)
#define SDIO_ClockPowerSave_Enable ((uint32_t)0x00000200)
#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_ClockPowerSave_Disable) || \
((SAVE) == SDIO_ClockPowerSave_Enable))
// @defgroup SDIO_Bus_Wide
#define SDIO_BusWide_1b ((uint32_t)0x00000000)
#define SDIO_BusWide_4b ((uint32_t)0x00000800)
#define SDIO_BusWide_8b ((uint32_t)0x00001000)
#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BusWide_1b) || ((WIDE) == SDIO_BusWide_4b) || \
((WIDE) == SDIO_BusWide_8b))
// @defgroup SDIO_Hardware_Flow_Control
#define SDIO_HardwareFlowControl_Disable ((uint32_t)0x00000000)
#define SDIO_HardwareFlowControl_Enable ((uint32_t)0x00004000)
#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HardwareFlowControl_Disable) || \
((CONTROL) == SDIO_HardwareFlowControl_Enable))
// @defgroup SDIO_Clock_Div;
/* This parameter can be a value between 0x00 and 0xFF. */
SDIO命令初始化结构体
typedef struct
{
uint32_t SDIO_Argument; // 命令参数
uint32_t SDIO_CmdIndex; // 命令号
uint32_t SDIO_Response; // 响应类型
uint32_t SDIO_Wait; // 等待使能
uint32_t SDIO_CPSM; // 命令路径状态机
} SDIO_CmdInitTypeDef;
SDIO_CmdInitTypeDef成员介绍
- SDIO_Argument:作为命令的一部分发送到卡的命令参数,它设定 SDIO 参数寄存器 (SDIO_ARG) 的值。
- SDIO_CmdIndex:命令号选择,它设定 SDIO 命令寄存器 (SDIO_CMD) 的 CMDINDEX 位的值。
- SDIO_Response:响应类型,SDIO 定义两个响应类型:长响应和短响应。根据命令号选择对 应的响应类型。SDIO 定义了四个 32 位的 SDIO 响应寄存器 (SDIO_RESPx,x=1..4),短响应只用到 SDIO_RESP1。
- SDIO_Wait:等待类型选择,有三种状态可选,一种是无等待状态,超时检测功能启动;一种是 等待中断,另外一种是等待传输完成。它设定 SDIO_CMD 寄存器的 WAITPEND 位和 WAITINT 位的值。
- SDIO_CPSM:命令路径状态机控制,可选使能或禁用 CPSM。它设定 SDIO_CMD 寄存器的 CPSMEN 位的值。
SDIO_CmdInitTypeDef成员可选参数
// @defgroup SDIO_Argument
/* 作为命令的一部分发送到卡的命令参数,它设定 SDIO 参数寄存器(SDIO_ARG)的值。 */
// @defgroup SDIO_Cmd_Index
/* 命令号选择,它设定 SDIO 命令寄存器 (SDIO_CMD) 的 CMDINDEX 位的值。 */
// @defgroup SDIO_Response_Type
#define SDIO_Response_No ((uint32_t)0x00000000)
#define SDIO_Response_Short ((uint32_t)0x00000040)
#define SDIO_Response_Long ((uint32_t)0x000000C0)
#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_Response_No) || \
((RESPONSE) == SDIO_Response_Short) || \
((RESPONSE) == SDIO_Response_Long))
// @defgroup SDIO_Wait_Interrupt_State
#define SDIO_Wait_No ((uint32_t)0x00000000) /*!< SDIO No Wait, TimeOut is enabled */
#define SDIO_Wait_IT ((uint32_t)0x00000100) /*!< SDIO Wait Interrupt Request */
#define SDIO_Wait_Pend ((uint32_t)0x00000200) /*!< SDIO Wait End of transfer */
#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_Wait_No) || ((WAIT) == SDIO_Wait_IT) || \
((WAIT) == SDIO_Wait_Pend))
// @defgroup SDIO_CPSM_State
#define SDIO_CPSM_Disable ((uint32_t)0x00000000)
#define SDIO_CPSM_Enable ((uint32_t)0x00000400)
#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_Enable) || ((CPSM) == SDIO_CPSM_Disable))
SDIO数据初始化结构体
typedef struct
{
uint32_t SDIO_DataTimeOut; // 数据传输超时
uint32_t SDIO_DataLength; // 数据长度
uint32_t SDIO_DataBlockSize; // 数据块大小
uint32_t SDIO_TransferDir; // 数据传输方向
uint32_t SDIO_TransferMode; // 数据传输模式
uint32_t SDIO_DPSM; // 数据路径状态机
} SDIO_DataInitTypeDef;
SDIO_DataInitTypeDef成员介绍
- SDIO_DataTimeOut:设置数据传输以卡总线时钟周期表示的超时周期,它设定 SDIO 数据定 时器寄存器 (SDIO_DTIMER) 的值。在 DPSM 进入 Wait_R 或繁忙状态后开始递减,直到 0 还处 于以上两种状态则将超时状态标志置 1。
- SDIO_DataLength:设置传输数据长度,它设定 SDIO 数据长度寄存器 (SDIO_DLEN) 的值。
- SDIO_DataBlockSize:设置数据块大小,有多种尺寸可选,不同命令要求的数据块可能不同。 它设定 SDIO 数据控制寄存器 (SDIO_DCTRL) 寄存器的 DBLOCKSIZE 位的值。
- SDIO_TransferDir:数据传输方向,可选从主机到卡的写操作,或从卡到主机的读操作。它设 定 SDIO_DCTRL 寄存器的 DTDIR 位的值。
- SDIO_TransferMode:数据传输模式,可选数据块或数据流模式。对于 SD 卡操作使用数据块 类型。它设定 SDIO_DCTRL 寄存器的 DTMODE 位的值。
- SDIO_DPSM:数据路径状态机控制,可选使能或禁用 DPSM。它设定 SDIO_DCTRL 寄存器的 DTEN 位的值。要实现数据传输都必须使能 SDIO_DPSM。
SDIO_DataInitTypeDef成员可选参数
// @defgroup SDIO_Data_Timer_Out
/* 设置数据传输以卡总线时钟周期表示的超时周期,它设定 SDIO 数据定时器寄存器 (SDIO_DTIMER) 的值。 */
// @defgroup SDIO_Data_Length
#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFF)
// @defgroup SDIO_Data_Block_Size
#define SDIO_DataBlockSize_1b ((uint32_t)0x00000000)
#define SDIO_DataBlockSize_2b ((uint32_t)0x00000010)
#define SDIO_DataBlockSize_4b ((uint32_t)0x00000020)
#define SDIO_DataBlockSize_8b ((uint32_t)0x00000030)
#define SDIO_DataBlockSize_16b ((uint32_t)0x00000040)
#define SDIO_DataBlockSize_32b ((uint32_t)0x00000050)
#define SDIO_DataBlockSize_64b ((uint32_t)0x00000060)
#define SDIO_DataBlockSize_128b ((uint32_t)0x00000070)
#define SDIO_DataBlockSize_256b ((uint32_t)0x00000080)
#define SDIO_DataBlockSize_512b ((uint32_t)0x00000090)
#define SDIO_DataBlockSize_1024b ((uint32_t)0x000000A0)
#define SDIO_DataBlockSize_2048b ((uint32_t)0x000000B0)
#define SDIO_DataBlockSize_4096b ((uint32_t)0x000000C0)
#define SDIO_DataBlockSize_8192b ((uint32_t)0x000000D0)
#define SDIO_DataBlockSize_16384b ((uint32_t)0x000000E0)
#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DataBlockSize_1b) || \
((SIZE) == SDIO_DataBlockSize_2b) || \
((SIZE) == SDIO_DataBlockSize_4b) || \
((SIZE) == SDIO_DataBlockSize_8b) || \
((SIZE) == SDIO_DataBlockSize_16b) || \
((SIZE) == SDIO_DataBlockSize_32b) || \
((SIZE) == SDIO_DataBlockSize_64b) || \
((SIZE) == SDIO_DataBlockSize_128b) || \
((SIZE) == SDIO_DataBlockSize_256b) || \
((SIZE) == SDIO_DataBlockSize_512b) || \
((SIZE) == SDIO_DataBlockSize_1024b) || \
((SIZE) == SDIO_DataBlockSize_2048b) || \
((SIZE) == SDIO_DataBlockSize_4096b) || \
((SIZE) == SDIO_DataBlockSize_8192b) || \
((SIZE) == SDIO_DataBlockSize_16384b))
// @defgroup SDIO_Transfer_Direction
#define SDIO_TransferDir_ToCard ((uint32_t)0x00000000)
#define SDIO_TransferDir_ToSDIO ((uint32_t)0x00000002)
#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TransferDir_ToCard) || \
((DIR) == SDIO_TransferDir_ToSDIO))
// @defgroup SDIO_Transfer_Type
#define SDIO_TransferMode_Block ((uint32_t)0x00000000)
#define SDIO_TransferMode_Stream ((uint32_t)0x00000004)
#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TransferMode_Stream) || \
((MODE) == SDIO_TransferMode_Block))
// @defgroup SDIO_DPSM_State
#define SDIO_DPSM_Disable ((uint32_t)0x00000000)
#define SDIO_DPSM_Enable ((uint32_t)0x00000001)
#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_Enable) || ((DPSM) == SDIO_DPSM_Disable))
STM32提供例程的函数
STM32例程外部函数接口
void SD_DeInit(void);
SD_Error SD_Init(void);
SDTransferState SD_GetStatus(void);
SDCardState SD_GetState(void);
uint8_t SD_Detect(void);
SD_Error SD_PowerON(void);
SD_Error SD_PowerOFF(void);
SD_Error SD_InitializeCards(void);
SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo);
SD_Error SD_GetCardStatus(SD_CardStatus *cardstatus);
SD_Error SD_EnableWideBusOperation(uint32_t WideMode);
SD_Error SD_SelectDeselect(uint32_t addr);
SD_Error SD_ReadBlock(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize);
SD_Error SD_ReadMultiBlocks(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
SD_Error SD_WriteBlock(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize);
SD_Error SD_WriteMultiBlocks(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
SDTransferState SD_GetTransferState(void);
SD_Error SD_StopTransfer(void);
SD_Error SD_Erase(uint32_t startaddr, uint32_t endaddr);
SD_Error SD_SendStatus(uint32_t *pcardstatus);
SD_Error SD_SendSDStatus(uint32_t *psdstatus);
SD_Error SD_ProcessIRQSrc(void);
SD_Error SD_WaitReadOperation(void);
SD_Error SD_WaitWriteOperation(void);
STM32提供例程所示例的函数功能简介
函数名称 | 功能简介 |
---|---|
void SD_DeInit | 取消SDIO接口的初始化。 |
SD_Error SD_Init | 初始化SD卡并将其置于待机状态 |
SDTransferState SD_GetStatus | 获取连接SD卡的数据传输状态 |
SDCardState SD_GetState | 获取SD卡的状态 |
uint8_t SD_Detect | 检测SD卡是否正确插入内存插槽。 |
SD_Error SD_PowerON | 查询所有SDIO接口上的卡设备,并查询其电压和配置时钟 |
SD_Error SD_PowerOFF | 关闭SDIO输出信号 |
SD_Error SD_InitializeCards | 初始化单个或所有卡,并让卡进入就绪状态 |
SD_Error SD_GetCardInfo | 返回有关卡的信息 |
SD_Error SD_GetCardStatus | 返回卡的状态 |
SD_Error SD_EnableWideBusOperation | 如果卡支持,则配置卡的数据宽度。 |
SD_Error SD_SelectDeselect | 选择卡相对地址为addr的卡,取消选择其他卡 |
SD_Error SD_ReadBlock | 允许从卡中的指定地址读取一个数据块。(DMA\轮询) |
SD_Error SD_ReadMultiBlocks | 允许从卡中的指定地址读取多个块。(DMA\轮询) |
SD_Error SD_WaitReadOperation | 等待SDIO DMA数据传输完成。确保数据由DMA控制器传输。 |
SD_Error SD_WriteBlock | 允许从卡中的指定地址开始写入一个块。(DMA\轮询) |
SD_Error SD_WriteMultiBlocks | 允许从卡中的指定地址写入多个块。(DMA\轮询) |
SD_Error SD_WaitWriteOperation | 等待SDIO DMA数据传输完成。确保数据由DMA控制器传输。 |
SDTransferState SD_GetTransferState | 获取目前数据传输状态 |
SD_Error SD_StopTransfer | 中止正在进行的数据传输。 |
SD_Error SD_Erase | 允许擦除为给定卡指定的存储区域。 |
SD_Error SD_SendStatus | 返回当前卡的状态。 |
SD_Error SD_SendSDStatus | 返回当前卡的状态。 |
SD_Error SD_ProcessIRQSrc | SDIO中断处理函数。允许处理所有高电平中断。 |
static SD_Error CmdError | 检查CMD0的执行条件,返回错误码 |
static SD_Error CmdResp7Error | 检查R7响应的错误状态,返回错误码 |
static SD_Error CmdResp1Error | 检查R1响应的错误状态,返回错误码 |
static SD_Error CmdResp3Error | 检查R3响应的错误状态,返回错误码 |
static SD_Error CmdResp2Error | 检查R2响应的错误状态,返回错误码 |
static SD_Error CmdResp6Error | 检查R6响应的错误状态,返回错误码 |
static SD_Error SDEnWideBus | 启用/禁用SDIO宽总线模式。 |
static SD_Error IsCardProgramming | 检查SD卡是否处于写操作状态 |
static SD_Error FindSCR | 查找SD卡的SCR寄存器值 |
uint8_t convert_from_bytes_to_power_of_two | 得到NumberOfBytes以2为底的指数 |