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

📄 sdcardnotworking.c

📁 PIC18F4550 SD CARD USB
💻 C
📖 第 1 页 / 共 2 页
字号:
 */   
/******************************************************************************
 * Function:        SDC_RESPONSE SendSDCCmd(BYTE cmd, DWORD address)
 *
 *
 * Input:           None
 *                  
 * Output:          response            - Response from the card
 *                                      - 0x00 or 0x01 Command received 
 *                                        successfully, else, command failed
 *                  -Bit 0              - In idle state if 1
 *                  -Bit 1              - Erase Reset if 1
 *                  -Bit 2              - Illgal Command if 1
 *                  -Bit 3              - Com CRC Error if 1
 *                  -Bit 4              - Erase Sequence Error if 1
 *                  -Bit 5              - Address Error if 1
 *                  -Bit 6              - Parameter Error if 1
 *                  -Bit 7              - Not used, always '0'
 *
 * Side Effects:    None
 *
 * Overview:        SendSDCCmd prepares the command packet and sends it out
 *                  over the SPI interface. Response data of type 'R1' or 'R2' for SEND_STATUS command (see
 *                  SD or MMC product manuals) is returned.
 *
 * Note:            SDC_CS is not set at the end of this function.
 *                  if the command has no data stage, call macro
 *                  mSendMediaCmd_NoData(), it reasserts SDC_CS to 1.
 *                  If the command has a data stage, SDC_CS must be
 *                  reasserted after the data transfer stage is complete.
 *                  See SECTORread and SECTORwrite for examples.
 *****************************************************************************/
SDC_RESPONSE SendSDCCmd(byte cmd, dword address)
{        
    word timeout = 8;
	byte index;
	SDC_RESPONSE response;
	CMD_PACKET CmdPacket;
	    
    SDC_CS = 0;                           //Card Select
    
    // Copy over data
    CmdPacket.cmd        = sdmmc_cmdtable[cmd].CmdCode;
    CmdPacket.address    = address;
    CmdPacket.crc        = sdmmc_cmdtable[cmd].CRC;       // Calc CRC here
    
    
    WriteSPI(CmdPacket.cmd);                //Send Command
   	WriteSPI(CmdPacket.addr3);              //Most Significant Byte
    WriteSPI(CmdPacket.addr2);
   	WriteSPI(CmdPacket.addr1);
    WriteSPI(CmdPacket.addr0);              //Least Significant Byte
    WriteSPI(CmdPacket.crc);                //Send CRC

    // see if  we are going to get a response    
    if(sdmmc_cmdtable[cmd].responsetype == R1 || sdmmc_cmdtable[cmd].responsetype == R1b)
    {
        do
        {
            response.r1._byte = ReadMedia();
            timeout--;
        }while((response.r1._byte == 0xFF) && (timeout != 0));
    }
    else if(sdmmc_cmdtable[cmd].responsetype == R2)
    {
        ReadMedia();
        
        response.r2._byte1 = ReadMedia();
        response.r2._byte0 = ReadMedia();
    }
    
    if(sdmmc_cmdtable[cmd].responsetype == R1b)
    {
		response.r1._byte = 0x00;
		
		for(index =0; index < 0xFF && response.r1._byte == 0x00; index++)
		{
	        timeout = 0xFFFF;
	           
	        do
	        {
	            response.r1._byte = ReadMedia();
	            timeout--;
	        }while((response.r1._byte == 0x00) && (timeout != 0)); 
		}
    }
        
    mSend8ClkCycles();                      //Required clocking (see spec)
 
    // see if we are expecting data or not
    if(!(sdmmc_cmdtable[cmd].moredataexpected))
        SDC_CS = 1;
    
    return(response);        
}

/******************************************************************************
 * Function:        BYTE ReadMedia(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *                  
 * Output:          BYTE    - One byte of data read in from SPI port
 *
 * Side Effects:    None
 *
 * Overview:        ReadMedia reads in one byte of data while sending out 0xFF
 *
 * Note:            Could not use ReadSPI because it initializes SSPBUF to
 *                  0x00. The card expects 0xFF (see spec).
 *****************************************************************************/
byte ReadMedia(void)
{
    SSPBUF = 0xFF;                              //Data Out - Logic ones
    while(!SSPSTATbits.BF);                     //Wait until cycle complete
    return(SSPBUF);                             //Return with byte read 
}//end ReadMedia

