赞
踩
uint8_t WaitEMMCReady(void)
{
uint8_t count = EMMC_TIMEOUT;
while(count--)
{
if(HAL_MMC_GetCardState(&hmmc)== HAL_MMC_CARD_TRANSFER)
{
return HAL_OK;
}
HAL_Delay(1);
}
return HAL_ERROR;
}
HAL_StatusTypeDef EMMC_ReadBlock_DMA(uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) { HAL_StatusTypeDef Status = HAL_OK; if(WaitEMMCReady() != HAL_OK) { Status = HAL_BUSY; } HAL_DMA_DeInit(&hdma_sdio); hdma_sdio.Instance = DMA2_Channel4; hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE; hdma_sdio.Init.MemInc = DMA_MINC_ENABLE; hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sdio.Init.Mode = DMA_NORMAL; hdma_sdio.Init.Priority = DMA_PRIORITY_LOW; if(HAL_DMA_Init(&hdma_sdio) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(&hmmc, hdmarx, hdma_sdio); if(HAL_MMC_ReadBlocks_DMA(&hmmc, pData, BlockAdd, NumberOfBlocks) != HAL_OK) { Status = HAL_ERROR; } return Status; }
HAL_StatusTypeDef EMMC_WriteBlock_DMA(uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) { HAL_StatusTypeDef Status = HAL_OK; if(WaitEMMCReady() != HAL_OK) { Status = HAL_BUSY; } HAL_DMA_DeInit(&hdma_sdio); hdma_sdio.Instance = DMA2_Channel4; hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE; hdma_sdio.Init.MemInc = DMA_MINC_ENABLE; hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sdio.Init.Mode = DMA_NORMAL; hdma_sdio.Init.Priority = DMA_PRIORITY_LOW; if(HAL_DMA_Init(&hdma_sdio) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(&hmmc, hdmatx, hdma_sdio); if (HAL_MMC_WriteBlocks_DMA(&hmmc, pData, BlockAdd, NumberOfBlocks) != HAL_OK) { Status = HAL_ERROR; } return Status; }
uint8_t recvbuf[512]; uint8_t sendbuf[512] = {0xAA,0xBB,0xCC,0xDD}; printf("\r\n--------> EMMC DMA Test\r\n"); ret= EMMC_ReadBlock_DMA(recvbuf,0,1); if(ret == HAL_OK) { for (uint16_t i = 0; i < BLOCKSIZE; i++) { printf("0x%02x ",recvbuf[i]); if((i%16) == 0) { printf("\r\n"); } } } ret = EMMC_WriteBlock_DMA(sendbuf,0,1); if(ret == HAL_OK) { printf("\r\n--------> EMMC 写入成功\r\n"); } ret = EMMC_ReadBlock_DMA(recvbuf,0,1); printf("\r\n--------> ret:%d\r\n",ret); if(ret == HAL_OK) { for (uint16_t i = 0; i < hmmc.MmcCard.BlockSize; i++) { printf("0x%02x ",recvbuf[i]); if((i%16) == 0) { printf("\r\n"); } } }
1.FATFS官网下载地址:http://elm-chan.org/fsw/ff/00index_e.html
2.截至2024.6.1最新版本为0.15
3.本工程使用版本为0.11a
底层驱动只需要修改diskio.c与ffconf.h
#define _USE_MKFS 1 // 0–>1
#define _CODE_PAGE 936 //932–>936 日文到中文
#define _USE_LFN 1 // 0->1 支持长文件名
#define _VOLUMES 1 //根据你使用的盘符数 自行更改
#define _MAX_SS 4096 // 512–>4096 SPI 扇区大小为4096
#define _FS_LOCK 3 // 0–>3 支持同时打开文件数 3个
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat = STA_NOINIT;
if(pdrv == MMC)
{
printf("\r\n--------> disk_status EMMC\r\n");
stat &= ~STA_NOINIT;
}
return stat;
}
DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { DSTATUS stat = STA_NOINIT; if(pdrv == MMC) { printf("\r\n--------> disk_initialize EMMC\r\n"); if(HAL_MMC_Init(&hmmc)==HAL_OK) { printf("\r\n--------> disk_initialize EMMC Success\r\n"); stat &= ~STA_NOINIT; } } return stat; }
DRESULT disk_read ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector address in LBA */ UINT count /* Number of sectors to read */ ) { DRESULT res; if(pdrv == MMC) { printf("\r\n--------> disk_read EMMC\r\n"); if(EMMC_ReadBlock_DMA((uint8_t*)buff,(uint32_t)sector,count) == HAL_OK) { printf("\r\n--------> disk_read Success\r\n"); res = RES_OK; } else { res = RES_PARERR; } } else { res = RES_ERROR; } return res; }
DRESULT disk_write ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ const BYTE *buff, /* Data to be written */ DWORD sector, /* Sector address in LBA */ UINT count /* Number of sectors to write */ ) { DRESULT res; if(pdrv == MMC) { printf("\r\n--------> disk_write EMMC\r\n"); if(EMMC_WriteBlock_DMA((uint8_t*)buff,(uint32_t)sector,count) == HAL_OK) { printf("\r\n--------> disk_write Success\r\n"); res = RES_OK; } else { res = RES_WRPRT; } } else { res = RES_ERROR; } return res; }
DRESULT disk_ioctl ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE cmd, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { DRESULT res = STA_NOINIT; int result; if(pdrv == MMC) { printf("\r\n--------> disk_ioctl EMMC\r\n"); switch(cmd) { case GET_SECTOR_COUNT: *(DWORD * )buff = hmmc.MmcCard.BlockNbr; break; case GET_SECTOR_SIZE: *(DWORD * )buff = hmmc.MmcCard.BlockSize; break; case GET_BLOCK_SIZE: *(DWORD * )buff = 1; break; case MMC_GET_SDSTAT: *(DWORD * )buff = HAL_MMC_GetState(&hmmc); break; } res = RES_OK; } return RES_OK; }
FATFS fs; /* FatFs文件系统对象 */ FIL fnew; /* 文件对象 */ FRESULT res_sd; /* 文件操作结果 */ UINT fnum; /* 文件成功读写数量 */ BYTE ReadBuffer[1024]={0}; /* 读缓冲区 */ BYTE WriteBuffer[] = "Hello World!!!"; /* 写缓冲区*/ printf("\r\n--------> EMMC 文件系统\r\n"); res_sd = f_mount(&fs,"0:",1); /*----------------------- 格式化测试 ---------------------------*/ /* 如果没有文件系统就格式化创建创建文件系统 */ if(res_sd == FR_NO_FILESYSTEM) { printf("--------> EMMC还没有文件系统,即将进行格式化...\r\n"); /* 格式化 */ res_sd=f_mkfs("0:",0,0); if(res_sd == FR_OK) { printf("--------> EMMC已成功格式化文件系统。\r\n"); /* 格式化后,先取消挂载 */ res_sd = f_mount(NULL,"0:",1); /* 重新挂载 */ res_sd = f_mount(&fs,"0:",1); } else { printf("--------> EMMC格式化失败\r\n"); while(1); } } else if(res_sd!=FR_OK) { printf("--------> EMMC挂载文件系统失败:(%d)\r\n",res_sd); printf("--------> EMMC初始化不成功。\r\n"); while(1); } else { printf("--------> EMMC文件系统挂载成功,可以进行读写测试\r\n"); } printf("\r\n--------> EMMC即将进行文件写入\r\n"); res_sd = f_open(&fnew, "0:FatFs1.txt",FA_CREATE_ALWAYS | FA_WRITE ); //ps:文件名不要过长,过长会导致创建失败,若过长需要在ffconf.h中开启宏定义 if ( res_sd == FR_OK ) { printf("--------> EMMC打开/创建FatFs1.txt文件成功,向文件写入数据。\r\n"); /* 将指定存储区内容写入到文件内 */ res_sd=f_write(&fnew,WriteBuffer,sizeof(WriteBuffer),&fnum); if(res_sd==FR_OK) { printf("--------> EMMC文件写入成功,写入字节数据:%d\n",fnum); printf("--------> EMMC向文件写入的数据为:\r\n%s\r\n",WriteBuffer); } else { printf("-------->EMMC文件写入失败:(%d)\n",res_sd); } /* 不再读写,关闭文件 */ f_close(&fnew); } else { printf("--------> EMMC打开/创建文件失败\r\n"); } printf("--------> EMMC即将进行文件读取\r\n"); res_sd = f_open(&fnew, "0:FatFs1.txt", FA_OPEN_EXISTING | FA_READ); if(res_sd == FR_OK) { printf("--------> EMMC打开文件成功。\r\n"); res_sd = f_read(&fnew, ReadBuffer, sizeof(ReadBuffer), &fnum); if(res_sd==FR_OK) { printf("--------> EMMC文件读取成功,读到字节数据:%d\r\n",fnum); printf("--------> EMMC读取得的文件数据为:\r\n%s \r\n", ReadBuffer); } else { printf("--------> EMMC文件读取失败:(%d)\n",res_sd); } } else { printf("--------> EMMC打开文件失败\r\n"); } /* 不再读写,关闭文件 */ f_close(&fnew); /* 不再使用文件系统,取消挂载文件系统 */ f_mount(NULL,"0:",1);
###测试结果
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。