Hola Tigreivan,

mi proyecto consiste en un modulo de adquisición de datos controlado por un pic 16f873, aqui te paso la rutina que he gastado para la mmc. Leo y escribo bien lo que me falta es manejar los archivos en fat16, estoy buscando cosas pero todavia ando un poco perdidillo. Bueno aqui te la dejo. Un saludo!
// archivos include
#include <16F873.h>
#device ICD=TRUE
//#define *=16
#device ADC=8
#include <STDIO.H> //Para las funciones RS232
#include <STDLIB.H> //Para la función atol
#include <STRING.H> //Para funciones con strings
//------Declaraciones para el compilador-------
#use delay(clock =19660800) //frecuencia de reloj
//#use i2c(master,sda=PIN_C4, scl=PIN_C3,FORCE_HW)
#use i2c(master,sda=PIN_C4, scl=PIN_C3,FORCE_HW,NOFLOAT_HIGH)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) //configuracion puerto serie
#fuses HS,NOWDT,PUT,NOPROTECT,BROWNOUT
#use standard_io(b)
int mmc_init();
int mmc_response(unsigned char response);
int mmc_read_block(unsigned long block_number);
int mmc_write_block(unsigned long block_number);
int mmc_get_status();
int dato;
char Keypress=" ";
//int sector[512];
/************************** MMC Init **************************************/
/* Initialises the MMC into SPI mode and sets block size, returns 0 on success */
int mmc_init()
{
int i;
SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_4 | SPI_SS_DISABLED);
*0x94 |= 0x40; // set CKE = 1 - clock idle low
*0x14 &= 0xEF; // set CKP = 0 - data valid on rising edge
OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
for(i=0;i<10;i++) // initialise the MMC card into SPI mode by sending clks on
{
SPI_WRITE(0xFF);
}
OUTPUT_LOW(PIN_C2); // set SS = 0 (on) tells card to go to spi mode when it receives reset
SPI_WRITE(0x40); // send reset command
SPI_WRITE(0x00); // all the arguments are 0x00 for the reset command
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x95); // precalculated checksum as we are still in MMC mode
puts("Sent go to SPI
"

;
if(mmc_response(0x01)==1) return 1; // if = 1 then there was a timeout waiting for 0x01 from the mmc
puts("Got response from MMC
"

;
i = 0;
while((i < 255) && (mmc_response(0x00)==1)) // must keep sending command if response
{
SPI_WRITE(0x41); // send mmc command one to bring out of idle state
SPI_WRITE(0x00); // all the arguments are 0x00 for command one
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF
i++;
}
if(i >= 254) return 1; // if >= 254 then there was a timeout waiting for 0x00 from the mmc
puts("Got out of idle response from MMC
"

;
OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
SPI_WRITE(0xFF); // extra clocks to allow mmc to finish off what it is doing
OUTPUT_LOW(PIN_C2); // set SS = 0 (on)
SPI_WRITE(0x50); // send mmc command one to bring out of idle state
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x02); // high block length bits - 512 bytes
SPI_WRITE(0x00); // low block length bits
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF
if((mmc_response(0x00))==1) return 1;
OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
puts("Got set block length response from MMC
"

;
puts("Memoria inicializada!!
"

;
return 0;
}
/************************** MMC Get Status **************************************/
/* Get the status register of the MMC, for debugging purposes */
int mmc_get_status()
{
OUTPUT_LOW(PIN_C2); // set SS = 0 (on)
SPI_WRITE(0x58); // send mmc command one to bring out of idle state
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00); //
SPI_WRITE(0x00); // always zero as mulitples of 512
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF
OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
OUTPUT_HIGH(PIN_C0);
return 0;
}
/************************** MMC Write Block **************************************/
int mmc_write_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl;
int j=0;
varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);
puts("Write block
"

; // block size has been set in mmc_init()
OUTPUT_LOW(PIN_C2); // set SS = 0 (on)
SPI_WRITE(0x58); // send mmc write block
SPI_WRITE(make8(varh,1));
SPI_WRITE(make8(varh,0));
SPI_WRITE(make8(varl,1));
SPI_WRITE(0x00); // always zero as mulitples of 512
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF
if((mmc_response(0x00))==1) return 1;
puts("
Got response to write block
"

;
SPI_WRITE(0xFE); // send data token
for(i=0;i<512;i++)
{
SPI_WRITE(j++); // send data
putc(j);
}
SPI_WRITE(0xFF); // dummy CRC
SPI_WRITE(0xFF);
if((SPI_READ(0xFF)&0x0F)!=0x05) return 1;
puts("Got data response to write block
"

;
OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
return 0;
}
/************************** MMC Read Block **************************************/
/**** Reads a 512 Byte block from the MMC and outputs each byte to RS232 ****/
int mmc_read_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl;
int parte_alta_varh;
int parte_baja_varh;
int parte_alta_varl;
OUTPUT_HIGH(PIN_C1);
varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);
parte_alta_varh=make8(varh,1);
parte_baja_varh=make8(varh,0);
parte_alta_varl=make8(varl,1);
OUTPUT_LOW(PIN_C2); // set SS = 0 (on)
SPI_WRITE(0x51); // send mmc read single block command
SPI_WRITE(parte_alta_varh); // arguments are address
SPI_WRITE(parte_baja_varh);
SPI_WRITE(parte_alta_varl);
SPI_WRITE(0x00);
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF
if((mmc_response(0x00))==1) return 1; // if mmc_response returns 1 then we failed to get a 0x00 response (affirmative)
puts("Got response to read block command
"

;
OUTPUT_LOW(PIN_C1);
if((mmc_response(0xFE))==1) return 1; // wait for data token
puts("
Got data token
"

;
for(i=0;i<12;i++)
{
putc(SPI_READ(0xFF)); // we should now receive 512 bytes
}
SPI_READ(0xFF); // CRC bytes that are not needed
SPI_READ(0xFF);
OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
SPI_WRITE(0xFF); // give mmc the clocks it needs to finish off
puts("
End of read block
"

;
return 0;
}
/************************** MMC get response **************************************/
/**** Repeatedly reads the MMC until we get the response we want or timeout ****/
int mmc_response(unsigned char response)
{
unsigned long count = 0xFFFF; // 16bit repeat, it may be possible to shrink this to 8 bit but there is not much point
while(SPI_READ(0xFF) != response && --count > 0);
if(count==0) return 1; // loop was exited due to timeout
else return 0; // loop was exited before timeout
}
void main (void){
int return0;
set_tris_c(0b10111111); //configuro puerto c como usart
disable_interrupts(GLOBAL); // Apaga todas las interrupciones
enable_interrupts(INT_RDA); // Da permiso a la interrupcion por recepcion RS232
enable_interrupts(GLOBAL); // Ahora habilitamos todas
delay_ms(3000);
printf("
********************************************
"

;
printf("Team Industrial SA
"

;
printf("Datalogger 01
"

;
printf("Realizado por: Jose Antonio Martinez Jimenez
"

;
printf("********************************************
"

;
// return0=mmc_init();
// return0=mmc_get_status();
// return0=mmc_read_block(1);
do {
if(dato!=0x00)
{
switch(dato)
{
case "i": if (mmc_init()==0)
printf("
Arranco la memoria
" );
else printf("
No anda la puta madre!
" );
break;
case "r":
return0=mmc_init();
if(mmc_read_block(0)==0){
printf("
leido el contenido de la memoria
" );
}else printf("
fallo al leer el contenido de la memoria
"

;
break;
case "w":
return0=mmc_init();
if(mmc_write_block(0)==0){
printf("
escribiendo en la memoria
" );
}else printf("
fallo al escribir en la memoria
"

;
break;
case "0": output_low(PIN_C0);
printf(" 0 - LED Apagado
" );
break;
case "1": output_high(PIN_C0);
printf(" 1 - LED Encendido
" );
break;
}
dato=0x00;
}
} while (TRUE);
}//main
#INT_RDA //Tratamiento de la interrupcion por recepcion
void rs232_isr(void)
{
//int dato;
dato=getch();
}