功能 MCU引脚 说明
SD电源 PB2 低电平上电,高电平断电
插卡检测 PB4 低电平表示已插卡
SPI4 SCK PE2 SD时钟
SPI4 MISO PE13 SD DATA0
SPI4 MOSI PE14 SD CMD
SD CS PB12 软件控制片选
// 设置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;
}
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);
}
#define SD_CS_HIGH() GPIO_SetBits(GPIOB, GPIO_Pin_12)
#define SD_CS_LOW() GPIO_ResetBits(GPIOB, GPIO_Pin_12)