void Delayms(byte milliseconds)
{
	T1CON = 0xB0;
	
	//enable interrupt
	TMR1IE = 1;

	do {
		// load timer
		TMR1H = high(0xFFFF - MILLISECDELAY);
		TMR1L = low(0xFFFF - MILLISECDELAY);
	
		// clear flag
		TMR1IF = 0;

		// turn on timer
		TMR1ON = 1;

		// wait for it to be done
		while(!TMR1IF)
		{
			;
		}

		// turn off timer
		TMR1ON = 0;

		// Making a little more accurate
		Nop();
		Nop();

		milliseconds--;
   	}while(milliseconds > 0);

Error:   
	// now turn everything off 
	TMR1ON = 0;
	TMR1IE = 0;
}


/******************************************************************************
 * Function:        SDC_Error SECTORread(DWORD sector_addr, BYTE *buffer)
 *
 * PreCondition:    None
 *
 * Input:           sector_addr - Sector address, each sector contains 512-byte
 *                  buffer      - Buffer where data will be stored, see
 *                                'ram_acs.h' for 'block' definition.
 *                                'Block' is dependent on whether internal or
 *                                external memory is used
 *                  
 * Output:          See SDC_Error.
 *
 * Side Effects:    None
 *
 * Overview:        SECTORread reads 512 bytes of data from the card starting
 *                  at the sector address specified by sector_addr and stores
 *                  them in the location pointed to by 'buffer'.
 *
 * Note:            The card expects the address field in the command packet
 *                  to be byte address. Therefore the sector_addr must first
 *                  be converted to byte address. This is accomplished by
 *                  shifting the address left 9 times.
 *****************************************************************************/
SDC_Error SECTORread(dword sector_addr, byte* buffer)
{
    word index;
    SDC_RESPONSE    response;
    byte data_token;
    SDC_Error status = sdcValid;
/*
	#ifdef STATUSLED
	STTRIS = OUTPUT;
	STLED = 1;
	#endif
*/
    // send the cmd
    response = SendSDCCmd(READ_SINGLE_BLOCK,(sector_addr << 9));

    // Make sure the command was accepted
    if(response.r1._byte != 0x00)
    {
        status = sdcCardBadCmd;
    }
    else
    {
        index = 0x2FF;                                     
     
        //Now, must wait for the start token of data block   
        do
        {
            data_token = ReadMedia();
            index--;
        }while((data_token == SDC_FLOATING_BUS) && (index != 0));
    
        // Hopefully that zero is the datatoken 
        if((index == 0) || (data_token != DATA_START_TOKEN))
            status = sdcCardTimeout;
        else
        {
            for(index = 0; index < SDC_SECTOR_SIZE; index++)                    //Reads in 512-byte of data
			{
					buffer[index] = ReadMedia();
            	//#ifdef 	 DEBUG_SDMMC
				//	U8toHexString(buffer[index],string);

				//	if((index % 0x10) == 0x00)
				//		DEBUG_PRINT("\n\r");

				//	DEBUG_PRINT_RAM((char*)string);
					
				//	DEBUG_PRINT(" ");
				// #endif
            }  
            // Now ensure CRC    
            mReadCRC();                                 //Read 2 bytes of CRC
            //status = mmcCardCRCError;
        }
        
        mSend8ClkCycles();                          //Required clocking (see spec)
    }

    SDC_CS = 1;

//	#ifdef STATUSLED
//	STLED = 0;
//	#endif

    return(status);
}//end SECTORread

/******************************************************************************
 * Function:        MMC_Error SECTORwrite(DWORD sector_addr, BYTE *buffer)
 *
 * PreCondition:    None
 *
 * Input:           sector_addr - Sector address, each sector contains 512-byte
 *                  buffer      - Buffer where data will be read, see
 *                                'ram_acs.h' for 'block' definition.
 *                                'Block' is dependent on whether internal or
 *                                external memory is used
 *                  
 * Output:          See MMC_Error.
 *
 * Side Effects:    None
 *
 * Overview:        SECTORwrite sends 512 bytes of data from the location
 *                  pointed to by 'buffer' to the card starting
 *                  at the sector address specified by sector_addr.
 *
 * Note:            The card expects the address field in the command packet
 *                  to be byte address. Therefore the sector_addr must first
 *                  be converted to byte address. This is accomplished by
 *                  shifting the address left 9 times.
 *****************************************************************************/
