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

📄 sdc_diskio.c

📁 STM32读取SD卡上FAT12_16_32文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (Stat & STA_NODISK) return Stat;	            /* No card in the socket */

    MMC_SPI_Config();
   
    MMC_POWERON();				            /* Force socket power on */
    for(Timer1=50; Timer1; );              

    SPI_LowSpeed();    
    MMC_DESELECT();
    /* Wait for enter Idle state in timeout of 5000 msec */
    Timer1 = 500;
    do{

        for (n = 10; n; n--) SPI_ReadWrite_Byte(0xff);	    /* 80 dummy clocks */
    }
    while((Send_Command(CMD0,0) != 1) && Timer1);

    ty = 0;
    Timer1 = 200;			        /* Initialization timeout of 2000 msec */
    if (Send_Command(CMD8, 0x1AA) == 1) {	    /* 检查是否支持SDC Ver2 */
        for (n = 0; n < 4; n++) 
            ocr[n] = SPI_ReadWrite_Byte(0xff);	/* Get trailing return value of R7 resp */
        if (ocr[2] == 0x01 && ocr[3] == 0xAA) {			
            /* The card can work at vdd range of 2.7-3.6V */
            /* Wait for leaving idle state (ACMD41 with HCS bit) */
            while (Timer1 && Send_Command(ACMD41, 1UL << 30));  				
            if (Timer1 && Send_Command(CMD58, 0) == 0) {		
                /* Check CCS bit in the OCR */
                for (n = 0; n < 4; n++)
                    ocr[n] = SPI_ReadWrite_Byte(0xff);
                /* When CCS bit is set  R/W in block address insted of byte address */
                ty = (ocr[0] & 0x40) ? 12 : 4;
            }
        }
    } else {							
        /* SDSC or MMC */
        if (Send_Command(ACMD41, 0) <= 1) 	{           /* initialize successful will response 0x00 */
            ty = 2; cmd = ACMD41;	/* SDv1 */
        } else {
            ty = 1; cmd = CMD1;		/* MMC */
        }
        while (Timer1 && Send_Command(cmd, 0));			/* Wait for leaving idle state */
        if (!Timer1 || Send_Command(CMD16, 512) != 0)	/* Set R/W block length to 512 */
            ty = 0;
    }

    CardType = ty;	
    SPI_HighSpeed();
    SPI_Release();

    if (ty) {
        /* Initialization succeded */
        Stat &= ~STA_NOINIT;	
        USART1_Puts("Initialization succeded.\n");
    } else {			            
        /* Initialization failed */
        MMC_POWEROFF(); 
        USART1_Puts("Initialization failed.\n");
    }

    return Stat;
}



/*-----------------------------------------------------------------------*/
/* Get Disk Status                                                       */
/*-----------------------------------------------------------------------*/

