参考基于stm32的fat32文件系统.docx
《参考基于stm32的fat32文件系统.docx》由会员分享,可在线阅读,更多相关《参考基于stm32的fat32文件系统.docx(61页珍藏版)》请在冰豆网上搜索。
![参考基于stm32的fat32文件系统.docx](https://file1.bdocx.com/fileroot1/2023-1/24/a84fb248-a051-4857-ab94-2e7d3c171890/a84fb248-a051-4857-ab94-2e7d3c1718901.gif)
参考基于stm32的fat32文件系统
(参考)基于stm32的fat32文件系统
Main.c
/************************************************************************STM32-3.2寸TFT液晶屏字符和汉字显示程序*
**
***********************************************************************/
#include"stm32f10x_lib.h"
#include"LCD_driver.h"
#include"fat.h"
#include"MMC.h"
structFAT32_Init_ArgInit_Arg_SD;//初始化参数结构体实体
structFAT32_Init_Arg*pArg;
structFileInfoStructFileInfo;//文件信息结构体实体
ucharfile_buf[150];//文件数据缓冲区,读取到的文件数据放在其中
ucharDev_No=0;//设备号,SDCARD的SD卡设备号的宏定义,根据设备号,znFAT会将底
层存储设备驱动连接到相应的存储设备驱动
//动态的切换设备号,就可以实现在各种存储设备之间进行切
换,这也是znFAT实现多设备的重要手段。
比如,我
//可以将SD卡上的文件拷贝到CF卡或U盘上,这就是多设备
的最典型应用
#defineCOLOR(r,g,b)(((((((uint)r)>>3)<<6)|(((uint)g)>>2))<<5)|(((uint)b)>>3))//r红色分量
0~31g绿色分量0~63b蓝色分量0~31
#include"LCD.c"
/********************************变量定义
---------------------------------------------------------*/GPIO_InitTypeDefGPIO_InitStructure;
ErrorStatusHSEStartUpStatus;
unsignedcharcsd_data[16];
unsignedcharcid_data[16];
unsignedcharby;
unsignedintc_size,c_size_mult,read_bl_len;unsignedlongdrive_size;
unsignedlongsize_mb;
/*********************************声明函数-----------------------------------------------*/
voidRCC_Configuration(void);
voidNVIC_Configuration(void);
voidDelay(vu32nCount);
/******************************************************************************
*
主函数
*******************************************************************************
/
intmain(void)
{
ucharitem;
RCC_Configuration();//系统时钟配置函数
NVIC_Configuration();//NVIC配置函数
//启动GPIO模块时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|
RCC_APB2Periph_AFIO,ENABLE);
//把调试设置普通IO口
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;//所有GPIO为同一类型端口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出的最大频率为50HZ
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIOA端口
GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化GPIOB端口
GPIO_Write(GPIOA,0xffff);//将GPIOA16个端口全部置为高电平
GPIO_Write(GPIOB,0xffff);//将GPIOB16个端口全部置为高电平
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15;//所有GPIO为同一类型端口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出的最大频率为50HZ
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIOA端口
LCD_Init();
LCD_clear
(2);//这句是显示背景颜色。
T_CS
(1);
//SD卡初始化
MMC_Reset();
MMC_Init();
if(Init_Flag==0)LCD_ShowString(20,5,colors[0],colors[7],"SDSUCCESS");
elseLCD_ShowString(20,5,colors[0],colors[7],"SDFAILURE");
pArg=&Init_Arg_SD;//pArg是znFAT的“初始参数结构指针”,它所指向的结构体中记录了存储器及其文件系统的重要参数信息
//在切换存储设备时,不光要更改设备号,还要将pArg指向相应存储设备的“初始参数结构”
Dev_No=SDCARD;//设备号为SDCARD,znFAT中将其宏定义为0
FAT32_Init();//文件系统初始化,使用znFAT前必须进行初始化,初始化过程中将所使用的存储设备的文件系统的一些重要参数
//记录到了pArg所指向的结构中,以备后面使用
item=0;
while
(1)
{UINT8rRe;
rRe=FAT32_Open_File(&FileInfo,"\\*.bmp",item);
if(rRe==0)//打开成功,则显示图像
{
display_pic();
item++;
}
elseitem=0;
}
}
/******************************************************************************
*
*配置RCC
*******************************************************************************
/
voidRCC_Configuration(void)
{
//复位RCC外部设备寄存器到默认值
RCC_DeInit();
//打开外部高速晶振
RCC_HSEConfig(RCC_HSE_ON);
//等待外部高速时钟准备好
HSEStartUpStatus=RCC_WaitForHSEStartUp();
if(HSEStartUpStatus==SUCCESS)//外部高速时钟已经准别好
{
//开启FLASH的预取功能
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//FLASH延迟2个周期
FLASH_SetLatency(FLASH_Latency_2);
//配置AHB(HCLK)时钟=SYSCLK
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//配置APB2(PCLK2)钟=AHB时钟
RCC_PCLK2Config(RCC_HCLK_Div1);
//配置APB1(PCLK1)钟=AHB1/2时钟
RCC_PCLK1Config(RCC_HCLK_Div2);
//配置PLL时钟==外部高速晶体时钟*9PLLCLK=8MHz*9=72MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
//使能PLL时钟
RCC_PLLCmd(ENABLE);
//等待PLL时钟就绪
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
{
}
//配置系统时钟=PLL时钟
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//检查PLL时钟是否作为系统时钟
while(RCC_GetSYSCLKSource()!
=0x08)
{
}
}
}
/*******************************************************************************
*NVIC配置函数
*******************************************************************************/
voidNVIC_Configuration(void)
{
#ifdefVECT_TAB_RAM
/*SettheVectorTablebaselocationat0x20000000*/
NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
#else/*VECT_TAB_FLASH*/
/*SettheVectorTablebaselocationat0x08000000*/
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
#endif
}
/*******************************************************************************
*延时函数
*******************************************************************************/
voidDelay(vu32nCount)
{
for(;nCount!
=0;nCount--);
}
#ifdefDEBUG
/*******************************************************************************
*FunctionName:
assert_failed
*Description:
Reportsthenameofthesourcefileandthesourcelinenumber*wheretheassert_paramerrorhasoccurred.
*Input:
-file:
pointertothesourcefilename
*-line:
assert_paramerrorlinesourcenumber*Output:
None
*Return:
None
*******************************************************************************/
voidassert_failed(u8*file,u32line)
{
/*Usercanaddhisownimplementationtoreportthefilenameandlinenumber,
ex:
printf("Wrongparametersvalue:
file%sonline%d\r\n",file,line)*/
/*Infiniteloop*/
while
(1)
{
}
}
#endif
mmc.c
#include"MMC.h"
unsignedcharInit_Flag;//Setitto1whenInitisprocessing.unsignedcharcard_type;
voidNOP(void);
unsignedcharCMD[]={0x40,0x00,0x00,0x00,0x00,0x95};//CMD0
/**********************************************************
延时子函数
**********************************************************/voiddelay(unsignedinttime)
{
while(time--);
}
/**********************************************************
us延时子程序(4.34us)
**********************************************************/voiddelayNOP()
{
NOP();
NOP();
NOP();
NOP();
}
/**********************************************************
延时程序
**********************************************************/voidNOP()
{vu16i;
for(i=0;i<10;i++);
}
/************************************************************
卡端口初始化
************************************************************/
voidMMC_Port_Init()
{
//SPI_CLK=1;
GPIO_SetBits(GPIOA,SPI_CLK);//置位LCD_RS
//SPI_DO=1;
GPIO_SetBits(GPIOA,SPI_DO);
//SPI_CS=1;
GPIO_SetBits(GPIOA,SPI_CS);}
/******************************************************************
-功能描述:
IO模拟SPI,发送一个字节
-隶属模块:
SD卡模块
-函数属性:
内部
-参数说明:
x是要发送的字节
-返回说明:
无返回
-注:
其中is_init为1时,写的速度放慢,初始化SD卡SPI速度不能太高
******************************************************************/
voidWrite_Byte_MMC(ucharvalue){
unsignedchari;
for(i=0;i<8;i++)
{
if(value&0x80)
//SPI_DI=1;//Sendbitbybit(MSBFirst)
GPIO_SetBits(GPIOA,SPI_DI);
else
//SPI_DI=0;
GPIO_ResetBits(GPIOA,SPI_DI);
//SPI_CLK=0;//Clocklow
GPIO_ResetBits(GPIOA,SPI_CLK);
if(Init_Flag)
delayNOP();
//SPI_CLK=1;//ClockHigh
GPIO_SetBits(GPIOA,SPI_CLK);
if(Init_Flag)
delayNOP();
value<<=1;
}
}
/******************************************************************
-功能描述:
IO模拟SPI,读取一个字节
-隶属模块:
SD卡模块
-函数属性:
内部
-参数说明:
无
-返回说明:
返回读到的字节
******************************************************************/
unsignedcharRead_Byte_MMC()
{
unsignedchartemp=0;
unsignedchari;
//SPI_DO=1;
GPIO_SetBits(GPIOA,SPI_DO);
for(i=0;i<8;i++)//MSBFirst
{
//SPI_CLK=0;//ClockLow
GPIO_ResetBits(GPIOA,SPI_CLK);
if(Init_Flag)
delayNOP();
//SPI_CLK=1;//ClockHigh
GPIO_SetBits(GPIOA,SPI_CLK);
if(Init_Flag)
delayNOP();
temp=(temp<<1)|GPIO_ReadInputDataBit(GPIOA,SPI_DO);//readmmcdataout
pin
}
return(temp);
}
/******************************************************************
-功能描述:
向SD卡写命令
-隶属模块:
SD卡模块
-函数属性:
内部
-参数说明:
SD卡的命令是6个字节,pcmd是指向命令字节序列的指针
-返回说明:
命令写入后,SD卡的回应值,调用不成功,将返回0xff
******************************************************************/
unsignedcharWrite_Command_MMC(unsignedchar*CMD)
{
unsignedchartmp;
unsignedchari;
GPIO_SetBits(GPIOA,SPI_CS);
Write_Byte_MMC(0xFF);//提高兼容性,如果没有这里,有些SD卡可能不支持
GPIO_ResetBits(GPIOA,SPI_CS);
//send6ByteCommandtoMMC/SD-Card
for(i=0;i<0x06;i++)
{
Write_Byte_MMC(*CMD++);
}
i=0;
//get16bitresponse
Read_Byte_MMC();//readthefirstbyte,ignoreit.
do
{//Onlylast8bitisusedhere.Readitout.
tmp=Read_Byte_MMC();
i++;
}
while((tmp==0xff)&&(i<100));
return(tmp);
}
/******************************************************************
-功能描述:
复位SD卡,用到CMD0,使用SD卡切换到SPI模式
-隶属模块:
SD卡模块
-函数属性:
内部
-参数说明:
无
-返回说明:
调用成功,返回0x00,否则返回INIT_CMD0_ERROR(sd.h中有定义)
******************************************************************/
unsignedcharMMC_Reset(void)//SD卡复位,进入SPI模式,使用CMD0(0号命令){
uchartime,temp,i;
ucharpcmd[]={0x40,0x00,0x00,0x00,0x00,0x95};
//SD_SCL=1;
//SD_SO=1;
//SD_CS=1;
GPIO_SetBits(GPIOA,SPI_CS);
Init_Flag=1;//Settheinitflag
for(i=0;i<0x0f;i++)//初始时,首先要发送最少74个时钟信号,这是必须的~~~
{
Write_Byte_MMC(0xff);//120clk
}
//SD_CS=0;
GPIO_ResetBits(GPIOA,SPI_CS);
time=0;
do
{
temp=Write_Command_MMC(pcmd);//写入CMD0
time++;
if(time>=TRY_TIME)
{
return(INIT_CMD0_ERROR);//CMD0写入失败
}
}while(temp!
=0x01);
//SD_CS=1;
GPIO_SetBits(GPIOA,SPI_CS);
//SD_spi_write(0xff);//按照SD卡的操作时序在这里补8个时钟
return0;//返回0,说明复位操作成功
}
/******************************************************************
-功能描述:
初始化SD卡,使用CMD1
-隶属模块:
SD卡模块
-函数属性:
内部
-参数说明:
无
-返回说明:
调用成功,返回0x00,否则返回INIT_CMD1_ERROR(sd.h中有定义)
***********