SDC_Error SECTORwrite(dword sector_addr, byte* buffer)
{
    word index;
    byte data_response;
	SDC_RESPONSE    response; 
    SDC_Error status = sdcValid;
  	/*
	#ifdef STATUSLED
	STTRIS = OUTPUT;
	STLED = 1;
	#endif
	*/
    // send the cmd
    response = SendSDCCmd(WRITE_SINGLE_BLOCK,(sector_addr << 9));
   
    // see if it was accepted
    if(response.r1._byte != 0x00) {
        status = sdcCardBadCmd;
	} else {
        WriteSPI(DATA_START_TOKEN);                 //Send data start token
        
        for(index = 0; index < 512; index++)                    //Send 512 bytes of data
            WriteSPI(buffer[index]);
            
        // calc crc    
        mSendCRC();                                 //Send 2 bytes of CRC
        
        data_response = ReadMedia();                //Read response
        
        if((data_response & 0x0F) != DATA_ACCEPTED)
        {
            status = sdcCardDataRejected;
        }
        else
        {
            index = 0;                                      //using i as a timeout counter
            
            do                                          //Wait for write completion
            {
                data_response = ReadMedia();
                index++;
            }while((data_response == 0x00) && (index != 0));
            
            if(index == 0)                                  //if timeout first
                status = sdcCardTimeout;
        }
        
        mSend8ClkCycles();        
    }
    
    SDC_CS = 1;
    /*
	#ifdef STATUSLED
	STLED = 0;
	#endif
	*/
  	return(status);
} //end SECTORwrite


/*****************************************************************
 Return the state of the WP Pin
 *****************************************************************/
byte WriteProtectState(void)
{
    return(MEDIA_WD);
}

// ShutdownMedia
// Simply turn off the card
//
void ShutdownMedia(void)
{
    // close the spi bus
    CloseSPI();
    
    // deselect the device
    SDC_CS = 1;                               
    
    // Turn off the card
    // SDC_OFF;        
}

/******************************************************************************
 * Function:        SDC_Error CSDread(BYTE *buffer)
 *
 * PreCondition:    None
 *
 * Input:           buffer      - Buffer where data will be stored
 *                  
 * Output:          See SDC_Error.
 *
 * Side Effects:    None
 *
 * Overview:        CSDread reads Card Specific Data (CSD) from the card by issuing the 
 					CMD9 SEND_CSD command. The contents of CSD register are used to find the 
 					card size. Response type for SEND_CSD is R1
 *****************************************************************************/
SDC_Error CSDread()
{
    word index, timeout=0x2ff;
    SDC_RESPONSE response;
    byte data_token;
    SDC_Error status = sdcValid;
    byte cmd=SEND_CSD;
    dword address=0x00;
	CMD_PACKET CmdPacket;
	    
    SDC_CS = 0;                           //Card Select
    
    // Copy over data
    CmdPacket.cmd        = sdmmc_cmdtable[cmd].CmdCode;
    CmdPacket.address    = address;
    CmdPacket.crc        = sdmmc_cmdtable[cmd].CRC;       // Calc CRC here
    
    
    WriteSPI(CmdPacket.cmd);                //Send Command
    WriteSPI(CmdPacket.addr3);              //Most Significant Byte
    WriteSPI(CmdPacket.addr2);
    WriteSPI(CmdPacket.addr1);
    WriteSPI(CmdPacket.addr0);              //Least Significant Byte
    WriteSPI(CmdPacket.crc);                //Send CRC

    // see if  we are going to get a response    

    do
    {
            response.r1._byte = ReadMedia();
            timeout--;
    } while((response.r1._byte == 0xFF) && (timeout != 0));
  
    //mSend8ClkCycles();                      //Required clocking (see spec)
 
    // see if we are expecting data or not
   // if(!(sdmmc_cmdtable[cmd].moredataexpected))
    //   SDC_CS = 1;
    
    // Make sure the command was accepted
    if(response.r1._byte != 0x00)
    {
        status = sdcCardBadCmd;
    }
    else
    {
        index = 0x2FF;                                     
     
        //Now, must wait for the start token of data block   
        do
        {
            data_token = ReadMedia();
            index--;
        }while((data_token == SDC_FLOATING_BUS) && (index != 0));
    
        // Hopefully that zero is the datatoken 
        if((index == 0) || (data_token != DATA_START_TOKEN))
            status = sdcCardTimeout;
        else
        {
            for(index = 0; index < CSD_SIZE; index++)                    //Reads in 16-byte of data
			{
					gblCSDReg._byte[index] = ReadMedia();
            }  
            // Now ensure CRC    
            // mReadCRC();                                 //Read 2 bytes of CRC
            //status = mmcCardCRCError;
        }
        
        mSend8ClkCycles();                          //Required clocking (see spec)
    }

    SDC_CS = 1;
    return(status);
}//end CSDread

⌨️ 快捷键说明

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