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

📄 cf.c

📁 使用PIC24 16位单片机 读写SD卡 支持FAT32
💻 C
📖 第 1 页 / 共 2 页
字号:
	    	        dsk->type = FAT16;
	    	    }
	    	    else
	    	        /* Volume is FAT32 */
	    	        // We don't support FAT32
	    	        error = CE_CARDFAT32;     
			}
	                	        
	        // 6.5 DATA = ROOT + (MAXIMUM ROOT *32 / 512) 
	        dsk->data = dsk->root + ( dsk->maxroot >> 4); // assuming maxroot % 16 == 0!!!
	        
	        // make sure that we can read in a complete sector!
	        if(BytesPerSec != MEDIA_SECTOR_SIZE)
	            error = CE_NOT_FORMATTED;
		}
    }

	return(error);
}


//----------------------------------------------------------------------
// Init CARD interface (I/Os)
//

BYTE MediaInit( void)
{
	CFRST = 0;
	RESETDIR = OUTPUT;
	CFCE = 1;
	CFCEDIR = OUTPUT;
	OE = 1;
	OEDIR = OUTPUT;
	WE = 1;
	WEDIR = OUTPUT;
	CFRDY = 0;
	READYDIR = INPUT;
	CFCD1 = 0;	
	CD1DIR = INPUT;

	ADRTRIS0 = 0;		// AD0-3
	ADRTRIS1 = 0;
	ADRTRIS2 = 0;
	ADRTRIS3 = 0;
	DATABinput;		    // D0-7 input

	return (StartupCard (&glbDiskData) == CE_GOOD);
	
} // CFinit

//----------------------------------------------------------------------
// Check for CF card presence
// 
//  returns     TRUE if a card is present

BYTE MediaDetect( void)
{
    return (CFCD1 == 0) ? TRUE : FALSE ; // test for CD1 pull down
} //CFDetect


BYTE WriteProtectState (void)
{
	return 0;
}


void CFwait(void)
{
	while(CFRDY == 0);
}

//----------------------------------------------------------------------
// CFread   Read contents of a CF register 
// 
// returns     register content

BYTE CFread( BYTE add)
// add  :   register address
{
	char d;
	char test1, test2, test3, test4;
	CFwait();
	DATABinput;     // make the databus input
	test1 = (BYTE)(add & 0x01) == 0x01;
	test2 = (BYTE)(add & 0x02) == 0x02;
	test3 = (BYTE)(add & 0x04) == 0x04;
	test4 = (BYTE)(add & 0x08) == 0x08;
	ADDR0 = (BYTE)(add & 0x01) == 0x01;	// publish the register address
	ADDR1 = (BYTE)(add & 0x02) == 0x02;
	ADDR2 = (BYTE)(add & 0x04) == 0x04;
	ADDR3 = (BYTE)(add & 0x08) == 0x08;
	CFCE = 0;    // select the CF card
	Nop();
	OE = 0;    // output enable
	Nop();
	d = DATABIN;      // get the data
	Nop();
	OE = 1;    
	CFCE = 1;
	return d;
} // CFread


//----------------------------------------------------------------------
// CFwrite  write in a CF register 
// 

void CFwrite( BYTE add, BYTE d)
// add  : CF register 
// d    : data
{
	CFwait();
	OE = 1;      // make sure the output is disabled first
	DATABoutput;    // make the bus output
	ADDR0 = (add & 0x01) == 0x01;	// publish the register address
	ADDR1 = (add & 0x02) == 0x02;
	ADDR2 = (add & 0x04) == 0x04;
	ADDR3 = (add & 0x08) == 0x08;
	DATABOUT = d;      // publish the data
	CFCE = 0;    // select the CF card
	Nop();
	WE = 0;    // strobe write
	Nop();
	WE = 1;
	CFCE = 1;
} // CFwrite




//----------------------------------------------------------------------
// Read a Sector of data
//

BYTE SECTORread( DWORD lda, BYTE * buf)
// lda  sector absolute address
// buf  working buffer
// cmd  sector read or drive identify
{
	BYTE	test = 0, notest = 0, threetest = 0;
	BYTE	testfive, testsix, testseven, testeight, testnine;

	WORD i = 0;

	#ifdef STATUSLED
	STTRIS = OUTPUT;
	STLED = 1;
	#endif

 	CFwrite( R_COUNT, 1); 
	test = CFread (R_STATUS);
 	CFwrite( R_SECT, lda);
	test = CFread (R_STATUS);
 	CFwrite( R_CYLO, lda>>8);
	test = CFread (R_STATUS);
 	CFwrite( R_CYHI, lda>>16);
	test = CFread (R_STATUS);
 	CFwrite( R_DRIVE, ((BYTE)(lda>>24) & 0xf)|0xe0);  // always select card #0
	test = CFread (R_STATUS);
 	CFwrite( R_CMD, cmdREAD_SECTORS);

 	while ((test = CFread( R_STATUS)) != S_READY)
 	{

		if (CFread (R_STATUS) == S_ERROR)
 		{
 			return FALSE;
 		}
//Code to check errors if error bit is set
		if ((test == 0x01))
		{
			notest = CFread (R_ERROR);
			CFwrite (R_DRIVE, 0xA0);
			CFwrite (R_CMD, 0x03);
			threetest = CFread (R_ERROR);
			while(1);
		}
 	}

	ADDR0 = (R_DATA & 0x01) == 0x01;	// publish the register address
	ADDR1 = (R_DATA & 0x02) == 0x02;
	ADDR2 = (R_DATA & 0x04) == 0x04;
	ADDR3 = (R_DATA & 0x08) == 0x08;
	DATABinput;         // make the databus input
    CFCE = 0;        // CF selected 
	
	while (i < 512)
	{
		OE = 0;
		buf[i++] = DATABIN;
		OE = 1;
	}

    CFCE = 1;        // CF deselected when done

	#ifdef STATUSLED
	STLED = 0;
	#endif


	return TRUE; 		
} // read_sector


