f_read 返回FR_OK ,但是读取的数据长度一直是0的现象:打开的是一个较小文件(不足1k)是能正确获取文件大小信息,打开一个较大文件(1.87MB)时返回FR_OK,文件大小信息是0
原因:SDIO时钟频率过低
我使用的是stm32f407vet6 通过sdio方式和SD卡通信
问题发现解决过程:
1、在问题出现前stm32使用的系统时钟频率是168mhz,为使产品符合低功耗要求降低频率至50mhz运行后出现问题,遂猜测和问题原因可能和系统时钟频率有关
2、通过逻辑分析仪检测SDIO 的CLK脚发现 在系统时钟为50MHZ时CLK脚频率为7mhz左右,168mhz 时CLK脚频率为24mhz左右。7mhz 时 f_open无法正确获取文件大小信息, 24mhz 时 f_open正确获取文件大小信息(强烈建议逻辑分析仪的采样频率要保证是被检测频率的10倍才能保证采样结果不失真!)
3、通过cube了解到stm32f407vet6的sdio 的工作频率范围为187khz-24mhz
工作频率计算方法为SDIO_CK = SDIOCLK / [CLKDIV + 2],其中CLKDIV(分频值)我的代码中已经设置为0
50MHZ时时钟配置如下,此时SDIOCLK为14.285mhz, SDIOCLK / [CLKDIV + 2]=7mhz,印证逻辑分析仪的采样结果,由cube时钟树图知上述公式中SDIOCLK的值取决于PLL中的Q值
系统时钟为50mhz时Q为2时超频,Q为3频率还是低
适当提高系统时钟频率为60mhz Q为3 ,f_open 打开文件后文件大小信息正确 增加的功耗在可承受范围, 完美解决问题。
系统时钟配置函数如下 配置时注意和cube中时钟树比对 以防出错!
/*******************************************************************************
函数功能 : 系统时钟设置
输 入 : PLL_OR_HSE-- 1-PLL 倍频 0--HSE 8MHZ
RCC_SYSCLK_Divx 系统时钟分频 注意对照CUBE里配置 时钟树末端不得出现小数
@arg RCC_SYSCLK_Div1: AHB clock = SYSCLK
@arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2
@arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4
@arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8
@arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16
@arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64
@arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128
@arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256
@arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512
输 出 : 无
使用方法 :
系统上电时、在功耗模式切换时调用 PLL_OR_HSE为1时使用PLL倍频 PLL_OR_HSE为0时不使用PLL 系统时钟为8MHZ
更改分频数时注意对照CUBE里配置 时钟树末端不得出现小数
STM32F407vet6--PCLK1最大42mhz 注意分频数
STM32F407vet6--PCLK2最大84mhz 注意分频数
*******************************************************************************/
void RCC_Configuration(uint8_t PLL_OR_HSE, uint32_t RCC_SYSCLK_Divx)
{
//----------使用外部RC晶振-----------
RCC_DeInit(); // 初始化为缺省值
RCC_HSEConfig(RCC_HSE_ON); // 使能外部的高速时钟
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); // 等待外部高速时钟使能就绪
RCC_HCLKConfig(RCC_SYSCLK_Divx); // HCLK = SYSCLK/Divx
RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK /2 36Mhz STM32F407vet6--PCLK2最大84mhz 注意分频数
if (PLL_OR_HSE) // PLL
{
RCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1 = HCLK/2 36Mhz STM32F407vet6--PCLK1最大42mhz 注意分频数
RCC_PLLConfig(RCC_PLLSource_HSE, 4, 60, 2, 3); // PLLCLK = 8MHZ * 7 =72MHZ
RCC_PLLCmd(ENABLE); // Enable PLLCLK
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}; // Wait till PLLCLK is ready
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock
while (RCC_GetSYSCLKSource() != 0x08)
; // Wait till PLL is used as system clock source
}
else
{
RCC_PCLK1Config(RCC_HCLK_Div1); // PCLK1 = HCLK/2 2Mhz
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET)
{
}; // Wait till PLLCLK is ready
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); // Select PLL as system clock
while (RCC_GetSYSCLKSource() != 0x04)
; // Wait till PLL is used as system clock source
* be one of the following:
* - 0x00: HSI used as system clock
* - 0x04: HSE used as system clock
* - 0x08: PLL used as system clock
}
}
至于SDIO低频时FATFS不能正常工作,高频时正常工作真正原因,搜了资料 大概好像是SDIO接口在低频率下的时序要求更加严格。由于低频传输速率较慢,时序的准确性对于数据的采样和传输至关重要。如果时序不准确或受到噪声等干扰,可能导致数据传输错误或中断,从而影响通信的稳定性。低频通信下,由于时钟速率较低,相对更容易受到电源噪声的影响。不稳定的电源供应可能导致信号质量下降、数据传输错误或中断,从而影响通信的稳定性。一般而言,在低频通信时增加传输时钟频率可以提高低频通信的稳定性。较高的传输时钟频率更容易满足各项要求,并且较短的传输时间减少了潜在的干扰和错误的机会。