stm32f103c8t6移植Fatfs文件系统出现的一些问题

一、环境
keil5,使用库函数

二、移植对象
stm32f103zet6 >> stm32f103c8t6

三、连接方式
硬件SPI1(PA5,6,7)

四、主函数代码

#include "stdio.h"

#include "delay.h"
#include "sys.h"
#include "oled.h"

#include "malloc.h"  
#include "MMC_SD.h"   
#include "ff.h"  
#include "exfuns.h"

void SD_Read_Sectorx(u32 sec);

int main(void)
{	
	u32 total,free;
	
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//设置NVIC中断分组2:2位抢占优先级,2位响应优先级 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 	LED_Init();			     //LED端口初始化

	OLED_Init();			//初始化OLED  
	OLED_Clear();
	OLED_ShowString(0,0,"OLED ready",12);
	delay_ms(1000);
	OLED_Fill(0,0,127,7,0);//清除显示	
	delay_ms(1000);
	exfuns_init();		//为fatfs相关变量申请内存	
	mem_init();				//初始化内存池	 
	
	while(SD_Initialize())					//检测SD卡
	{
		OLED_ShowString(0,0,"SD Card Error!",12);
		delay_ms(200);
		OLED_Fill(0,0,127,7,0);//清除显示		  
		delay_ms(200);
		//LED0=!LED0;//DS0闪烁
	}								   	
 	exfuns_init();							//为fatfs相关变量申请内存				 
	f_mount(fs[0],"0:",1); 					//挂载SD卡 
	while(exf_getfree("0",&total,&free))	//得到SD卡的总容量和剩余容量
	{
		OLED_ShowString(0,0,"Fatfs Error!",12);
		delay_ms(200);
		OLED_Fill(0,0,127,7,0);//清除显示				  
		delay_ms(200);
		//LED0=!LED0;//DS0闪烁
	}	
	
	OLED_ShowString(0,0,"FATFS OK!",12);	 
	OLED_ShowString(0,1,"Total:     MB",12);	 
	OLED_ShowString(0,2,"Free :     MB",12); 	    
 	OLED_ShowNum(48,1,total>>10,5,12);					//显示SD卡总容量 MB
 	OLED_ShowNum(48,2,free>>10,5,12);		
	
	while(1) 
	{		

	}	  
	
}

四、问题
0.移植准备
①修改device为STM32F103C8
②将C/C++中define“STM32F10X_HD,USE_STDPERIPH_DRIVER”改为“STM32F10X_HD,USE_STDPERIPH_DRIVER”
③更换相应的启动文件(.s)

1.编译报错内存不足
①从工程中删除cc936.c等文件,c8t6装不下
②mallco.h中#define MEM_MAX_SIZE 421024改小,测试101024可用,需保证编译结果后面两个size的和小于20k
③#define _CODE_PAGE 936 改为 #define _CODE_PAGE 1 使用ascii码减少存储开销
④相应#define _LFN_UNICODE 0 和 #define _STRF_ENCODE 0 ,使用ascii

2.程序死在while(SD_Initialize())中
①强烈建议检查连线,特别是SLK
②最好单片机单独供电而不是使用仿真器供电,可能由于供电不足导致spi初始化的高电平不符合要求
③如果使用仿真器调试时卡在此处,可能是卡在以下代码

while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==RESET)
{
	//...
}

百度到的解释是“rxne只能读一次,如果调试器读取了,那么程序就永远读不到了”,此外SPI运行时有一定几率程序会卡死在检查接受标志位处RXNE,论坛上的解决方案是将检查接受标志位改为检查忙状态,所以可以换成

while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET)
{
	//...
}

经测试此方案可行。
④如果改为SPI2,可能是SPI2时钟初始化的问题。SPI1的时钟在APB2上而SPI2的在APB1上,初始化需调用不同的函数。如:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);	//硬件SPI1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);	//硬件SPI2

3.程序死在while(exf_getfree(“0”,&total,&free))中
①一般来说不会在这句话中卡住,卡住了检查下连线吧
②设置SPI为高速模式时可能由于时钟太快导致初始化不成功(也可能是初始化之后的部分导致无法正常使用,ZET6没有这个问题而C8T6存在),可以适当降低高速模式的时钟

//SD卡正常工作的时候,可以高速了
void SD_SPI_SpeedHigh(void)
{
 	//SPI1_SetSpeed(SPI_BaudRatePrescaler_2);//原函数	
	SPI1_SetSpeed(SPI_BaudRatePrescaler_4);//修改
}

五、资料
1.SPI存储器W25X16,Debug时卡在SPI_I2S_GetFlagStatus(SPI1, 2.SPI_I2S_FLAG_RXNE
3.SPI调试小结
4.fatfs文件系统移植 读写时莫名出现FR_DISK_ERR问题
5.死循环了:while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET);
6.SPI/I2S调试总结
7.F103C8T6移植Fatfs文件系统时编译报错空间不够

扫描二维码关注公众号,回复: 5469886 查看本文章

猜你喜欢

转载自blog.csdn.net/redgragon0/article/details/84963374