irilias
Newbie level 4
- Joined
- Aug 18, 2010
- Messages
- 7
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Location
- Algeria
- Activity points
- 1,338
Hi, i'm new to programming PIC microcontrollers and will be using one (pic16f877a) to develop a project using an MMC/SD card.
i found a piece of code that initializes an MMC card into SPI mode, sets the block length, and writes raw data into 512 bytes blocks.
here's the code :
my question concerns the "MMC Write Block" Function, as i understood from the pic16f877a datasheet, this pic has a 10 bits A/D converter, so why would the coder declare "f" as an 8bit variable and reads a 10bit value from the A/D ? and then he proceeds to calculate the quantum on a 256 range? ( n= (fx5)/256 )
i mean wouldn't it be correct if we declare "f" as a long variable (16bits) and put n= (fx5)/1024 ? am i missing something?
any help would be much appreciated, Thank you
Note: n represents the corresponding analog value to be stored (or displayed)
i found a piece of code that initializes an MMC card into SPI mode, sets the block length, and writes raw data into 512 bytes blocks.
here's the code :
Code:
/************************** 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\n\r");
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\n\r");
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\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(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\n\r");
return 0;
}
/************************** MMC Write Block *******************************/
int mmc_write_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl;
char p,f,n;
set_adc_channel(0);
delay_us(10);
f=read_adc();
n=(f*5)/256;
p=(n*9375)/206;
varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);
puts("Write block\n\r"); // 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(varh);
SPI_WRITE(varl);
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\n\r");
SPI_WRITE(0xFE); // send data token
for(i=0;i<512;i++)
{
SPI_WRITE(p); // send data
}
SPI_WRITE(0xFF); // dummy CRC
SPI_WRITE(0xFF);
if((SPI_READ(0xFF)&0x0F)!=0x05) return 1;
puts("Got data response to write block\n\r");
OUTPUT_HIGH(PIN_C2); // set SS = 1 (off)
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
}
/**************************************************************************/
my question concerns the "MMC Write Block" Function, as i understood from the pic16f877a datasheet, this pic has a 10 bits A/D converter, so why would the coder declare "f" as an 8bit variable and reads a 10bit value from the A/D ? and then he proceeds to calculate the quantum on a 256 range? ( n= (fx5)/256 )
i mean wouldn't it be correct if we declare "f" as a long variable (16bits) and put n= (fx5)/1024 ? am i missing something?
any help would be much appreciated, Thank you
Note: n represents the corresponding analog value to be stored (or displayed)