1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
| #include <p18f46k22.h> //head file.
#define cs LATBbits.LATB0 //define sd pin.
#define SSP1IF PIR1bits.SSP1IF
unsigned char r1=0;
void delay_100ms(void);
void spi_init(void); //spi init
void spi_low(void); //produce low band func(sd card init use.)
void spi_high(void); //produce high band func(sd card init use.)
unsigned char sd_reset(void); //sd card init func
unsigned char SD_SendCommand(char CMD, unsigned long arg, char CRC); //write sd card command func
unsigned char SPI_WriteByte(unsigned char val); //write one byte func.
unsigned char SPI_ReadByte(void); //receive one byte func.
/////////////////////////////////////////////////
//main
void main()
{
unsigned char res;
spi_init();
while(1)
{
res= sd_reset(); //sd card init.
if(res) break; //if init is abnormal,exit and don't perform the next func.
}
}
////////////////////////////////////////////////
//spi init
void spi_init()
{
TRISCbits.TRISC5=0; // SDO declarer en sortie
TRISCbits.TRISC3=0; //SCK est declarer en sortie sur le maitre
TRISCbits.TRISC4=1; // SDI declarer en entree
SSP1STAT=0x80; // rising edge,send data.
SSP1CON1=0x32; //high when idle.fosc/64
}
unsigned char SD_SendCommand(char CMD, unsigned long sct, char CRC)
{
unsigned char r1;
//unsigned char adrss;
unsigned char retry1=0; //repeat count.
cs=0; //enable cs signal.
SPI_WriteByte(CMD); //write command.
SPI_WriteByte(sct>>24); //data segment the 4th byte.
SPI_WriteByte(sct>>16); //data segment the 3th byte.
SPI_WriteByte(sct>>8); //data segment the 2nd byte.
SPI_WriteByte(sct); //data segment the 1st byte.
SPI_WriteByte(CRC); //CRC check sum.
while((r1 = SPI_WriteByte(0xff)) == 0xff)//wait ack.
{
if(retry1++ > 100) break; //overtime exit.
}
cs=1; //clear cs.
return r1; //return the status value.
}
////////////////////////////////////////////////
//set low band.
void spi_low()
{
SSP1CON1=0x31; //SPI clk use the system clk--fosc/64 0x32
}
////////////////////////////////////////////////
//set high band.
void spi_high()
{
SSP1CON1=0x32; //SPI clk use the system clk--fosc/64 0x31
}
///////////////////////////////////////////////
//write one byte.
unsigned char SPI_WriteByte(unsigned char val)
{
SSP1BUF = val; //load to send buffer
while(!SSP1IF); //wait to finish sending.
SSP1IF=0; //clear send finish flag.
return SSP1BUF; //read the receive buffer(even the data is unvalid,it is still need cleared.)
}
////////////////////////////////////////////////
//SD reset.
unsigned char sd_reset()
{
unsigned char i,tmp;
unsigned char retry; //repeat times.
retry=0;
//spi_low(); //use low band.
do
{
spi_low();
for(i=0;i<10;i++) SPI_WriteByte(0xff);
r1=SD_SendCommand(0x40, 0, 0x95);
retry++;
//if(retry>10) return 1; //overtime exit.
} while(r1 != 0x01); //wait IDLE command return.
retry = 0;
SPI_WriteByte(0xff);
r1 = SD_SendCommand(0x48, 0x1AA, 0x87);
if(r1 == 0x01)
{
do
{
for(i=0;i<100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(0x41, 1UL << 30, 0xFF);
retry++;
if(retry>100) return 1; //overtime exit.
} while(r1);
}
else
{
do
{
for(i=0;i<100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(0x41, 0, 0xFF);
retry++;
if(retry>100) return 1; //overtime exit.
} while(r1); //wait Active command exit.
}
spi_high(); //use high band.
return 0; //return normal.
} |
Partager