发表于 2018 年 1 月 2 日 12:18
大家好,
最近使用 STM32CubeMX Ver 4.0(STMCube V1.0),固件V1.18为STM32F407生成代码,使用SDIO 4位总线通过DMA或标准IO访问SD卡。生成的代码可能无法运行。
为了使其工作,您必须修改 STM32CubeMX 生成的三个文件:
1. bsp_driver_sd.c
2. sd_diskio.c
3.fatfs.c
以下是程序:
1.
bsp_driver_sd.c
修改
BSP_SD_WriteBlocks() 和
BSP_SD_ReadBlocks_DMA() 支持 DMA 或标准 I/O:
- // A flag indicating if to use DMA for read/write
- uint8_t BSP_SD_Ext_UseDMA = 1;
- /*==========================================================================
- Description
- DMA or polling mode of Reads block(s) from a specified address in an SD card
- * @param pData: Pointer to the buffer that will contain the data to transmit
- * @param ReadAddr: Address from where data is to be read
- * @param NumOfBlocks: Number of SD blocks to read
- * @param Timeout: Timeout for read operation
- * @retval SD status
- ---------------------------------------------------------------------------*/
- uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
- {
- HAL_SD_StateTypeDef state_return;
- uint32_t timeout = 0;
- if (BSP_SD_Ext_UseDMA == 0) {
- if (HAL_SD_ReadBlocks(&hsd, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout) != HAL_OK)
- return MSD_ERROR;
- } else {
- // Read block(s) in DMA transfer mode
- if (HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t*) pData, ReadAddr, NumOfBlocks) != HAL_OK)
- return MSD_ERROR;
- // Wait until the SDIO/SDMMC and DMA finish the read/write
- timeout = 0;
- do {
- state_return = HAL_SD_GetState(&hsd);
- timeout++;
- } while((state_return == HAL_SD_STATE_BUSY) && (timeout < SD_DATATIMEOUT));
- if (HAL_SD_STATE_READY != state_return)
- return MSD_ERROR;
- }
- return MSD_OK;
- }
- /*==========================================================================
- Description
- DMA or polling mode of Write block(s) to a specified address in an SD card
- * @param pData: Pointer to the buffer that will contain the data to transmit
- * @param WriteAddr: Address from where data is to be written
- * @param NumOfBlocks: Number of SD blocks to write
- * @param Timeout: Timeout for write operation
- * @retval SD status
- ---------------------------------------------------------------------------*/
- uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
- {
- HAL_SD_StateTypeDef state_return;
- uint32_t timeout = 0;
- if(BSP_SD_Ext_UseDMA == 0) {
- if (HAL_SD_WriteBlocks(&hsd, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout) != HAL_OK)
- return MSD_ERROR;
- } else {
- // Read block(s) in DMA transfer mode
- if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t*) pData, WriteAddr, NumOfBlocks) != HAL_OK)
- return MSD_ERROR;
- // Wait until the SDIO/SDMMC and DMA finish the read/write
- timeout = 0;
- do {
- state_return = HAL_SD_GetState(&hsd);
- timeout++;
- }
- while((state_return == HAL_SD_STATE_BUSY) && (timeout < SD_DATATIMEOUT));
- if (HAL_SD_STATE_READY != state_return)
- return MSD_ERROR;
- }
- return MSD_OK;
- }
2. sd_diskio.c
i) 修复缺少的 SDIO 初始化代码
原始生成代码:
- DSTATUS SD_initialize(BYTE lun)
- {
- return SD_CheckStatus(lun);
- }
应该修改(我不知道
为什么 BSP_SD_Init() 不见了!
):
- DSTATUS SD_initialize(BYTE lun)
- {
- Stat = STA_NOINIT;
- if (BSP_SD_Init() == MSD_OK)
- Stat = SD_CheckStatus(lun);
- return Stat;
- }
否则,它无法通过 HAL_SD_Init() 初始化 SDIO!
ii) 修改SD_read()和SD_write:
- DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
- {
- DRESULT res = RES_ERROR;
- if (BSP_SD_ReadBlocks((uint32_t*)buff,
- (uint32_t) (sector),
- count,
- SDMMC_DATATIMEOUT) == MSD_OK) {
- // wait until the read operation is finished
- while (BSP_SD_GetCardState()!= MSD_OK);
- res = RES_OK;
- }
- return res;
- }
- DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
- {
- DRESULT res = RES_ERROR;
- if (BSP_SD_WriteBlocks((uint32_t*)buff,
- (uint32_t)(sector),
- count,
- SDMMC_DATATIMEOUT) == MSD_OK) {
- // wait until the Write operation is finished
- while (BSP_SD_GetCardState() != MSD_OK);
- res = RES_OK;
- }
- return res;
- }
-
3.
fatfs.c
添加挂载程序挂载SD卡文件系统
原始生成代码:
- void MX_FATFS_Init(void)
- {
- /*## FatFS: Link the SD driver ###########################*/
- retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
- /* USER CODE BEGIN Init */
- /* additional user code for init */
- /* USER CODE END Init */
- }
修改后的代码:
- void MX_FATFS_Init(void)
- {
- /*## FatFS: Link the SD driver ###########################*/
- retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
- /* USER CODE BEGIN Init */
- /* additional user code for init */
- if (retSD != 0)
- Error_Handler();
- if (f_mount(&SDFatFS, (TCHAR const*)SDPath, 0) != FR_OK)
- Error_Handler();
- /* USER CODE END Init */
- }
最后,我们可以编写代码来测试 FATFS:
- void SDFileTest(void)
- {
- FIL MyFile;
- FRESULT res; /* FatFs function common result code */
- uint32_t byteswritten, bytesread; /* File write/read counts */
- uint8_t wtext[] = 'Hello, STM32F4 FatFs!'; /* File write buffer */
- uint8_t rtext[100]; /* File read buffer */
- printf('SD File createn');
- // Create file test
- if (f_open(&MyFile, 'STMTXT', FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
- Error_Handler();
- res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);
- if ((byteswritten == 0) || (res != FR_OK))
- Error_Handler();
- f_close(&MyFile);
- printf('done!n');
- printf('SD File openn');
- // Read file test
- if (f_open(&MyFile, 'STMTXT', FA_READ) != FR_OK)
- Error_Handler();
- res = f_read(&MyFile, rtext, sizeof(rtext), (UINT*)&bytesread);
- if ((bytesread == 0) || (res != FR_OK))
- Error_Handler();
- f_close(&MyFile);
- if ((bytesread != byteswritten))
- Error_Handler();
- printf('done!n');
- }
- int main(void)
- {
- .
- .
- MX_DMA_Init();
- .
- .
- MX_SDIO_SD_Init();
- .
- .
- MX_FATFS_Init();
- .
- .
- SDFileTest();
- while (1);
- }
-
0
|
1个回答
|
|
|