//----------------------------------------------------------------------
// Write a Sector of data
//

BYTE SECTORwrite( DWORD lda, BYTE * buf)
// lda   sector lda 
// buf   512 byte block
{
	WORD i;
	BYTE d;

	if (lda == 0)
		return FALSE;

	#ifdef STATUSLED
	STTRIS = OUTPUT;
	STLED = 1;
	#endif

 	CFwrite( R_COUNT, 1); 
 	CFwrite( R_SECT, lda);
 	CFwrite( R_CYLO, lda>>8);
 	CFwrite( R_CYHI, lda>>16);
 	CFwrite( R_DRIVE, ((BYTE)(lda>>24) & 0xf)|0xe0);  // always select card #0

 	CFwrite( R_CMD, C_SECTOR_WRITE);

 	while (CFread( R_STATUS) != S_READY)
 	{
 		if (CFread( R_STATUS) == S_ERROR)
 		{
 			return FALSE;
 		}
 	}

	ADDR0 = (R_DATA & 0x01) == 0x01;	// publish the register address
	ADDR1 = (R_DATA & 0x02) == 0x02;
	ADDR2 = (R_DATA & 0x04) == 0x04;
	ADDR3 = (R_DATA & 0x08) == 0x08;
	DATABoutput;         // make the databus output
    CFCE = 0;        // CF selected 
 	for ( i=0; i<512; i++)
 	{
 		DATABOUT = RAMread( buf, 0);  // read data
 	    WE = 0;                  // WE enable
 		WE = 1;                  // WE disable
 		buf++;
    }
    CFCE = 1;        // CF deselected when done
   
	#ifdef STATUSLED
	STLED = 0;
	#endif

	return TRUE; 		
} // write_sector




void StopCard (DISK * dsk)
{
	dsk->mount = FALSE;
	return;
}





#ifdef EXTERNAL_BUS_DIAGNOSTIC
//----------------------------------------------------------------------
// BUS diagnostic test
//
void BUStest( void)
{
	TRISE = 0xff;		// all bus and ctl lines in input
	TRISJ = 0xff;
	TRISH = 0xff;
	TRISG = 0xff;

	// test all pins port E, ADDBL
	LATE = 0xff;
	TRISE = 0xfe;		// turn on pin 0
	Rlncf(	TRISE,1,0);	// pin 1
	Rlncf(	TRISE,1,0);	// pin 2
	Rlncf(	TRISE,1,0);	// pin 3
	Rlncf(	TRISE,1,0);	// pin 4
	Rlncf(	TRISE,1,0);	// pin 5
	Rlncf(	TRISE,1,0);	// pin 6
	Rlncf(	TRISE,1,0);	// pin 7
	TRISE = 0xff;

	// test all pins port F, CTRL
	LATJ = 0xff;
	TRISJ = 0xfe;		// turn on pin 0, SYNC
	Rlncf(	TRISJ,1,0);	// pin 1, RAMCE
	Rlncf(	TRISJ,1,0);	// pin 2, CFCE
	Rlncf(	TRISJ,1,0);	// pin 3, WE
	Rlncf(	TRISJ,1,0);	// pin 4, OE
	TRISJ = 0xff;


	// test all pins port H, ADDBH
	LATH = 0xff;
	TRISH = 0xfe;		// turn on pin 0
	Rlncf(	TRISH,1,0);	// pin 1
	Rlncf(	TRISH,1,0);	// pin 2
	Rlncf(	TRISH,1,0);	// pin 3
	TRISH = 0xff;


	// test all pins port D, DATAB
	LATG = 0xff;
	TRISG = 0xfD;		// turn on pin 0
	Rlncf(	TRISG,1,0);	// pin 3
	Rlncf(	TRISG,1,0);	// pin 4
	Rlncf(	TRISG,1,0);	// pin 5
	TRISG = 0xff;
	
} //BUStest

#endif


BYTE ReadByte( BYTE* pBuffer, WORD index )
{
	return( pBuffer[index] );
}

WORD ReadWord( BYTE* pBuffer, WORD index )
{
	BYTE loByte, hiByte;
	WORD res;

	loByte = pBuffer[index];
	hiByte = pBuffer[index+1];
	res = hiByte;
	res *= 0x100;
	res |= loByte;
	return( res );
}


DWORD ReadDWord( BYTE* pBuffer, WORD index )
{
	WORD loWord, hiWord;
	DWORD result;

	loWord = ReadWord( pBuffer, index );
	hiWord = ReadWord( pBuffer, index+2 );

	result = hiWord;
	result *= 0x10000;
	result |= loWord;
	return result;
}

⌨️ 快捷键说明

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