SD卡引脚

功能			MCU引脚		   说明
SD电源	     PB2		低电平上电,高电平断电
插卡检测	    PB4	       低电平表示已插卡
SPI4 SCK	  PE2	     SD时钟
SPI4 MISO	  PE13	     SD DATA0
SPI4 MOSI	  PE14	     SD CMD
SD CS	      PB12	     软件控制片选

SPI函数

// 设置SPI速度:SPI_BaudRatePrescaler_256,SPI_BaudRatePrescaler_4,2-256多种
static void SPI4_SetPrescaler(uint16_t prescaler) 
{
    SPI_Cmd(SPI4, DISABLE); //SPI_Cmd是SDK已经有的一个函数,直接读写
    SD_SPI->CR1 = (SD_SPI->CR1 & (uint16_t)~0x0038) | (prescaler & 0x0038);
    SPI_Cmd(SPI4, ENABLE);
}
//SPI读写
static uint8_t SPI4_RW(uint8_t dat)
{
    while (SPI_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET);
    SPI_SendData(SPI4, dat);
    while (SPI_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
    return (uint8_t)SPI_ReceiveData(SD_SPI);
}
//MCU读SPI外设,内部调用SPI4_RW
static void SPI4_RxMulti(uint8_t *buff, uint32_t len)
{
    while (len--) *buff++ = SPI4_RW(0xFF);
}
//MCU写SPI外设,内部调用SPI4_RW
static void SPI4_TxMulti(const uint8_t *buff, uint32_t len)
{
    while (len--) SPI4_RW(*buff++);
}

控制引脚初始化

//电源引脚配置
GPIO_InitTypeDef  gpio;
PeripheralEnable(PeripheralGPIOB, true);
gpio.GPIO_Pin  = GPIO_Pin_2; //SD卡电源使能, 低有效(拉低上电/供电), 拉高关断
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
gpio.GPIO_PuPd  = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpio);

//插入判断DET引脚
gpio.GPIO_Pin  = SD_DET_PIN;
gpio.GPIO_Mode = GPIO_Mode_IN;
gpio.GPIO_PuPd  = GPIO_PuPd_UP;
GPIO_Init(SD_DET_PORT, &gpio);

void SD_SPI_PowerOn(void)
{
    GPIO_ResetBits(GPIOB, GPIO_Pin_2);   /* 低有效使能: 拉低 PB2 给 SD 卡上电 */
}

void SD_SPI_PowerOff(void)
{
    GPIO_SetBits(GPIOB, GPIO_Pin_2);     /* 拉高 PB2 关断 SD 卡电源 */
}
//读取是否插入
uint8_t SD_SPI_IsInserted(void)
{
    /* DET 外部上拉, 插入为低电平 */
    return (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == Bit_RESET) ? 1 : 0;
}

SPI引脚配置

void SD_SPI_Init(void)
{
    SPI_InitTypeDef   spi;
    /* 3. SPI4 复用脚: PE2(SCK) PE13(MISO) PE14(MOSI), AF5 */
    PeripheralEnable(PeripheralGPIOE, true);
    /* SCK + MOSI: 无上下拉 (主机驱动) */
    gpio.GPIO_Pin   = SD_SPI_SCK_PIN | SD_SPI_MOSI_PIN;
    gpio.GPIO_Mode  = GPIO_Mode_AF;
    gpio.GPIO_OType = GPIO_OType_PP;
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
    gpio.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOE, &gpio);
    /* MISO: 上拉! SD卡CS=高时MISO为高阻态, 无上拉则电平浮动,
     *       SD_WaitReady() 轮询 0xFF 会读到浮动值超时失败。 */
    gpio.GPIO_Pin   = SD_SPI_MISO_PIN;
    gpio.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_Init(GPIOE, &gpio);
    GPIO_PinAFConfig(GPIOE,  GPIO_PinSource2,  (uint8_t)0x05);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, (uint8_t)0x05);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, (uint8_t)0x05);

    /* 4. CS 脚 PB12: 软件控制, 推挽输出, 默认高 */
    gpio.GPIO_Pin  = SD_SPI_CS_PIN;
    gpio.GPIO_Mode = GPIO_Mode_OUT;
    gpio.GPIO_OType = GPIO_OType_PP;
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
    gpio.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &gpio);
    SD_CS_HIGH(); //对应下面CS操作

    /* 5. SPI4 外设 (APB2) */
    PeripheralEnable(PeripheralSPI4, true);
    SPI_StructInit(&spi); //初始化结构体
    spi.SPI_Direction     = SPI_Direction_2Lines_FullDuplex;
    spi.SPI_Mode          = SPI_Mode_Master;
    spi.SPI_DataSize      = SPI_DataSize_8b;
    spi.SPI_CPOL          = SPI_CPOL_Low;
    spi.SPI_CPHA          = SPI_CPHA_1Edge;
    spi.SPI_NSS           = SPI_NSS_Soft;
    spi.SPI_BaudRatePrescaler = SD_SPI_SLOW_PRESCALER;
    spi.SPI_FirstBit      = SPI_FirstBit_MSB;
    spi.SPI_CRCPolynomial = 7;
    SPI_Init(SPI4, &spi);
    SPI_Cmd(SPI4, ENABLE);
}

CS操作

#define SD_CS_HIGH()   GPIO_SetBits(GPIOB,  GPIO_Pin_12)
#define SD_CS_LOW()    GPIO_ResetBits(GPIOB, GPIO_Pin_12)