分享

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

 goodwangLib 2019-05-16

一、环境
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) { } }
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

  • 19

  • 20

  • 21

  • 22

  • 23

  • 24

  • 25

  • 26

  • 27

  • 28

  • 29

  • 30

  • 31

  • 32

  • 33

  • 34

  • 35

  • 36

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

  • 48

  • 49

  • 50

  • 51

  • 52

  • 53

  • 54

  • 55

  • 56

  • 57

  • 58

  • 59

  • 60

四、问题
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){	//...}
  • 1

  • 2

  • 3

  • 4

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

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

  • 2

  • 3

  • 4

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

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);	//硬件SPI1RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);	//硬件SPI2
  • 1

  • 2

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

  • 2

  • 3

  • 4

  • 5

  • 6

五、资料
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文件系统时编译报错空间不够

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多