Está en la página 1de 11

PIC 16F877 con memoria SD

Temas generales de la Memoria SD


El usar como memoria de datos de un PIC, una tarjeta SD, es un trabajo complicado, hasta
develar sus misterios. Hay poca informacin y la que hay est confusa y con
equivocaciones. Me ha llevado mas de diez das de trabajo poder hacer que el sistema
funcione. Es mi anhelo, que con esta informacin les lleve muchos menos das.
Lo primero de todo es que tengan en su PC un programa que lea y edite las tarjetas SD.
Encontr el Explorer y el WinHex. El primero me dej de leer el puerto USB con el adaptador
de tarjeta y el segundo me result el mejor. Bajarlo de http://alvareitor.programasfull.com. El
archivo es WinHex_15.0_SR2_Espanol_bY_Alvareitor.rar. Una vez bajado e instalado segn
las instrucciones, vern esta pantalla:

Muestra la memoria SD que uso para las experiencias. Marqu con rojo las cosas
importantes.
Est conectada en un USB, drive O, Formateada en FAT16, muestro el sector 3, que
comienza en la direccin 600 hexadecimal, tiene 1.8 GB de capacidad til y casi 2 GB de
capacidad total. 512 Bytes por sector.

Lo ms importante que quiero mostrar es donde dice Sector fsico = 140 y Sector lgico=
3. Los @ los grab yo y comienzan en la direccin lgica 0x600. En todos los ejemplos
que vi en Internet usan esta direccin para grabar. Tard muchos das experimentando sin
poder grabar, hasta que encontr en un artculo en ingls, que la direccin que se debe usar
es la fsica. Y entonces grab y le bien. La direccin lgica cero corresponde a la fsica 137
(Decimales), de manera que en lugar de marcar como inicio de grabacin o lectura la
direccin 0x600 = sector 3 x 0x200, se deber calcular (3 + 137) x 512 = 71680 , o sea
0x11800.
En una segunda memoria SD de la misma capacidad, el sector lgico cero es 135 fsico, de
manera que para cada tarjeta se debe mirar el nmero y hacer los clculos, o en mi caso
uso 137 para las dos.
Cuando segu haciendo experiencias con las grabaciones, en un caso por mala
programacin me grab el sector cero, y perd la FAT, con el resultado de Tarjeta imposible
de leer en la PC.
Para formatear la SD, usar el programa oficial de tarjetas SD. Est en Download SD
Formatter donde encontrarn instrucciones de uso.
Instrucciones para formatear. Se bajan de esta direccin.
Cuando la quise formatear, el SD formatter no me la aceptaba, porque en el sector averiado,
supongo que estn los cdigos que protegen las SD contra copias piratas, si se las protege.
Entonces la formate con el Windows XP, haciendo botn derecho en <MI PC> luego
seleccionar <administrar> luego <Administracin de discos>. Aparecer la tarjeta SD si est
conectada a la PC. All se formatea lento y destruir las protecciones, de manera que
desaparece la diferencia entre sectores lgicos y sectores fsicos. Solo queda el sector
fsico, y no vale lo que mostr arriba. La direccin donde comienza la escritura y la lectura se
calcula como Sector * 512. Para el sector 3 es 3 * 512 = 1536 en decimal o 0x600.
Encontrarn que en firmware simple, la direccin es 0x11800 y en el firmware funcin la
direccin es 1536 decimal. En este ltimo caso, no hay diferencia entre fsico y lgico, y la
funcin comando recalcula la direccin a hexadecimal.
Para convertir unidades uso este convertidor. Tambin de la pgina pueden bajar el archivo
fuente. ( www.arossini.com.ar ).

Esta es otra cosa a tener en cuenta. A no olvidarse. Es como en los disquetes.

Plaqueta para conectar la Memoria SD al PIC


Este fue otro dolor de cabeza, porque copi diseos de Internet, que no me sirvieron, porque
al mirar las ondas de clock y datos con un osciloscopio, deformaban la onda, convirtindola
de cuadrada a triangular, y nada funcionaba.

Comenc a disear mi propia interfase, con ayuda del osciloscopio y este esquema del
manual de la memoria San Disk, que se baja de aqu.
Ningn diseo usaba resistencias Pull Up, como indica el manual

