⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disk.c

📁 Atmega64单片机程序(完整工程)
💻 C
字号:
#define   IN_DISK 

#include "SYS_Config.h" 
#include "FS_Config.h"
#include "USART1.h"
#include "fat.h" 


Disk_Info DiskInfo[MAX_DRIVES];//逻辑盘信息
/*********************************************************************************************************
** 函数名称: DiskInit
** 功能描述: 初始化逻辑盘管理模块
** 输   入: 无
** 输   出: 无
** 全局变量: DiskInfo
** 调用模块: 无
********************************************************************************************************/
void DiskInit(void)
{
    INT8U i ;
    
    for(i=0;i<MAX_DRIVES;i++)
    {
        DiskInfo[i].Drive=EMPTY_DRIVE ;       // 没有分配
        DiskInfo[i].FATType=0xff ;            // 无效的文件系统
        DiskInfo[i].SecPerClus=0 ;            // 每簇扇区数
        DiskInfo[i].NumFATs=0 ;               // FAT表数
        DiskInfo[i].SecPerDisk=0xffffffff ;   // 逻辑驱动器包含扇区数
        DiskInfo[i].BytsPerSec=0 ;            // 每扇区字节数
        DiskInfo[i].RootDirTable=0 ;          // 根目录开始扇区号(FAT32为开始簇号)
        DiskInfo[i].RootSecCnt=0 ;            // 根目录占用扇区数
        DiskInfo[i].FATStartSec=0 ;           // FAT表开始扇区号
        DiskInfo[i].FATSecCnt=0 ;             // 每个FAT占用扇区数
        DiskInfo[i].DataStartSec=0 ;          // 数据区开始扇区号
        DiskInfo[i].PathClusIndex=0 ;         // 当前目录
        DiskInfo[i].DiskCommand=NULL ;        // 驱动程序
    }
    CacheInit();
    //初始化磁盘cache
}

