STM32CubeMx + SD Card + FatFs 读写SD卡死等问题

发布者:老桃子最新更新时间:2018-07-19 来源: eefocus关键字:STM32CubeMx  Card  FatFs  读写SD  卡死 手机看文章 扫描二维码
随时随地手机看文章

Cube Mx使用较新版本 Version:4.24.0

MDK v5.20

STM32F429ZGT6

两年以前记得试过SD卡读写,好像不是单纯的Read和Write,应该是用了文件系统,很顺利的试验成功了,所以源码和记录都没留,这次要做一个新的板子,真所谓苦难重重啊,到现在32.768K的晶振一直没起振,由原来的10P电容换了6P的,还是不行,应该说偶尔可以,但生产代码中MX_RTC_Init() 依然死在里面,LSE未就绪啊~, 言归正传,写了一个试验SD卡的程序,f_open 死在路上了,经调试发现ReadStatus 始终不会置1,唯一修改其值的方法BSP_SD_ReadCpltCallback根本没人调用,先是怀疑自己配置,在方法SD_read中直接调用了BSP_SD_ReadBlocks_DMA,可见,不用DMA不行,配置SDIO的DMA,如下


通过调试,还是不行,现在的中断函数已经被调用了HAL_DMA_IRQHandler,中断方法中传输完成调用hdma->XferM1CpltCallback(hdma); 而在读取方法中设置回调 hsd->hdmarx->XferCpltCallback = SD_DMAReceiveCplt; 在SD_DMAReceiveCplt方法中最后调用了HAL的回调HAL_SD_RxCpltCallback(hsd);而此方法又空,和希望的回调基本同名BSP_SD_ReadCpltCallback。所以把读写都放到此方法里(文件stm32f4xx_hal_sd.c 头加入extern void BSP_SD_ReadCpltCallback(void); extern void BSP_SD_WriteCpltCallback(void);)至此,Open方法过去了,但写方法一直失败,原因是HAL_SD_TxCpltCallback居然没地方调用,放到方法SD_DMATransmitCplt里,写一次后返回HAL_OK,但hsd->State一直是busy,导致下次读直接返回HAL_ERROR,再次在方法SD_DMATransmitCplt中添加hsd->State = HAL_SD_STATE_READY;至此SD卡读写正常。

总结一下生成代码后的改动:

stm32f4xx_hal_sd.c


 //dp:add at2018.6.20

extern void BSP_SD_ReadCpltCallback(void);

extern void BSP_SD_WriteCpltCallback(void);

/**

  * @brief Tx Transfer completed callbacks

  * @param hsd Pointer to SD handle

  * @retval None

  */

 __weak void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)

{

  /* Prevent unused argument(s) compilation warning */

  //UNUSED(hsd);

    //dp:add

    BSP_SD_WriteCpltCallback();

  /* NOTE : This function should not be modified, when the callback is needed,

            the HAL_SD_TxCpltCallback can be implemented in the user file

   */

}

 

/**

  * @brief Rx Transfer completed callbacks

  * @param hsd Pointer SD handle

  * @retval None

  */

__weak void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)

{

  /* Prevent unused argument(s) compilation warning */

  //UNUSED(hsd);

    //dp:add

    BSP_SD_ReadCpltCallback();

  /* NOTE : This function should not be modified, when the callback is needed,

            the HAL_SD_RxCpltCallback can be implemented in the user file

   */

}

/**

  * @brief  DMA SD transmit process complete callback 

  * @param  hdma DMA handle

  * @retval None

  */

static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma)     

{

  SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);

  

  /* Enable DATAEND Interrupt */

  __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DATAEND));

    //dp:add

    hsd->State = HAL_SD_STATE_READY;

    HAL_SD_TxCpltCallback(hsd);

}

例子程序:试了一下128的数组没问题,然后写到外扩SRAM里,再写入SD卡,再读128也没问题,最后的长度判断请忽略

/**

  ******************************************************************************

  * @file    xx_module_debug.c

  * @author  deep

  * @version V1.0.0

  * @date    2018.6.14

  * @brief   debug module

  ******************************************************************************

  */

 

#include "main.h"

#include "ff.h"

#include "string.h"

#include "xx_base_types.h"

 

U32 m_sram_addr = 0x64000000;

void xx_fill_sram(void);

 

FATFS fs;

FIL fil;

 

char sd_file_name[] = "hd_sd_test.txt";

 

extern void _Error_Handler(char *file, int line);

extern uint8_t retSD;

 

void hd_sd_file_read_write(void)

{

    //char szwrite[128];

    char szread[128];

    U32 bytewritten;

    U32 byteread;

    U32 ADD = m_sram_addr;

    

    if (retSD != 0)

    {

        _Error_Handler(__FILE__, __LINE__);

    }

    

    hd_fill_sram();

    

    retSD = f_mount(&fs, "", 0);

    if (retSD)

    {

        _Error_Handler(__FILE__, __LINE__);

    }

    

    retSD = f_open(&fil, sd_file_name, FA_CREATE_ALWAYS | FA_WRITE);

    if (retSD)

    {

        _Error_Handler(__FILE__, __LINE__);

    }

    

    //strcpy(szwrite, " This function is called in f_mount() function to create a new !!\n");

    //retSD = f_write(&fil, (void *)szwrite, strlen(szwrite), (void *)&bytewritten);

    retSD = f_write(&fil, (void *)ADD, 512, (void *)&bytewritten);

    if (retSD)

    {

        _Error_Handler(__FILE__, __LINE__);

    }

    retSD = f_write(&fil, (void *)(ADD + 512), 512, (void *)&bytewritten);

    if (retSD)

    {

        _Error_Handler(__FILE__, __LINE__);

    }

    retSD = f_write(&fil, (void *)(ADD + 512), 512, (void *)&bytewritten);

    if (retSD)

    {

        _Error_Handler(__FILE__, __LINE__);

    }

    

    retSD = f_close(&fil);

    if (retSD)

    {

        _Error_Handler(__FILE__, __LINE__);

    }

    

    retSD = f_open(&fil, sd_file_name, FA_READ);

    if (retSD)

    {

        _Error_Handler(__FILE__, __LINE__);

    }

    

    retSD = f_read(&fil, szread, sizeof(szread), (U32 *)&byteread);

    if (retSD)

    {

        _Error_Handler(__FILE__, __LINE__);

    }

    

    retSD = f_close(&fil);

    if (retSD)

    {

        _Error_Handler(__FILE__, __LINE__);

    }

    

    if (byteread == bytewritten)

    {

        printf("FATFS OK!!!!!!!!!");

    }

    else

    {

        printf("FATFS ERROR, ERROR, ERROR!");

    }

    

}

时钟设置



SDIO设置



单次写操作大于512会出错,暂时没去纠结原因,回头更新了版本再试。

-------------------------------------------------------------------------------------------------------

2018.6.21 发现个很弱的弱函数标示,一直没有注意

__weak void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)

注:

weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”。

加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,

那么编译器就会执行__weak 声明的函数,并且编译器不会报错。

所以最终更改,在文件 sd_diskio.c 中末尾加入:


/* USER CODE BEGIN lastSection */ 

/* can be used to modify / undefine previous code or add new code */

void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)

{

    BSP_SD_WriteCpltCallback();

}

 

void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)

{

     BSP_SD_ReadCpltCallback();

}

/* USER CODE END lastSection */

SD_DMATransmitCplt 方法中的添加暂时没找到好办法,防止生成时覆盖。


关键字:STM32CubeMx  Card  FatFs  读写SD  卡死 引用地址:STM32CubeMx + SD Card + FatFs 读写SD卡死等问题

上一篇:STM32 TFT学习笔记——SD卡读写
下一篇:STM32F767 TF卡与FAT文件系统研究

推荐阅读最新更新时间:2024-03-16 16:09