Las resistencias Pull Up son las de 10K.


Los Zener de 3.3 Volt, bajan la tensin de 5 Volt del PIC a 3 Volt aproximadamente.
El consumo de la Tarjeta est en el orden de 65 mA.

Este esquema est en el esquema general del PIC. Yo lo armo en una plaqueta separada
para poder usarlo con otros PICs, al igual que la plaqueta que uso para la comunicacin con
el puerto serie.

Comandos usados en SPI para SD


Este trabajo, hecho lo ms simple posible, es para INICIALIZAR la tarjeta, ESCRIBIRLA y
LEERLA, escribiendo y leyendo bloques de memoria. Se escriben las posiciones de
memoria.
El trabajo siguiente a publicar ser el de escribir y leer archivos de texto. Por ahora son
palabras mayores para m.
La estructura de los comandos que se usan es de 6 Bytes y es la siguiente:

Los comandos usados en este trabajo son:


CMD0

0x40 00 00 00 00 95

Coloca la tarjeta en inactividad

CMD1

0x41 00 00 00 00 FF

Activa la tarjeta

CMD17

0x51 XX XX XX XX FF

Permite leer un sector de la tarjeta

CMD24

0x58 XX XX XX XX FF

Indica el sector de inicio de la escritura

XX son datos en hexadecimal. Mas abajo explico como se calculan y escriben.


Cuando enviamos un comando, debemos leer la respuesta. Es de 1 Byte
Para calcular el nmero del comando para el CMD17 por ejemplo:
CMD = 17; pasado a binario en el programa convertidor es 0b10001; se le agrega 01 de los
bit 7 y 6 y 0 para el bit 5 mas los 5 bit de 10001, quedando 0b01010001. Se lo pasa a
hexadecimal quedando 0x51, que es el valor mostrado arriba para comando 17.
Esta es la estructura de la respuesta que se recibe:

COMANDO

RESPUESTA

INDICA

CMD0

0x01

En espera

CMD1

0x00

Activo (Lista)

CMD17
tarjeta

0xFE + (bytes ledos de 1 a 512)

Leer un sector de la

CMD24

0x00

0xFE + (bloque a escribir) 0xE5

Seguir con la escritura


Recepcin correcta

A 0xFE se lo denomina Token.


Luego seguiremos con ms detalles, en el Firmware.

Esquema

Firmware
Hay en este trabajo, presentados dos Firmware:
a) .Firmware simple.
b) Firmware funcion.
Los dos hacen lo mismo, escriben un sector de 512 Bytes con un carcter, y luego leen solo
una cantidad de direcciones limitada en ese sector grabado.

El a) est hecho de la manera ms simple posible, sin funciones que puedan hacer perder el
fundamento de la comunicacin SPI. Es un Firmware didctico. Cuando Ustedes hagan el
suyo, podrn tratar de ahorrar toda la memoria que quieran, seguramente.
El b), usan una funcin llamada comando, que enva los comandos, y adems funcines
Inicializar, Escribir y Leer.
Tiene comunicacin serie, para que manden a la PC todo lo que deseen, cuando hagan
mejoras y necesiten corregir o detectar errores. Encontrarn que la mayora de los
comandos puerto serie estn comentados, pues se usan solo en caso de problemas y me
resultaron indispensables en su momento. Ustedes des-comentarn lo que necesiten.
Us el PIC 16F877, porqu encontr ejemplos con el en Internet. Seguir con el 18F4550,
pero presenta algn problema pues coincide la comunicacin serie con el SPI, y ello me trajo
conflictos que deber solucionar.
Usamos cristal de 20Mhz para que al seleccionar el divisor de frecuencia de clock de SPI a
64 obtengamos una frecuencia del mismo de aproximadamente 312Khz. (frecuencia para
inicializar la memoria). La cuenta es 20000000 / 64 = 312500 Hz. La mxima frecuencia
permitida para inicializar es 400 MHz. Luego puede llegar a 25 MHz.

Comunicacin SPI
Inicializacin

Lectura

Escritura

Detalles del comando 17