/*********************************************************************************************************
** 函数名称: GetDiskInfo
** 功能描述: 获取指定逻辑盘信息
** 输   入: 逻辑盘号
** 输   出: 指向逻辑盘信息的结构体指针
** 全局变量: DiskInfo
** 调用模块: 无
********************************************************************************************************/
Disk_Info *GetDiskInfo(INT8U Drive)
{
    Disk_Info *Rt ;
    Rt=NULL ;
    
    if(Drive<MAX_DRIVES)
    {
        if(DiskInfo[Drive].Drive!=EMPTY_DRIVE)
        {
            Rt=DiskInfo+Drive ;
        }
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: GetEmptyDiskInfoAddr
** 功能描述: 获取空闲逻辑盘
** 输   入: 无
** 输   出: 指向逻辑盘信息的结构体指针
** 全局变量: DiskInfo
** 调用模块: 无
********************************************************************************************************/
Disk_Info *GetEmptyDiskInfoAddr(void)
{
    INT8U i ;
    Disk_Info *Rt ;
    
    Rt=NULL ;
    for(i=0;i<MAX_DRIVES;i++)
    {
        // 逻辑盘号空闲
        if(DiskInfo[i].Drive==EMPTY_DRIVE)
        {
            Rt=DiskInfo+i ;
            DiskInfo[i].Drive=i ;
            break ;
        }
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: AddFileDriver
** 功能描述: 增加一个底层驱动程序
** 输   入: DiskCommand:驱动程序接口函数
** 输   出: 无
** 全局变量: DiskInfo
** 调用模块: 无
********************************************************************************************************/
void AddFileDriver( INT16U(* DiskCommand)(INT8U Command,void *Parameter) )
{ 
    INT8U  i ;
    INT8U  *Buf ;
    INT16U temp ;
    INT32U temp1 ;
    
    if(DiskCommand==NULL)// 参数无效退出
    {
        return ;
    }
    
    if(DiskCommand(DISK_INIT,NULL)==DISK_INIT_NOT_OK)// 底层驱动初始化不成功退出
    {
        #if FS_DEBUG_EN
	    #if USART1_EN
	        Uart1_SendString("\nSD/MMC INIT NOT OK");//调试用,初始化失败
	    #endif
	    #endif
		
        return ;
    }
    
    for(i=0;i<MAX_DRIVES;i++)/* 重新获取逻辑盘信息 */
    {
        /* 逻辑盘已分配 */
        if(DiskInfo[i].Drive!=EMPTY_DRIVE)
        {
            Buf=OpenSec(DiskInfo[i].Drive,0);/* 打开扇区0(保留扇区) */
            ReadSec(DiskInfo[i].Drive,0);
	    
            if(Buf!=NULL)
            {
                /* 每扇区字节数 */
                DiskInfo[i].BytsPerSec=((INT16U)Buf[12]<<8)+Buf[11];
	            #if FS_DEBUG_EN
		        #if USART1_EN
	            {   
	                Uart1_SendString("\n 1.BytsPerSec:");//调试用,每扇区字节数
	                PUT_INT32U_DecTOString(DiskInfo[i].BytsPerSec);
	            }
		        #endif
	            #endif
	      
		/* 每簇扇区数 */
                DiskInfo[i].SecPerClus=Buf[13];
		        #if FS_DEBUG_EN
		        #if USART1_EN
	            {
	                Uart1_SendString("\n 2.SecPerClus:");//调试用 ,每簇扇区数
	                PUT_INT32U_DecTOString(DiskInfo[i].SecPerClus);
	            }
	            #endif
		        #endif
               
	        /* FAT开始扇区号 */
                DiskInfo[i].FATStartSec=((INT16U)Buf[15]<<8)+Buf[14];
				#if FS_DEBUG_EN
				#if USART1_EN
	      		{
	                Uart1_SendString("\n 3.FATStartSec:");//调试用 ,FAT开始扇区号
	                PUT_INT32U_DecTOString(DiskInfo[i].FATStartSec);
	        	}
	        	#endif
				#endif
                
		 /* FAT表占用扇区数 */
                temp=((INT32U)Buf[23]<<8)+Buf[22];
                if(temp!=0)
                    DiskInfo[i].FATSecCnt=temp ;
                else 
                {
                    DiskInfo[i].FATSecCnt=((INT32U)Buf[37]<<8)+Buf[36];
                    DiskInfo[i].FATSecCnt|=(((INT32U)Buf[38]<<16)+((INT32U)Buf[39]<<24));
                }
		#if FS_DEBUG_EN
		#if USART1_EN
	        {
	            Uart1_SendString("\n 4.FATSecCnt:");//FAT表占用扇区数
	            PUT_INT32U_DecTOString(DiskInfo[i].FATSecCnt);
	        }
	        #endif
		#endif
		
		/* FAT表个数 */
                DiskInfo[i].NumFATs=Buf[16];
		#if FS_DEBUG_EN
		#if USART1_EN
	        {
	            Uart1_SendString("\n 5.NumFATs:");//调试用 ,FAT表个数
	            PUT_INT32U_DecTOString(DiskInfo[i].NumFATs);
	        }
	        #endif
		#endif
                
		/* 根目录占扇区数 */
                DiskInfo[i].RootSecCnt=((((INT16U)Buf[18]<<8)+Buf[17])*32+DiskInfo[i].BytsPerSec-1)/DiskInfo[i].BytsPerSec ;
		#if FS_DEBUG_EN
		#if USART1_EN
	        {
	            Uart1_SendString("\n 6.RootSecCnt:");//根目录占扇区数
	            PUT_INT32U_DecTOString(DiskInfo[i].RootSecCnt);
	        }
	        #endif
		#endif
		
                /* 逻辑盘(卷)占扇区数 */
                temp=((INT16U)Buf[20]<<8)+Buf[19];
                if(temp!=0)
                    DiskInfo[i].SecPerDisk=temp ;
                else 
                {
                    DiskInfo[i].SecPerDisk=((INT32U)Buf[33]<<8)+Buf[32];
                    DiskInfo[i].SecPerDisk|=(((INT32U)Buf[34]<<16)+((INT32U)Buf[35]<<24));
                }
		#if FS_DEBUG_EN
		#if USART1_EN
	        {
	            Uart1_SendString("\n 7.SecPerDisk:");//逻辑盘(卷)占扇区数
	            PUT_INT32U_DecTOString(DiskInfo[i].SecPerDisk);
	        }
	        #endif
		#endif
		
                DiskInfo[i].PathClusIndex=0 ;/* 当前目录为根目录 */
		
                /* 根目录开始扇区号 */
                DiskInfo[i].RootDirTable=DiskInfo[i].NumFATs*DiskInfo[i].FATSecCnt+DiskInfo[i].FATStartSec ;
                #if FS_DEBUG_EN
		#if USART1_EN
	        {
	            Uart1_SendString("\n 8.RootDirTable:");//根目录开始扇区号
	            PUT_INT32U_DecTOString(DiskInfo[i].RootDirTable);
	        }
	        #endif
		#endif
	    
	        /* 数据区开始扇区号 */
                DiskInfo[i].DataStartSec=DiskInfo[i].RootDirTable+DiskInfo[i].RootSecCnt ;
                #if FS_DEBUG_EN
		#if USART1_EN
	        {
	            Uart1_SendString("\n 9.DataStartSec:");//数据区开始扇区号
	            PUT_INT32U_DecTOString(DiskInfo[i].DataStartSec);
	        }
	        #endif
		#endif
	    
	        temp1=DiskInfo[i].SecPerDisk-DiskInfo[i].DataStartSec ;
                temp1=temp1/DiskInfo[i].SecPerClus ;
                DiskInfo[i].ClusPerData=temp1 ;
           
	        /* 判断是FAT12、FAT16还是FAT32 */
                if(temp1<4085)
                {
	            DiskInfo[i].FATType=FAT12 ;
	            #if FS_DEBUG_EN
		    #if USART1_EN
	                Uart1_SendString("\n10.File System is FAT12\n");//调试用 
		    #endif
		    #endif
                }
                else if(temp1<65525)
                {
	            DiskInfo[i].FATType=FAT16 ;
	            #if FS_DEBUG_EN
		    #if USART1_EN
	                Uart1_SendString("\n10.File System is FAT16\n");//调试用 
		    #endif 
		    #endif
                }
                else 
                {
	            DiskInfo[i].FATType=FAT32 ;
	            #if FS_DEBUG_EN
		    //#if USART1_EN
	                Uart1_SendString("\n10.File System is FAT32\n");//调试用 
		    //#endif
		    #endif
	
                    /* FAT32 RootDirTable为开始簇号 */
                    DiskInfo[i].RootDirTable= ((INT32U)Buf[45]<<8)+Buf[44];
                    DiskInfo[i].RootDirTable|=(((INT32U)Buf[46]<<16)+((INT32U)Buf[47]<<24));
                    DiskInfo[i].PathClusIndex=DiskInfo[i].RootDirTable ;
                }
	    }    
            CloseSec(DiskInfo[i].Drive,0);/* 关闭扇区 */
        }
    }
}

/*********************************************************************************************************
** 函数名称: RemoveFileDriver
** 功能描述: 删除一个底层驱动程序
** 输   入: Drive:逻辑驱动器号
** 输   出: 无
** 全局变量: DiskInfo
** 调用模块: 无
********************************************************************************************************/
void RemoveFileDriver(INT8U Drive)
{
    Disk_RW_Parameter Pa ;
    
    if(Drive<MAX_DRIVES)
    if(DiskInfo[Drive].Drive!=EMPTY_DRIVE)
    {
        AllCacheWriteBack();
        Pa.Drive=Drive ;
        Pa.RsvdForLow=DiskInfo[Drive].RsvdForLow ;
        DiskInfo[Drive].DiskCommand(DISK_CLOSE,&Pa);
        
        DiskInfo[Drive].Drive=EMPTY_DRIVE ;    // 没有分配
        DiskInfo[Drive].FATType=0xff ;         // 无效的文件系统
        DiskInfo[Drive].SecPerClus=0 ;         // 每簇扇区数
        DiskInfo[Drive].NumFATs=0 ;            // FAT表数
        DiskInfo[Drive].SecPerDisk=0xffffffff ;// 逻辑驱动器包含扇区数
        DiskInfo[Drive].BytsPerSec=0 ;         // 每扇区字节数
        DiskInfo[Drive].RootDirTable=0 ;       // 根目录开始扇区号(FAT32为开始簇号)
        DiskInfo[Drive].RootSecCnt=0 ;         // 根目录占用扇区数
        DiskInfo[Drive].FATStartSec=0 ;        // FAT表开始扇区号
        DiskInfo[Drive].FATSecCnt=0 ;          // 每个FAT占用扇区数
        DiskInfo[Drive].DataStartSec=0 ;       // 数据区开始扇区号
        DiskInfo[Drive].PathClusIndex=0 ;      // 当前目录
        DiskInfo[Drive].DiskCommand=NULL ;     // 驱动程序
    }
}


/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -