【前言】
这几天准备在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给我们生成工程给了便利,但是一些特殊的外设还需要参照官方的示例进行修改,才能正确运行。