Code:
#include<16f877a.h>
#include<def_877a.h>
// Speihersutz121345=aus,Debug11=aus,ProgrammFlash9=an,EEpromRead8=an,NiendervoltProgr7=aus
// NiederVoltReset6=an,EinschaltTimer3=an,WachDogTimer2=aus,Oszilator01=XC
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232 (baud=4800 , parity = N , xmit=pin_C6 , rcv=pin_C7 )
#bit CS = PORTC.2 //Ausgang für Chip Select
#bit SCK = PORTC.3 //Ausgang Clock
#bit SDO = PORTC.5 //Ausgang Daten Output
#bit SDI = PORTC.4 //Eingang Daten Input
#byte temp = 0x31
#bit temp_7 = temp.7
#byte temp1 = 0x32
#bit temp1_0 = temp1.0
#define bls 20
int mmc_init();
int mmc_response(unsigned char response);
int mmc_read_block(int32 add,int result);
int1 mmc_write_block(int32 add,int tem);
int mmc_get_status();
#INT_RDA // Ham xu ly ngat noi tiep
void Receive_isr()
{
int c;
c = fgetc();
printf("%d",c);
}
/*-------------------------------------------------------------------------*/
int1 command(int8 bef,long adrh,long adrl,int8 bes)
{spi_write(0xff);
spi_write(bef);
spi_write(make8(adrh,1));
spi_write(make8(adrh,0));
spi_write(make8(adrl,1));
spi_write(make8(adrh,0));
spi_write(bes);
spi_write(0xff);
return (spi_read(0xff));
}
/************************** MMC Init **************************************/
/*
Initialises the MMC into SPI mode and sets block size, returns 0 on success */
int mmc_init()
{
long i;
SETUP_SPI(SPI_MASTER | SPI_l_TO_h | SPI_CLK_DIV_16);
*0x94 |= 0x40; // set CKE = 1 - clock idle low
*0x14 &= 0xEF; // set CKP = 0 - data valid on rising edge
cs=1; // set SS = 1 (off)
for(i=0;i<1000;i++) // initialise the MMC card into SPI mode by sending clks on
{
SPI_WRITE(0xff);
}
cs=0; ;
// set SS = 0 (on) tells card to go to spi mode when it receives reset
i=20;
while((command(0x40,0,0,0x95)!=1)&&(i>0)) { command(0x40,0,0,0x95);--i; }
if(i==0) return 1;
// precalculated checksum as we are still in MMC mode
puts("Sent go to SPI\n\r");
// if = 1 then there was a timeout waiting for 0x01 from the mmc
puts("Got response from MMC\n\r");
i = 0;
while((i < 255) && (spi_read(0xff)==0))
// 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\n\r");
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(0x00);
// high block length bits - 512 bytes
SPI_WRITE(0x14);
// low block length bits
SPI_WRITE(0xFe);
// 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\n\r");
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)
return 0;
}
/*---------------------------------------------------------------------------*/
int1 mmc_write_sector(int32 add,int temp)
{int32 j;
int8 val,tg;
j=add;
output_low(pin_c2);
SPI_WRITE(0x58);
// send mmc write block
SPI_WRITE(make8(j,3));
SPI_WRITE(make8(j,2));
SPI_WRITE(make8(j,1));
SPI_WRITE(make8(j,0));
SPI_WRITE(0x00);
SPI_WRITE(0xff);
if(spi_read(0xff)!=0x05) return 1;
SPI_WRITE(0xff);
spi_write(0xfe); //crc
for(tg=20;tg>0;--tg) Spi_write(temp);
spi_write(0xff); //crc
spi_write(0xff); //crc
if(!(mmc_response(0x00)&&0x1f)==0x05) return 1;
printf("ok da 1 xong\n\r");
output_high(pin_c2);
return 0;
}
/*---------------------------------------------------------------------------*/
int mmc_read_block(int32 add,int result)
{
int32 i;
int8 tg;
i=add;
output_low(pin_c2);
spi_write(0x51);
SPI_WRITE(make8(i,3));
SPI_WRITE(make8(i,2));
SPI_WRITE(make8(i,1));
SPI_WRITE(make8(i,0));
SPI_WRITE(0x00);
SPI_WRITE(0xff);
if(spi_read(0xff)!=0) return 1;
printf("da doc\n\r");
for(tg=20;tg>0;--tg) result=spi_read(0xff);
spi_write(0xff); //crc
spi_write(0xff); //crc
Output_high(Pin_c2);
spi_write(0xff);
return result;
}
/************************** 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()
{
int add,hi,m;
char i,temp;
TRISC=0xc3;
trisb=0x00;
portc=0x00;
i=2;
add=1024;
enable_interrupts(int_rda);
enable_interrupts(GLOBAL);
mmc_init();
if(mmc_init()==0) printf("Hello PIC Viet Nam!\n\r ");
else
printf("chan qua! ");
}
cho em hỏi code của em sai tại đâu mà không thể khởi tạo được MMC. Tức phản hồi R1 của MMC luôn #0x01