当前位置: 首页 > news >正文

stm32F4挂载emmc以及重定义printf

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 0xffff

HAL_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();

使用串口助手查看信息

计算总容量的方法如下:

  1. 块数量BlockNbr = 61079552
  2. 每块大小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博客

http://www.xdnf.cn/news/1413847.html

相关文章:

  • ThinkPHP8学习篇(五):数据库(一)
  • 洛谷p2392kkksc03考前临时抱佛脚 详解(回溯,深度搜索法)
  • Redis常见数据类型及应用场景
  • java 安装流程配置
  • 金仓数据库KingbaseES:中国自主原创的数据库领军者
  • 【四位加密】2022-10-25
  • GDPU操作系统实验:生产者消费者问题
  • 【读数笔记】《你的生存本能正在杀死你》
  • 经典卷积神经网络CNN
  • sublime MAC系统快捷键及常见问题
  • Qwen2.5-VL代码初步解读
  • 恒香全新旗舰店开幕 新店传承百年文化
  • 容器seccomp配置文件在云服务器安全策略中的实施规范
  • 常用定位技术对比解析
  • MySQL数据库——0.MySQL大纲
  • 【全功能图片处理工具详解】基于Streamlit的现代化图像处理解决方案
  • OpenCV 图像轮廓检测
  • 【系统分析师】高分论文:论面向服务方法在信息系统开发中的应用
  • 基于CotSegNet网络和机器学习的棉花点云器官分割和表型信息提取
  • 获取某天的零点日期
  • 解锁GPU计算潜能:深入浅出CUDA架构与编程模型
  • Day18 (前端:JavaScript基础阶段)
  • Langflow 评估与迭代技术深度分析
  • Cookie、Session 和 JWT
  • git中使用SSH的配置
  • 堆排序:高效稳定的大数据排序法
  • 【图论】 Graph.jl 概览
  • 面试问题详解十三:Qt 多线程同步【QReadWriteLock】讲解
  • 24数学建模国赛C
  • 【数据分享】上市公司-国际化程度-营业收入指标(2005-2023)