关于STM32单片机移植FATFS
使用单片机的朋友都知道单片机一般提供的ROM和RAM都比较小。就算是STM32这样的提供256KB flash和64KB RAM的。一旦你需要存一些数据量比较大的文件的时候还是不够用的。一般可以通过外扩SD和nand flash来实现大容量存储。相对来说SD卡的使用更加方便一些。使用过nand flash的也许会知道nand flash有坏块,使用的时候需要做坏块管理,还有就是需要做损耗均衡。不然nand flash很容易就会坏掉。 下面说说SD卡。SD卡驱动有两种方式。一种是SPI驱动方式。还有一种是SDIO驱动方式。SPI驱动时只需要4更线:CLK、SD_CS、MISO、MOSI。SDIO则需要CLK、CMD、Data0、Da
[单片机]
LPC11U14实现SD卡U盘
此实验在本人设计的LPC1114/LPC1343/LPC11U14开发板是验证成功:下面先秀秀图吧,下面是三种芯片三种开发板。SD卡在背面。。。 要实现SD卡U盘功能只有实验LPC1343或者LPC11U14才行,因为它们都有USB功能。下面先讲讲大概的思路。 通过USB和PC进行通信,并枚举一个U盘,具体的操作是通过SPI总线操作SD卡。 下面就先看NXP源代码模拟的U盘,和我们修改后实现的SD卡U盘: NXP模拟U盘 SD卡U盘 1.NXP原厂代码免费赠送: USBMem.rar (294.52 KB) 2.本人修改的SD卡U盘,收费哦: SD卡U盘.rar (1.45 MB
[单片机]
LPC11U14实现<font color='red'>SD</font>卡U盘
STM32双缓冲机制初始化(使用STM32CubeMX
1.使用STM32CubeMX配置的串口引脚设置和dma的设置会生成在usart.c。 1)如果DMA接收想采用循环缓冲区的方式,可以直接将RX-DMA设置成Circle方式,然后数据就会硬件上自动实现环形缓冲区的功能,省了不少时间。 2)DMA在采用Normal模式的时候,当一次任务完成后,DMA- DMA_BufferSize自动清零,并且DMA自动停止。如果想再次设置DMA的BufferSize的话,必须要进行如下操作: step1:DMA_CMD(DMAx_Channely,DISABLE); step2: 设置DMA_BufferLen step3:DMA_CMD(DMAx_Channely
[单片机]
派拓网络下一代SD-WAN,大大简化网络运营
随着SD-WAN成为主要的广域网架构,企业要求相应的解决方案能够提供更好的用户体验,同时实现更简单的部署和管理。Palo Alto Networks(派拓网络)的下一代SD-WAN即是采用了一种全新的方法,其方案具有以下特点: ● 应用定义—提供应用层可视化,使网络团队能够创建基于应用的策略,并为所有应用提供服务等级协议(SLA),改善终端用户体验。 ● 自动—利用机器学习和数据科学实现自动化操作和问题规避,消除高达99%的广域网和应用访问故障单。 ● 云交付—实现所有分支机构服务从云端交付,包括联网及安全,简化广域网管理,使分支机构能够将启动服务时间从数月缩短至几分钟。 根据Forrester咨询公司的
[网络通信]
派拓网络下一代<font color='red'>SD</font>-WAN,大大简化网络运营
STM32CubeMX软件工程描述_USART配置过程
Ⅰ、写在前面 学习本文之前可以查看我前面的文章: STM32CubeMX介绍、下载与安装 STM32CubeMX使用方法及功能介绍 STM32CubeMX新建工程+基本IO配置过程 本文接着前面 STM32CubeMX 文章结合USART实例,讲述关于STM32CubeMX新建USART工程,以及新建好完成的软件工程。最终通过STM32CubeMX工具配置完成实现USART串口通信的软件工程。 本文使用 Keil(MDK-ARM) V5 软件为编译环境,如果你没有安装最新版本的软件,请安装Keil(MDK-ARM) V5版本的软件,具体过程可以参考我的一篇文章: MDK-ARM下载与安装 关于本文的更多详情
[单片机]
<font color='red'>STM32CubeMX</font>软件工程描述_USART配置过程
STM32CubeMX图形化配置软件使用
1、RCC(reset and clock control):复位与时钟控制 由上图可知,可以选择三个时钟来源: 1、Disable(失能) ,意味着板子要选择内部时钟。 2、BYPASS Clock Source(旁路时钟源),是指无需使用外部晶体时所需的芯片内部时钟驱动组件,犹如芯片内部的驱动组件被旁路了,也就是无需内部的驱动电路了,直接使用外部的时钟信号。 3、Crystal/Ceramic Resonator(晶体/陶瓷晶振),该时钟源是由外部无源晶体与MCU内部时钟驱动电路共同配合形成,有一
[单片机]
<font color='red'>STM32CubeMX</font>图形化配置软件使用
SD卡在单片机系统上的应用
SD卡在现在的日常生活与工作中使用非常广泛,时下已经成为最为通用的数据存储卡。在诸如MP3、数码相机等设备上也都采用SD卡作为其存储设备。SD卡之所以得到如此广泛的使用,是因为它价格低廉、存储容量大、使用方便、通用性与安全性强等优点。既然它有着这么多优点,那么如果将它加入到单片机应用开发系统中来,将使系统变得更加出色。这就要求对SD卡的硬件与读写时序进行研究。对于SD卡的硬件结构,在官方的文档上有很详细的介绍,如SD卡内的存储器结构、存储单元组织方式等内容。要实现对它的读写,最核心的是它的时序,笔者在经过了实际的测试后,使用51单片机成功实现了对SD卡的扇区读写,并对其读写速度进行了评估。下面先来讲解SD卡的读写时序。 (1
[单片机]
基于ATmega32的SD卡上FAT32文件系统数据读取
   O 引言   SD卡(secure digital memory card,安全数码卡)是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。大小犹如一张邮票的SD记忆卡,重量只有2 g,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性。   本文正是通过AVR单片机经过软硬结合的设计方案,来读取SD卡上FAT32文件系统中的数据,FAT32是微软公司开发的新一代的文件系统,支持更大的存储容量和长达255个字符的文件名,也可以通过串口转USB接口芯片通过
[单片机]
基于ATmega32的<font color='red'>SD</font>卡上FAT32文件系统数据读取
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved