Red de conocimiento informático - Problemas con los teléfonos móviles - Problema de inicialización de la tarjeta SD

Problema de inicialización de la tarjeta SD

Encuentre el motivo usted mismo. Tenga en cuenta que cuando la tarjeta SD no está inicializada, la frecuencia CLK de comunicación SPI debe ser baja.

Parece que el máximo no supera los 400KHZ

#include "..\inc\includes.h"

#include "New_sd.h"

sbit c_SPI_CS = P2^4; //Sht-mp3 Config

//establecer MMC_Chip_Select en alto (MMC/tarjeta SD no válida)

#define SD_Disable () c_SPI_CS = 1

//establecer MMC_Chip_Select en nivel bajo (MMC/tarjeta SD activa)

#define SD_Enable() c_SPI_CS = 0

sbit c_SPI_SI = P1^ 5;

sbit c_SPI_SO = P1^6;

sbit c_SPI_CLK = P1^7;

sbit c_SD_In = P2^7;

sbit c_SD_WP = P2^6;

sbit c_SD_Power = P2^3;

#define Macro_Set_SI_High() c_SPI_SI = 1

#define Macro_Set_SI_Low () c_SPI_SI = 0

#define Macro_Set_CLK_High() c_SPI_CLK = 1

#define Macro_Set_CLK_Low() c_SPI_CLK = 0

//bool bSPICLK_LowSpeed;

vacío estático SD_PowerOn(vacío)

{

c_SD_Power = 0;

}

/*

vacío estático SD_PowerOff(void)

{

c_SD_Power = 1

}

*/

/ /extern uint8 BUFFER[512];

uint8 SD_SPI_ReadByte(void);

void SD_SPI_WriteByte(uint8 ucSendData);

//#define SPI_ReadByte () SD_SPI_ReadByte ()

//#define SPI_TransferByte(x) SD_SPI_WriteByte(x)

/*

static uint8 SPI_ReadByte(void)

{

uchar ucReadData

uchar ucCount

ucReadData = 0

Macro_Set_SI_High();

for(ucCount=0; ucCountlt; 8; ucCount )

{

ucReadData lt;lt;= 1;

p>

//Reducir la frecuencia del reloj

Macro_Set_CLK_Low();

//Reducir la frecuencia del reloj

// if(bSPICLK_LowSpeed)

// {

// Delay_100us();

// }

Macro_Set_CLK_High()

/ / if (bSPICLK_LowSpeed)

// {

// Delay_100us()

// }

if(c_SPI_SO)

{

ucReadData |= 0x01

}

}

return(ucReadData);

// SPDR = 0xFF;

// while (!(SPSR amp; 0x80));

// return SPDR;

static void SPI_TransferByte(uint8 ucSendData)

{

uchar ucCount

uchar ucMaskCode

ucMaskCode; = 0x80 ;

for(ucCount=0; ucCountlt; 8; ucCount )

{

Macro_Set_CLK_Low();

if( ucMaskCode amp; ucSendData)

{

Macro_Set_SI_High()

}

más

{

Macro_Set_SI_Low();

}

//Reducir la frecuencia del reloj

// if(bSPICLK_LowSpeed)

/ / {

// Delay_100us();

// }

Macro_Set_CLK_High()

ucMaskCode gt; ;

//Reducir la frecuencia del reloj

// if(bSPICLK_LowSpeed)

// {

// Delay_100us();

// }

}

//SPDR=cmp1;

//mientras(!(SPS

Rampa; (1lt; lt; SPIF)));

}

*/

static uint8 SPI_ReadByte(void)

