【前言】
这几天准备在stm32f769上驱动SD卡。我使用STM32CubeMX来配置了时钟,由于使用开发板的SD卡驱动来做试验,所以没有在意SDMMC的时钟,由此折腾了两天,今天晚上终于找到了他的问题所在。现在记录如下:
【环境的搭建】
我使用stm32cubeMX进行了cmake的工程创建,然后手工移植了驱动。工程的时钟配置如下图所示
由于PLLQ给在stm32f769i_discovery_sd.c的sdmmc的时钟,因此他的时钟为200MHz。
而SDMMC只能接受48MHz以下的频率。
我用测试程为如下代码:
void SD_demo(void)
{
GPIO_InitTypeDef gpio_init_structure;
/* Configure Interrupt mode for SD detection pin */
uint8_t SD_state = MSD_OK;
SdmmcTest = 1;
SD_state = BSP_SD_Init();
if (SD_state != MSD_OK)
{
if (SD_state == MSD_ERROR_SD_NOT_PRESENT)
{
printf("SD shall be inserted before running test");
}
else
{
printf("SD Initialization : FAIL.\r\n");
}
printf("SD Test Aborted.\r\n");
}
else
{
printf("SD Initialization : OK.\r\n");
printf("Before Erase, Card State: %d\n", BSP_SD_GetCardState());
SD_state = BSP_SD_Erase(BLOCK_START_ADDR, (BLOCKSIZE * NUM_OF_BLOCKS));
printf("After Erase, Card State: %d, SD_state: %d\n", BSP_SD_GetCardState(), SD_state);
/* Wait until SD card is ready to use for new operation */
while (BSP_SD_GetCardState() != SD_TRANSFER_OK)
{
}
if (SD_state != MSD_OK)
{
printf("SD ERASE : FAILED.\r\n");
printf("SD Test Aborted.\r\n");
}
else
{
printf("SD ERASE : OK.\r\n");
/* Fill the buffer to write */
Fill_Buffer(aTxBuffer, BUFFER_WORDS_SIZE, 0x22FF);
SD_state = BSP_SD_WriteBlocks_DMA(aTxBuffer, BLOCK_START_ADDR, NUM_OF_BLOCKS);
/* Wait for the write process is completed */
while ((SDWriteStatus == 0))
{
}
SDWriteStatus = 0;
/* Wait until SD cards are ready to use for new operation */
while ((BSP_SD_GetCardState() != SD_TRANSFER_OK))
{
}
if (SD_state != MSD_OK)
{
printf("SD WRITE : FAILED.\r\n");
printf("SD Test Aborted.\r\n");
}
else
{
printf("SD WRITE : OK.\r\n");
SD_state = BSP_SD_ReadBlocks_DMA(aRxBuffer, BLOCK_START_ADDR, NUM_OF_BLOCKS);
/* Wait for我运行工程后,进行SD卡的擦除,一直报错如下

为此我一路debug,找到了出错点在:

经查提示,有好几种原因:

而我排除了前面的几种原因,最后定位是SDMMC时钟配置。
为此我找到了原来的BSP工程的主时钟配置与我的工程的时钟配置:

STM32CubeMX配置给PLLQ的时钟频率为 200M 而BSP工程为:25M/25*432/9 = 48MHz 。因此不符合他的时钟要求,所以出错。
我按照BSP工程的时钟配置后,顺利的写入成功,打印日志如下:

【总结】
STM32CubeMX给我们生成工程给了便利,但是一些特殊的外设还需要参照官方的示例进行修改,才能正确运行。
我要赚赏金