Void Leer(void)
{
CS = 0; delay_us(100);
//Respuesta=12;

// Habilitamos la Tarjeta SD

// Para que comience a funcionar el while si Respuesta viene = 0.

while(spi_read() !=0xFE){CMD17();} // Manda el comando 17, que lee un bloque del tamao
indicado por el comando 16, en la direccin 0x11800(0x600)
for(i=0;i<100;i++){spi_write(0xFF);Respuesta=spi_read();printf("Leo: %c\n\r",Respuesta);}//
Leer parte del bloque
puts("Termine de Leer");
CS = 1;

// Deshabilitamos la SD

} // Fin de Leer
CS = 0;

// Habilitamos la Tarjeta SD

Respuesta=12;

// Para que comience a funcionar el while si Respuesta viene = 0.

while(Respuesta !=0x00) // Manda el comando 17, que lee un bloque del tamao estndar
de 512 Bytes, en la direccin 0x600
La direccin 0x600 = sector 3 * 512 Byte= sector 3 * 0x200 Byte. Corresponde a sector
lgico, que es lo que se ve en el programa WinHex, mostrado arriba. Pero nosotros
necesitamos entrar la direccin correspondiente al sector fsico; debemos sumar entonces
137 al nmero de sector.
La direccin 0x600 (Lgico)= sector (3 +137)* 512 Byte = 71680. En hexadecimal = 0x11800.
Lo agrupamos como 00 01 18 00 y as lo escribimos en el comando, como se ve abajo.
El FOR es para leer la respuesta de la SD. Primero se manda un clock para dar tiempo a
que llegue la respuesta y luego se la espera hasta que llegue. Si todo est bien se pasa a la
rutina siguiente.
void CMD17()
{
spi_write(0x51);

// Comando

spi_write(0x00);

// Comando

spi_write(0x01);

// Comando

spi_write(0x18);

// Comando

spi_write(0x00);

// Comando

spi_write(0xFF);

// Comando

for(i=0;i<12;i++) {spi_write(0xFF);Respuesta=spi_read();//printf("Leo 17: %x\n\r",Respuesta);


if(Respuesta==0xFE) break;}
}

Detalles del comando 24


Para este trabajo, se usa la misma direccin, de manera que se debe mirar el comando 17.

Para resolver problemas


//puts("Pulsar Escribir");while(Pulsador ==1); delay_ms(500);
Spi_write(0xFE) ; // Byte Inicial Escritura
for(x=0;x<512;x++) {spi_write(Caracter);}
spi_write(0xFF) ;

// CRC

for(i=0;i<64;i++) {spi_write(0xFF);Respuesta=spi_read(); //printf("Res Escribir: %x,


%i\n\r",Respuesta,i);
En rojo, muestro dos partes que estn comentadas. Se usan para resolver problemas,
cuando algo no funciona.
Desmarcando la primera, manda un mensaje por puerto serie, mostrando lo ltimo que hizo
bien, y deteniendo el programa hasta que se presione el pulsador. La segunda nos muestra
valores ledos, para que podamos interpretar la causa del problema.
Tambin se usa el pulsador, para poder ver esa seal en modo Single o sea que se
detenga al recibir la seal, para observacin.

Pantalla del osciloscopio

Estas ondas estn generadas con la rutina Prueba 05, del Firmware. En amarillo es clock,
en azul es el 0x01.
//*************** Prueba 05 Mandamos clocks continuamente

CS = 1;

// Deshabilitamos la Tarjeta SD

puts("Mando Pulsos reloj con CS=1 y spi_write(0x01)");


puts("para ver CLOCK y SDI");
while(True) {spi_write(0x01);}

Fotografa

Otra lista con comandos


Comando:

Argumentos:

Respuesta: Descripcin:

CMD0

No

R1

Resetea la tarjeta

CMD1

No

R1

Inicializa la tarjeta

CMD9

No

R1

Pide a la tarjeta su informacin


CSD

CMD10

No

R1

Pide a la tarjeta su identificacin


CID

CMD13

No

R2

Consulta el estado de la tarjeta

CMD16

[31..0] Longitud del R1


bloque.

Establece la longitud (en bytes) del


bloque para los datos en las
operaciones de lectura y escritura.

CMD17

[31..0] Direccin de R1
datos.

Lee un bloque del tamao indicado


por el comando 16.

CMD24

[31..0] Direccin de R1 R1 R1 Escribe un bloque del tamao


datos
indicado por el comando 16.

También podría gustarte