1.Cubemx
SDIO
USART
使用串口输出调试信息
FATFS
Clock Configuration
防止堆栈溢出
2.Keil5
新建自定义文件夹及文件
将文件夹添加进工程
新建.c与.h文件,保存到自定义的文件夹,并添加到工程中
bsp_emmc.c
#include "bsp_emmc.h"
#include "ff.h"
#include <stdio.h>
//全局变量
extern MMC_HandleTypeDef hmmc;
extern DMA_HandleTypeDef hdma_sdio_rx;
extern DMA_HandleTypeDef hdma_sdio_tx;//emmc 大小信息结构体
HAL_MMC_CardInfoTypeDef emmc_info;//等待emmc状态
HAL_StatusTypeDef wait_EMMC_Ready(void)
{
uint16_t count = EMMC_TIMEOUT; //.h
while(count--)
{
if(HAL_MMC_GetCardState(&hmmc) == HAL_MMC_CARD_TRANSFER)
{
return HAL_OK;
}
HAL_Delay(1);
}
return HAL_ERROR;
}
//emmc DMA 读取数据
HAL_StatusTypeDef EMMC_ReadBlock_DMA(uint8_t *pData, uint32_t BlockAdd ,uint32_t NumberOfBlocks)
{
HAL_StatusTypeDef Status = HAL_OK;
if(HAL_MMC_ReadBlocks_DMA(&hmmc,pData,BlockAdd,NumberOfBlocks) == HAL_OK)
{
while(wait_EMMC_Ready() != HAL_OK){} //等待emmc状态
Status =HAL_OK;
}
return Status;
}//emmc DMA写入
HAL_StatusTypeDef EMMC_WriteBlock_DMA(uint8_t *pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)
{
HAL_StatusTypeDef Status = HAL_OK;
if(wait_EMMC_Ready() != HAL_OK)
{
Status = HAL_BUSY;
}
if(HAL_MMC_WriteBlocks_DMA(&hmmc,pData,BlockAdd,NumberOfBlocks) != HAL_OK)
{
Status = HAL_ERROR;
}
return Status;}
//emmc 擦除
HAL_StatusTypeDef EMMC_Erase(uint32_t BlockAdd ,uint32_t NumberOfBlocks)
{
HAL_StatusTypeDef Status = HAL_ERROR;
if(HAL_MMC_Erase(&hmmc,BlockAdd,BlockAdd*NumberOfBlocks) == HAL_OK)
{
while(wait_EMMC_Ready() != HAL_OK){};
Status = HAL_OK;
}
return Status;
}HAL_StatusTypeDef EMMC_GetInfo(HAL_MMC_CardInfoTypeDef *pData)
{
HAL_StatusTypeDef Status = HAL_ERROR;
if(HAL_OK == HAL_MMC_GetCardInfo(&hmmc,pData))
{
Status = HAL_OK;
}
return Status;
}
void EMMC_Getinfo_TEST()
{
HAL_StatusTypeDef ret =HAL_OK;
printf("\r\n ---EMMC_Getinfo_Test\r\n");
ret= EMMC_GetInfo(&emmc_info);
if(ret == HAL_OK)
{
printf("---EMMC_Info: \r\n");
printf("---CardType: %d\r\n",emmc_info.CardType);
printf("---Class: %d\r\n",emmc_info.Class);
printf("---RelCardAdd: %d\r\n",emmc_info.RelCardAdd);
printf("---BlockNbr: %d\r\n",emmc_info.BlockNbr);
printf("---BlockSize: %d\r\n",emmc_info.BlockSize);
printf("---LogBlockNbr: %d\r\n",emmc_info.LogBlockNbr);
printf("---LogoBlockSize: %d\r\n",emmc_info.LogBlockSize);
}
else
{
printf("\r\n --- EMMC_GetInfo_ERROR(%d) \r\n",ret);
}}
//接收数据
uint8_t recvbuf[512];
//发送数据
uint8_t sendbuf[512]={0x22, 0xaa};//读写
void EMMC_TEST()
{
HAL_StatusTypeDef ret = HAL_OK;
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<hmmc.MmcCard.BlockSize;i++)
{
printf("0x%02x",recvbuf[i]);
if((i%16) == 0&& i!=0)
{
printf("EMMC_TEST read end\r\n");
}
}
}
//EMMC_WriteBlock_DMA 烧录后,注释这一段
//注释begin
// ret=EMMC_WriteBlock_DMA(sendbuf,0,1);
// if(ret ==HAL_OK)
// {
// printf("\r\n -----EMMC write_source");
// }
// 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 && i!=0)
// {
// printf("\r\n");// }
// }
//
// }
//注释end
}
//EMMC 擦除
void Erase_Test()
{
HAL_StatusTypeDef ret = HAL_OK;
printf("\r\n ----EMMC Read1 \r\n");
ret=EMMC_ReadBlock_DMA(recvbuf,0,1);
if(ret == HAL_OK)
{
for(uint16_t i=0;i<hmmc.MmcCard.BlockSize;i++)
{
printf("0x%02x",recvbuf[i]);
if((i%16) == 0 && i!=0)
{
printf("---\r\n");
}
}
}
printf("\r\n ---Erase_Test\r\n");
if(HAL_OK == EMMC_Erase(0x00,1))
{
printf("\r\n -----EMMC_OK\r\n");
}
else
{
printf("\r\n ------EMMC_Error");
}
if(ret ==HAL_OK)
{
for(uint16_t i=0;i<hmmc.MmcCard.LogBlockSize;i++)
{
printf("0x%02x",recvbuf[i]);
if(i%16 == 0 && i!=0)
{
printf("\r\n");
}
}
}
}FATFS fs; //Fatfs系统对象
FIL fnew; //文件对象
FRESULT res_sd; //文件操作结果
UINT fnum; //文件成功读写数量
BYTE ReadBuffer[1024]={0}; //读缓冲区
BYTE WriteBuffer[]="123456\r\n"; //写缓冲区
BYTE work[_MAX_SS];//文件系统读写测试函数
void EMMC_FATFS_TEST(void)
{
printf("\r\n读写测试\r\n");
res_sd=f_mount(&fs,"0",1);
//格式化测试
//若没有文件系统就格式化 创建文件系统
if(res_sd == FR_NO_FILESYSTEM)
{
printf("\r\n 无文件系统,即将格式化");
//格式化
res_sd=f_mkfs("0:",FS_FAT32,0,work,sizeof(work));
if(res_sd == FR_OK)
{
printf("\r\n 格式化成功\r\n");
//取消挂载
res_sd =f_mount(NULL ,"0:",1);
//重新挂载
res_sd = f_mount(&fs,"0",1);
}
else
{
printf("\r\n--格式化失败--\r\n");
return;
}
}else if(res_sd != FR_OK)
{
printf("挂载文件系统失败,(%d)\r\n",res_sd);
printf("可能原因:初始化失败,\r\n");
return;
}
else
{
printf("\r\n文件系统挂载成功,可进行读写测试\r\n");
}
//--------------------文件系统测试:写测试--------------
//打开文件,若文件不存在就创建它
printf("\r\n--- 即将进入文件写入测试");
res_sd = f_open(&fnew ,"0:FatFs.txt",FA_OPEN_ALWAYS|FA_WRITE);
if(res_sd ==FR_OK)
{
printf("打开/创建Fatfs读写测试文件.txt文件成功,向文件写入数据,\r\n");
//指定存储区内容写入到文件
printf("the fire size is %d",(int)f_size(&fnew));
f_lseek(&fnew,f_size(&fnew));
res_sd=f_write(&fnew,WriteBuffer,sizeof(WriteBuffer),&fnum);
if(res_sd == FR_OK)
{
printf("--文件写入成功,写入字节数据 :%d\n",fnum);
printf("--写入数据为:\r\n %s \r\n",WriteBuffer);
}
else
{
printf("---!!写入文件失败:(%d)\n",res_sd);
}
//不读写了,关闭文件
f_close(&fnew);
}
else
{
printf("!!打开文件失败:(%d)\n",res_sd);
}//--------------文件系统测试:读测试---------------
printf("---即将进行文件读取测试...\r\n");
res_sd = f_open(&fnew,"0:FatFs.txt",FA_OPEN_ALWAYS|FA_READ);
if(res_sd == FR_OK)
{
printf("----打开文件成功,\r\n");
res_sd = f_read(&fnew , ReadBuffer,sizeof(ReadBuffer),&fnum);
if(res_sd ==FR_OK)
{
printf("---文件读取成功,读取到字节数据: %d\r\n",fnum);
printf("---d读取的文件数据为:\r\n %s \r\n",ReadBuffer);
}
else
{
printf("读取文件失败(%d)\r\n",res_sd);
}
}
//不再读写,关闭文件
f_close(&fnew);
f_mount(NULL,"0:",1);
printf("取消挂载");
}
bsp_emmc.h
#ifndef __BSP_EMMC_H_
#define __BSP_EMMC_H_#include "main.h"
#define EMMC_TIMEOUT 0xffffHAL_StatusTypeDef EMMC_ReadBlock_DMA(uint8_t *pData, uint32_t BlockAdd ,uint32_t NumberOfBlocks);
HAL_StatusTypeDef EMMC_WriteBlock_DMA(uint8_t *pData,uint32_t BlockAdd,uint32_t NumberOfBlocks);
HAL_StatusTypeDef EMMC_Erase(uint32_t BlockAdd ,uint32_t NumberOfBlocks);
HAL_StatusTypeDef EMMC_GetInfo(HAL_MMC_CardInfoTypeDef *pData);void EMMC_Getinfo_TEST();
void EMMC_TEST(void);
void Erase_Test(void);
void EMMC_FATFS_TEST(void);#endif
重定义printf
打开Cubemx生成的USART.c
添加
#include <stdio.h>
void _sys_exit(int x)
{
x=x;
}//重定义fputc函数
int fputc(int ch ,FILE *f)
{
while((USART1->SR&0x40) == 0){}//满足此条件循环发送直到发送完毕 ,不满足则跳转至下面
USART1->DR = (uint8_t)ch;
return ch;
};
main.c
添加
HAL_Delay(1000);
EMMC_Getinfo_TEST();
// EMMC_FATFS_TEST();
使用串口助手查看信息
计算总容量的方法如下:
- 块数量:
BlockNbr = 61079552
- 每块大小:
BlockSize = 512
字节
总容量 = 块数量 × 每块大小
计算:
61079552×512= = 31268536064 字节
将字节转换为千字节 (KB):
容量 (KB)=31268536064/1024= 30539776KB
将千字节转换为兆字节 (MB):
容量 (MB)=30539776/1024} = 29813.5MB
将兆字节转换为千兆字节 (GB):
容量 (GB)=29813.5/1024≈29.1 GB
因此,总容量约为 29.1 GB。
参考
STM32使用HAL库驱动EMMC挂载FATFS文件系统_stm32 emmc-CSDN博客