DSTATUS disk_status (
        BYTE drv		/* Physical drive nmuber (0) */
        )
{
    if (drv) return STA_NOINIT;		/* Supports only single drive */
    return Stat;
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/

DRESULT disk_read (
        BYTE drv,			/* Physical drive nmuber (0) */
        BYTE *buff,			/* Pointer to the data buffer to store read data */
        DWORD sector,		        /* Start sector number (LBA) */
        BYTE count			/* Sector count (1..255) */
        )
{
    if (drv || !count) return RES_PARERR;
    if (Stat & STA_NOINIT) return RES_NOTRDY;

    if (!(CardType & 8)) sector *= 512;	/* Convert to byte address if needed */

    if (count == 1) {	/* Single block read */
        if ((Send_Command(CMD17, sector) == 0)	/* READ_SINGLE_BLOCK */
                && Receive_DataBlock(buff, 512))
            count = 0;
    }
    else {				/* Multiple block read */
        if (Send_Command(CMD18, sector) == 0) {	/* READ_MULTIPLE_BLOCK */
            do {
                if (!Receive_DataBlock(buff, 512)) break;
                buff += 512;
            } while (--count);
            Send_Command(CMD12, 0);				/* STOP_TRANSMISSION */
        }
    }
    SPI_Release();

    return count ? RES_ERROR : RES_OK;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/

#if _READONLY == 0
DRESULT disk_write (
        BYTE drv,			/* Physical drive nmuber (0) */
        const BYTE *buff,	/* Pointer to the data to be written */
        DWORD sector,		/* Start sector number (LBA) */
        BYTE count			/* Sector count (1..255) */
        )
{
    if (drv || !count) return RES_PARERR;
    if (Stat & STA_NOINIT) return RES_NOTRDY;
    if (Stat & STA_PROTECT) return RES_WRPRT;

    if (!(CardType & 8)) sector *= 512;	/* Convert to byte address if needed */

    if (count == 1) {	/* Single block write */
        if ((Send_Command(CMD24, sector) == 0)	/* WRITE_BLOCK */
                && Transmit_DataBlock(buff, 0xFE))
            count = 0;
    }
    else {				/* Multiple block write */
        if (CardType & 6) Send_Command(ACMD23, count);
        if (Send_Command(CMD25, sector) == 0) {	/* WRITE_MULTIPLE_BLOCK */
            do {
                if (!Transmit_DataBlock(buff, 0xFC)) break;
                buff += 512;
            } while (--count);
            if (!Transmit_DataBlock(0, 0xFD))	/* STOP_TRAN token */
                count = 1;                      /* faild */
        }
    }
    SPI_Release();

    return count ? RES_ERROR : RES_OK;
}
#endif /* _READONLY == 0 */



/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/

#if _USE_IOCTL != 0
DRESULT disk_ioctl (
        BYTE drv,		/* Physical drive nmuber (0) */
        BYTE ctrl,		/* Control code */
        void *buff		/* Buffer to send/receive control data */
        )
{
    DRESULT res;
    BYTE n, csd[16], *ptr = buff;
    WORD csize;


    if (drv) return RES_PARERR;

    res = RES_ERROR;

    if (ctrl == CTRL_POWER) {
        switch (*ptr) {
            case 0:		/* Sub control code == 0 (POWER_OFF) */
                if (chk_power())
                    MMC_POWEROFF(); 		/* Power off */
                res = RES_OK;
                break;
            case 1:		/* Sub control code == 1 (POWER_ON) */
                MMC_POWERON();				/* Power on */
                res = RES_OK;
                break;
            case 2:		/* Sub control code == 2 (POWER_GET) */
                *(ptr+1) = (BYTE)chk_power();
                res = RES_OK;
                break;
            default :
                res = RES_PARERR;
        }
    }
    else {
        if (Stat & STA_NOINIT) return RES_NOTRDY;

        switch (ctrl) {
            case CTRL_SYNC :		/* Make sure that no pending write process */
                MMC_SELECT();
                if (Wait_Ready() == 0xFF)
                    res = RES_OK;
                break;

            case GET_SECTOR_COUNT :	/* Get number of sectors on the disk (DWORD) */
                if ((Send_Command(CMD9, 0) == 0) && Receive_DataBlock(csd, 16)) {
                    if ((csd[0] >> 6) == 1) {	/* SDC ver 2.00 */
                        csize = csd[9] + ((WORD)csd[8] << 8) + 1;
                        *(DWORD*)buff = (DWORD)csize << 10;
                    } else {					/* SDC ver 1.XX or MMC*/
                        n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
                        csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
                        *(DWORD*)buff = (DWORD)csize << (n - 9);
                    }
                    res = RES_OK;
                }
                break;

            case GET_SECTOR_SIZE :	/* Get R/W sector size (WORD) */
                *(WORD*)buff = 512;
                res = RES_OK;
                break;

            case GET_BLOCK_SIZE :	/* Get erase block size in unit of sector (DWORD) */
                if (CardType & 4) {			/* SDC ver 2.00 */
                    if (Send_Command(ACMD13, 0) == 0) {		/* Read SD status */
                        SPI_ReadWrite_Byte(0xff);
                        if (Receive_DataBlock(csd, 16)) {				/* Read partial block */
                            for (n = 64 - 16; n; n--) SPI_ReadWrite_Byte(0xff);	/* Purge trailing data */
                            *(DWORD*)buff = 16UL << (csd[10] >> 4);
                            res = RES_OK;
                        }
                    }
                } else {					/* SDC ver 1.XX or MMC */
                    if ((Send_Command(CMD9, 0) == 0) && Receive_DataBlock(csd, 16)) {	/* Read CSD */
                        if (CardType & 2) {			/* SDC ver 1.XX */
                            *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
                        } else {					/* MMC */
                            *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
                        }
                        res = RES_OK;
                    }
                }
                break;

            case MMC_GET_TYPE :		/* Get card type flags (1 byte) */
                *ptr = CardType;
                res = RES_OK;
                break;

            case MMC_GET_CSD :		/* Receive CSD as a data block (16 bytes) */
                if (Send_Command(CMD9, 0) == 0		/* READ_CSD */
                        && Receive_DataBlock(ptr, 16))
                    res = RES_OK;
                break;

            case MMC_GET_CID :		/* Receive CID as a data block (16 bytes) */
                if (Send_Command(CMD10, 0) == 0		/* READ_CID */
                        && Receive_DataBlock(ptr, 16))
                    res = RES_OK;
                break;

            case MMC_GET_OCR :		/* Receive OCR as an R3 resp (4 bytes) */
                if (Send_Command(CMD58, 0) == 0) {	/* READ_OCR */
                    for (n = 4; n; n--) *ptr++ = SPI_ReadWrite_Byte(0xff);
                    res = RES_OK;
                }
                break;

            case MMC_GET_SDSTAT :	/* Receive SD statsu as a data block (64 bytes) */
                if (Send_Command(ACMD13, 0) == 0) {	/* SD_STATUS */
                    SPI_ReadWrite_Byte(0xff);
                    if (Receive_DataBlock(ptr, 64))
                        res = RES_OK;
                }
                break;

            default:
                res = RES_PARERR;
        }

    }
    
    SPI_Release();
    return res;
}
#endif /* _USE_IOCTL != 0 */

DWORD get_fattime (void)
{
    return 0;  
}
/*-----------------------------------------------------------------------*/
/* Device Timer Interrupt Procedure  (Platform dependent)                */
/*-----------------------------------------------------------------------*/
/* This function must be called in period of 10ms                        */

/*
   void disk_timerproc (void)
   {
   static BYTE pv;
   BYTE n, s;


   n = Timer1;						    // 100Hz decrement timer
   if (n) Timer1 = --n;
   n = Timer2;
   if (n) Timer2 = --n;

   n = pv;
   pv = SOCKPORT & (SOCKWP | SOCKINS);	// Sample socket switch 

   if (n == pv) {					    // Have contacts stabled? 
   s = Stat;

   if (pv & SOCKWP)			// WP is H (write protected) 
   s |= STA_PROTECT;
   else						// WP is L (write enabled) 
   s &= ~STA_PROTECT;

   if (pv & SOCKINS)			// INS = H (Socket empty) 
   s |= (STA_NODISK | STA_NOINIT);
   else						// INS = L (Card inserted) 
   s &= ~STA_NODISK;

   Stat = s;
   }
   }
   */

⌨️ 快捷键说明

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