{

uchar ucReadData

uchar ucCount

ucReadData = 0

Macro_Set_SI_High()

para (ucCount=0; ucCountlt; 8; ucCount )

{

ucReadData lt;lt;= 1;

//Reducir la frecuencia del reloj

Macro_Set_CLK_Low();

//Reduce la frecuencia del reloj

// if(bSPICLK_LowSpeed)

// {

/ /Delay_100us();

// }

Macro_Set_CLK_High();

// if(bSPICLK_LowSpeed)

// {

// Delay_100us();

// }

if(c_SPI_SO)

{

ucReadData | = 0x01;

}

}

return(ucReadData

// SPDR = 0xFF; p >// while (!(SPSR amp; 0x80));

// return SPDR

}

static void SPI_TransferByte(uint8 ucSendData) < / p>

{

uchar ucCount;

uchar ucMaskCode;

ucMaskCode = 0x80

for(ucCount=0; ; ucCountlt; 8; ucCount )

{

Macro_Set_CLK_Low()

if(ucMaskCode y ucSendData)

{

Macro_Set_SI_High()

}

más

{

Macro_Set_SI_Low(); > }

//Reducir la frecuencia del reloj

// if(bSPICLK_LowSpeed)

// {

//

Delay_100us();

// }

Macro_Set_CLK_High();

ucMaskCode gt; Frecuencia de reloj

// if(bSPICLK_LowSpeed)

// {

// Delay_100us();

// }

}

//SPDR=cmp1;

// while(!(SPSRamp;(1lt;lt;SPIF)));

}

void SD_Port_Init(void)

//*************************** *** ************************************************* **

{

c_SPI_SO = 1;

c_SD_In = 1

c_SD_WP = 1; SD_PowerOn() ;

}

//****************************** *** **********************************************

//Enviar un comando a MMC/SD-Card

//Retorno: el segundo byte del registro de respuesta de MMC/SD-Card

uint8 Write_Command_SD(uint8 *cmd)

//*************************************** *************************************

{

uint8 tmp, i;

uint8 retry=0;

SD_Disable()

SPI_TransferByte(0xFF); p> SD_Enable();

for(i=0;ilt;6;i)

{

SPI_TransferByte(*cmd);

}

p>

SPI_ReadByte();

hacer{

tmp = SPI_ReadByte(); while((tmp==0xff)amp; amp ;(reintentar lt;100));

return(tmp);

}

//* *********** **************************************** ************ ****

********

//Enviar un comando a MMC/tarjeta SD

//Retorno: el segundo byte del registro de respuesta de MMC/tarjeta SD

uint8 Write_Command_SD_HighSpeed(uint8 *cmd)

//****************************** ***********************************************

{

uint8 tmp, i;

uint8 retry=0;

SD_Disable()

SD_SPI_WriteByte( 0xFF);

SD_Enable();

for(i=0;ilt;6;i)

{

SD_SPI_WriteByte( *cmd

}

SD_SPI_ReadByte();

hacer{

tmp = SD_SPI_ReadByte(); p> } while((tmp==0xff)amp;amp;(retry lt;100));

return(tmp);

}

//************************************************ ******************************

//Rutina para inicio de tarjeta MMC/SD (MODO SPI )

uint8 SD_Init(void)

//****************************** ** *************************************************

{

reintento uint8, temp;

uint8 i

uint8 CMD[] = {0x40, 0x00, 0x00, 0x00 , 0x00, 0x95 };

SD_Port_Init(); //Iniciar puerto SPI

// para (i = 0; i lt; 200; i ) asm("nop") ; //Espera MMC/SD listo...

for (i = 0; i lt; 200; i )

{

_nop_();

}

//Bus SPI activo a baja velocidad

// SPCR=0x53 //SPI Master, MSB First

// SPSR= 0x00; //doble

le speed deshabilitar, Fsck=Fosc/128

for (i = 0; i lt; 16; i )

SPI_TransferByte(0xff); //¡enviar 74 relojes al menos! !

//Enviar comando CMD0 a tarjeta MMC/SD

SD_Enable()

reintentar = 0

hacer p>

{ //reintentar 200 veces para enviar el comando CMD0

temp = Write_Command_SD(CMD

if (reintentar == 200)

<); p> return INIT_CMD0_ERROR; //¡Error CMD0!

}

while (temp != 1);

//Enviar comando CMD1 a MMC/SD- Tarjeta

CMD[0] = 0x41; //Comando 1

CMD[5] = 0xFF

reintento = 0; > do

{ //reintentar 100 veces para enviar el comando CMD1

temp = Write_Command_SD(CMD

if (retry == 100)

return INIT_CMD1_ERROR; //¡Error CMD1!

}

while (temp != 0);

//Modo SPI activo de alta velocidad (Fsck =Fosc/2)

// SPCR = 0x50;

// SPSR = 0x00

SD_Disable() //establece MMC_Chip_Select en alto;

return INIT_OK; //Se han tomado todos los comandos.

}

uint8 SD_Read_Block(uint8 *CMD, uint8 *Buffer, uint16 Bytes)

//********************************************* *******************************

{

uint16 i;

p>

uint8 retry, temp;

//Enviar comando CMD a MMC/tarjeta SD

retry=0;

//#if 1

do

{ //Reintentar 100 veces para enviar el comando.

// temp=Write_Command_SD(CMD) ;

>

temp=Write_Command_SD_HighSpeed(CMD);

if(retry == 100)

return READ_BLOCK_ERROR //¡bloquear error de escritura!

}

while (temp != 0);

//Leer el byte de inicio de la tarjeta MMC/SD (FEh/Byte de inicio)

while (SPI_ReadByte() != 0xfe);

//#endif

//Leer bloques (normal 512 Bytes) en MMC/tarjeta SD

#if 1

for (i = 0; i lt; Bytes; i) //int count for loop cost 13 ciclo de máquina

{

// *Buffer = SPI_ReadByte() ; //Costo 70 ciclos de máquina

//Cuando el punto definido es un punto Xdata, entonces costo 62 ciclos de máquina

*Buffer = SD_SPI_ReadByte() //Costo 70 ciclos de máquina

p>

// put_c(*Buffer);

}

#endif

/*

i = Bytes;

while(i--) //Cuando se elimina {} 2 ciclos de máquina se guarda.

*Buffer = SPI_ReadByte() //Costo 70 ciclos de máquina

*/

//CRC-Byte

SPI_ReadByte(); //CRC - Byte

SPI_ReadByte() //CRC - Byte

p>

//establece MMC_Chip_Select en alto (MMC/tarjeta SD no válida)

SD_Disable();

devuelve READ_BLOCK_OK;

}

//********************************************* *********************************

//Rutina para escribir un bloque (512Byte) a MMC/Tarjeta SD

//Devuelve 0 si la escritura del sector es

completado.

uint8 SD_read_sector(uint32 addr, uint8 *Buffer)

//************************ ************************************************** * ****

{

//El comando 16 lee bloques de la tarjeta MMC/SD

uint8 CMD[] = {0x51, 0x00, 0x00, 0x00, 0x00, 0xFF};

// asm("cli"); //borrar todas las interrupciones.

//Dirección de conversación(dirección del bloque lógico--gt; dirección de bytes)

addr = addr lt; //addr = addr * 512

CMD[1] = ((addr amp; 0xFF000000) gt; gt; 24);

CMD[2] = ((dirección amp; 0x00FF0000) gt; gt; 16

CMD[3] = ((dirección amp; 0x0000FF00) gt; gt; 8); );

return SD_Read_Block(CMD, Buffer, 512);

}

/*

uint8 SD_write_sector(dirección uint32, uint8 *Búfer)

//*************************************** ** ****************************************

{

uint8 tmp, retry;

uint16 i;

//El comando 24 es un comando de escritura de bloques para MMC/SD-Card.

uint8 CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};

asm("cli"); //borrar todas las interrupciones.

addr = addr lt; lt; 9; //dirección = dirección * 512

CMD[1] = ((dirección amp; 0xFF000000) gt; gt; 24); = ((dirección amp; 0x00FF0000) gt; gt; 16

CMD[3] = ((dirección amp; 0x0000FF00) gt; gt; 8 ); Enviar comando CMD24 a MMC/tarjeta SD (escribir 1 bloque/512 bytes)

retry=0;

do

{ //Reintentar 100 veces para enviar comando .

>

tmp = Write_Command_SD(CMD);

if(retry == 100)

return(tmp); //¡enviar comando Error!

}

while(tmp != 0);

//Antes de escribir, envía 100 relojes a MMC/tarjeta SD

para (i = 0; i lt; 100; i )

SPI_ReadByte();

//Enviar byte de inicio a MMC/tarjeta SD

SPI_TransferByte(0xFE); p>

p>

//Ahora envíe datos reales Bolck (512Bytes) a MMC/tarjeta SD

para (i = 0; i lt; 512; i )

SPI_TransferByte( *Buffer ); //enviar 512 bytes a la tarjeta

//CRC-Byte

SPI_TransferByte(0xFF); //CRC ficticio

SPI_TransferByte(0xFF) ; //Código CRC

tmp=SPI_ReadByte(); // leer respuesta

if((tmp amp; 0x1F) != 0x05) // bloque de datos ¿aceptado?

{

SD_Disable();

return WRITE_BLOCK_ERROR; //¡Error!

}

//Espera hasta que MMC/Tarjeta SD no esté ocupada

while (SPI_ReadByte() != 0xFF){};

//establece MMC_Chip_Select en alto (MMC/SD-Card No válido)

SD_Disable();

devuelve 0

}

*/

carácter externo sin firmar; xdata Page_Buf[512] ; //Búfer de archivos.

void SD_SPI_WriteByte(uint8 ucSendData);

//Prueba el rendimiento de la interfaz SPI de la tarjeta SD

void TestSD_SPIFunc(void)

{

uchar ucCount;

uchar ucReadData;

ucCount = 0; //Iniciar

for(ucCount=0; ucCountlt; 10; ucCount )

{

// SPI_TransferByte(0x88); //El número de ciclos de máquina para escribir bytes implementados en lenguaje C es 188

SD_SPI_WriteByte(0x88 );

//Utilice la variable bData de C51 y utilice instrucciones de bits para transmitir directamente la operación ***Utilice la máquina 49

}

para(. ucCount=0 ; ucCountlt; 50; ucCount )

{

ucReadData = SPI_ReadByte(); // La máquina de lectura de bytes SPI implementada en lenguaje C tiene un ciclo de 154

// Variable bData de uso propio de C51, utilizando operación de instrucción de bits para leer bytes. El ciclo de la máquina es 49

}

ucCount= 88; /p>

SD_read_sector (0, Page_Buf);

}