
Tuesday, September 30, 2008
As I was programming the SD (MMC) card of the QL200 then I saw that I couldn't go on without an SPI EEprom.
So I took the sample cod that was given on the CD and I extended the functions there.
and I wrote following code today :
//experiment purpose: familiar SPI general line and how to read and write 9346EEPROM
//when press RBO key ,write DATA and DATA2 in some EEPROM address from EE¡ªADDR
//when write finished,the LED display single 9 to indicate finished.
//when key RB1 press,read EEPROM address from EE¡ªADDR and send to LED display
//hardware request: SW S5¡¢S6¡¢S3 all set ON,S1 7-8 bits set ON
//if use 93C46 from ATMEL,must set ¡°WORD SIZE¡± jumper is sixteen.
#include<pic.h>
__CONFIG(0x1832);
//THE configure of MCU,watchdog OFF,electrify delay OPEN,power down check OFF,
//LOW power programme OFF,encrypt,4M crystal HS surge.
#define c_s RC2
#define clk RC3
#define d_i RC5
#define d0 RC4
//#define ee_addr 0x5
#define ee_addr 0x400 // maximum adress (1024)
#define ee_addr2 0x5 // one less
#define nop() asm("nop")
const char ee_data_write[]={0x56,0x78};
unsigned char ee_date[4];
const char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
unsigned int temp;
void init();
void ee_write(unsigned char adress,unsigned char data);
void ee_read(unsigned char adress);
void display();
void delay();
void ee_write_enable();
void spi_comm(unsigned char x);
void main()
{
init();
while(1)
{
if(!RB0)
{
ee_write(0x5,0xf3);
ee_write(63,0xf4);
}
if(!RB1)
{
ee_read(63);
while(1)
{
display();
}
}
if(!RB2)
{
ee_read(0x5);
while(1)
{
display();
}
}
}
}
void init()
{
ADCON1=0X07;
TRISA=0X30;
TRISB=0X07;
TRISC=0X10;
TRISD=0X00;
PORTD=0XFF;
SSPSTAT=0X80;
SSPCON=0X31;
INTCON=0X00;
PIR1=0X00;
c_s=0;
}
void ee_write(unsigned char adress,unsigned char data) // the memory range extends from 0 to 63 (decimal)
{
int i,j;
ee_write_enable();
c_s=1;
spi_comm(0x1);
spi_comm(adress|0x40);
for(i=0;i<2;i++)
{
j=data;
spi_comm(j); //this time we write two times the data of 8 bits - that means 16 bits
} // 16 x 64 = 1024 -> so we have the volume of 1 K
c_s=0;
nop();
nop();
c_s=1;
nop();
nop();
while(!d0);
c_s=0;
nop();
nop();
PORTD=0X90;
PORTA=0X3E;
}
void ee_read(unsigned char adress)
{
int i;
c_s=1;
nop();
nop();
spi_comm(0x01);
spi_comm(adress|0x80);
for(i=0;i<2;i++)
{
spi_comm(0);
ee_date[i]=temp;
}
nop();
c_s=0;
nop();
}
void ee_write_enable()
{
c_s=1;
spi_comm(0x01);
spi_comm(0x30);
c_s=0;
nop();
nop();
}
void spi_comm(unsigned char x)
{
SSPBUF=x;
while(!SSPIF);
SSPIF=0;
temp=SSPBUF;
}
void display()
{
int i;
i=ee_date[0]&0xf0;
i=i>>4;
PORTD=table[i];
PORTA=0x3e;
delay();
i=ee_date[0]&0x0f;
PORTD=table[i];
PORTA=0x3d;
delay();
i=ee_date[1]&0xf0;
i=i>>4;
PORTD=table[i];
PORTA=0x3b;
delay();
i=ee_date[1]&0x0f;
PORTD=table[i];
PORTA=0x37;
delay();
}
void delay()
{
int i;
for(i=100;i>0;i--);
}
2.10.2008 Today I was searcing for a code on how I could write a huge data amount to the SD card. I was very disappointed as I saw that the SPI EEprom could only sore a 128 bytes. Then I was very disappointed as I saw that I could only write from the internal Memory of the PIC16F877 62 bytes into the SD card.
Maybe someone knows a better solution on how to manage the memory and on how to write the whole memory of the SD card with useful data?
Here the code :
//experiment purpose: familiar SPI general line and how to read and write 9346EEPROM
//when press RBO key ,write DATA and DATA2 in some EEPROM address from EE¡ªADDR
//when write finished,the LED display single 9 to indicate finished.
//when key RB1 press,read EEPROM address from EE¡ªADDR and send to LED display
//hardware request: SW S5¡¢S6¡¢S3 all set ON,S1 7-8 bits set ON
//if use 93C46 from ATMEL,must set ¡°WORD SIZE¡± jumper is sixteen.
#include<pic.h>
#include"delay.h"
__CONFIG(0x1832);
//THE configure of MCU,watchdog OFF,electrify delay OPEN,power down check OFF,
//LOW power programme OFF,encrypt,4M crystal HS surge.
#define cs RC2 //define sd pin.
#define c_s RC2
#define clk RC3
#define d_i RC5
#define d0 RC4
// #define ee_addr 0x5
// #define ee_addr 0x400 // maximum adress (1024)
// #define ee_addr2 0x5 // one less
#define nop() asm("nop")
const char ee_data_write[]={0x56,0x78};
unsigned char ee_date[62];
const char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
const char TABLE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0X82,0XF8,0X80,0X90};
unsigned int temp;
unsigned char HIGHBYTE;
unsigned char LOWBYTE;
// 1.10.2008 : The SPI EEprom functions were fully implemented :
void init();
void ee_write(unsigned char adress,unsigned char datah,unsigned char datal); // we have 16 bits
unsigned char ee_read(unsigned char adress,int hilo);
void display(unsigned char temp);
void delay();
void DelayMs(unsigned char cnt);
void ee_write_enable();
unsigned int spi_comm(unsigned char x);
// SD card functions :
void spi_init(); //spi init
void spi_low(); //produce low band func(sd card init use.)
void spi_high(); //produce high band func(sd card init use.)
unsigned char sd_reset(); //sd card init func
unsigned char SD_SendCommand(unsigned char cmd,unsigned long arg); //write sd card command func
unsigned char SPI_WriteByte(unsigned char val); //write one byte func.
unsigned char SPI_ReadByte(void); //receive one byte func.
unsigned char SD_WriteSingleBlock(unsigned long sector); //write sd card one blockfunc.
unsigned char SD_ReadSingleBlock(unsigned long sector); //read sd card one blockfunc.
void main()
{ int i,j;
unsigned char loop,res;
// for(i=0;i<62;i++)
for(i=0;i<62;i++) ee_date[i]=48+i;
spi_init();
while(1)
{
for(i=0;i<64;i++)
{// ADRESS , H , L
ee_write(i,i,48+i); // the 8bit count goes until 255 (FF)
}
if(!RB1)
{
for(i=0;i<64;i++)
{
HIGHBYTE = ee_read(i,1);
LOWBYTE = ee_read(i,0);
for(j=60;j--;) //loop display for 30 times and ensure the time internal.
{
display(HIGHBYTE);
}
}
}
// The memory of the SPI EEprom is written and now we want to write down the Data into the SD card
if(!RB0) // if RB0 is pressed then the Data shall be stored
{
// The data is being stored in the SD card
loop=1;
while(loop)
{
// spi_init(); //system init.
res= sd_reset(); //sd card init.
if(res) break; //if init is abnormal,exit and don't perform the next func.
SD_WriteSingleBlock(7592); //write sd card one block,and the block number is 1.
if(res) break;
SD_ReadSingleBlock(7592); //read sd card one block,and the block number is 1.
if(res) break;
loop=0;
RC1=0;
// while(1);
}
RC0=1;
}
}
}
// EEprom functions :
void ee_write(unsigned char adress,unsigned char datah,unsigned char datal) // the memory range extends from 0 to 63 (decimal)
{
int i,j;
ee_write_enable();
c_s=1;
spi_comm(0x1);
spi_comm(adress|0x40);
j=datal;
spi_comm(j); //this time we write two times the data of 8 bits - that means 16 bits
// 16 x 64 = 1024 -> so we have the volume of 1 K
j=datah;
spi_comm(j); // first the lower bits are shifted then the higher ones get on their turn
c_s=0;
nop();
nop();
c_s=1;
nop();
nop();
while(!d0);
c_s=0;
nop();
nop();
}
unsigned char ee_read(unsigned char adress,int hilo)
{
int i;
unsigned char numberh;
unsigned char numberl;
c_s=1;
nop();
nop();
spi_comm(0x01);
spi_comm(adress|0x80);
numberh = spi_comm(0);
numberl = spi_comm(0);
nop();
c_s=0;
nop();
if(hilo)return (numberh);
if(!hilo)return (numberl);
}
void ee_write_enable()
{
c_s=1;
spi_comm(0x01);
spi_comm(0x30);
c_s=0;
nop();
nop();
}
unsigned int spi_comm(unsigned char x)
{
unsigned int temp;
SSPBUF=x;
while(!SSPIF);
SSPIF=0;
temp=SSPBUF;
return (temp);
}
////////////////////////////////////////////////
//display func.
void display(unsigned char temp)
{
unsigned char bai,shi,ge; //define 4 temporary.
bai=temp/0x64; //calculate the display value.
shi=(temp%0x64)/0xa; //calculate the display value.
ge=(temp%0x64)%0xa; //calculate the display value.
PORTD=TABLE[bai]; //search table.
PORTA=0x37; //RA3 output low to open the display.(110111)
delay(); //delay for display strenth.
PORTD=TABLE[shi]; //search table.
PORTA=0x2F; //RA4 output low to open the display.(101111)
delay(); //delay for display strenth.
PORTD=TABLE[ge]; //search table.
PORTA=0x1F; //RA5 output low to open the display.(011111)
delay(); //delay for display strenth.
PORTA=0x3F; //(111111) All displays are off
}
void DelayMs(unsigned char cnt)
{
#if XTAL_FREQ <= 2MHZ
do {
DelayUs(996);
} while(--cnt);
#endif
#if XTAL_FREQ > 2MHZ
unsigned char i;
do {
i = 4;
do {
DelayUs(255); //250 initial value
} while(--i);
} while(--cnt);
#endif
}
void delay()
{
int i;
for(i=100;i>0;i--);
}
// SD card (MMC) functions :
////////////////////////////////////////////////
//spi init
void spi_init()
{
TRISC=0xd0; //set SDI as input£¬other port c are output.
TRISD=0X00; //set port d as output.
TRISA=0X00; //set port a as output.
ADCON1=0X07; //set port a as ordinary i/o.
SSPCON=0x32; //high when idle.fosc/64
SSPSTAT=0x80; // rising edge,send data.
RC0=0;
RC1=0;
PORTA=0XFF;
}
////////////////////////////////////////////////
//set low band.
void spi_low()
{
SSPCON=0x32; //SPI clk use the system clk--fosc/64
}
////////////////////////////////////////////////
//set high band.
void spi_high()
{
SSPCON=0x31; //SPI clk use the system clk--fosc/16
// we have a faster speed here
}
///////////////////////////////////////////////
//write one byte.
unsigned char SPI_WriteByte(unsigned char val)
{
SSPBUF = val; //load to send buffer
while(!SSPIF); //wait to finish sending.
SSPIF=0; //clear send finish flag.
return SSPBUF; //read the receive buffer(even the data is unvalid,it is still need cleared.)
}
///////////////////////////////////////////////
//read one byte.
unsigned char SPI_ReadByte(void)
{
SSPBUF = 0xff; //load to send buffer to start receiving.
while(!SSPIF); //wait to finish receiving.
SSPIF=0; //clear receiving finish flag.
return SSPBUF; //read the receive buffer
}
////////////////////////////////////////////////
//send command func
unsigned char SD_SendCommand(unsigned char cmd,unsigned long arg)
{
unsigned char r1;
unsigned char retry1=0; //repeat count.
cs=0; //enable cs signal.
SPI_WriteByte(cmd | 0x40); //write command.
SPI_WriteByte(arg>>24); //data segment the 4th byte.
SPI_WriteByte(arg>>16); //data segment the 3th byte.
SPI_WriteByte(arg>>8); //data segment the 2nd byte.
SPI_WriteByte(arg); //data segment the 1st byte.
SPI_WriteByte(0x95); //CRC check sum.
while((r1 = SPI_WriteByte(0xff)) == 0xff)//wait ack.
if(retry1++ > 100) break; //overtime exit.
cs=1; //clear cs.
return r1; //return the status value.
}
////////////////////////////////////////////////
//SD reset.
unsigned char sd_reset()
{
unsigned char i,tmp;
unsigned char retry; //repeat times.
unsigned char r1=0;
retry=0;
spi_low(); //use low band.
do
{
for(i=0;i<100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(0,0);//send idle command.
retry++;
if(retry>10) return 1; //overtime exit.
} while(r1 != 0x01); //wait IDLE command return.
retry = 0;
do
{
for(i=0;i<100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(1, 0); //send Active command.
retry++;
if(retry>100) return 1; //overtime exit.
} while(r1); //wait Active command exit.
spi_high(); //use high band.
for(i=0;i<100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(59, 0); //off crc
if(r1!=0) return 1; //return is wrong,exit init.
for(i=0;i<100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(16, 512); //set block size is 512
if(r1!=0) return 1; //return is wrong,exit init.
return 0; //return normal.
}
///////////////////////////////////////////////
//write one block
unsigned char SD_WriteSingleBlock(unsigned long sector)
{
unsigned char r1;
unsigned int i,u=0;
unsigned char retry=0;
spi_low();
do
{
for(i=0;i<100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(24, sector<<9);//write command.
retry++;
if(retry>10) return 1; //overtime,exit.
} while(r1 != 0x00);
cs=0;
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xff);
SPI_WriteByte(0xfe); //send start command.
// 01.10.2008 my first 62 Bytes from the internal memory of the 16F877 were written :
for(i=0; i<62; i++) //send 32 byte data.
{
SPI_WriteByte(ee_date[i]);
// Here is my problem :
// if I load here the EEprom contents then the whole story does not functionalize
// SPI_WriteByte(ee_date[i]) = ee_read(unsigned char adress,int hilo); - that makes my controller standing still
// How can i combine both impemented SPI storage media ???
}
for(i=0;i<450;i++) SPI_WriteByte(48); // "0"
SPI_WriteByte(0x95);
SPI_WriteByte(0x95); //16-bits CRC
r1 = SPI_WriteByte(0xff); //read ack bit.
if(retry++ >10) return 1; //overtime, exit.
while(!((r1&0x0f)==5)); //wait data success return info.
while(!(SPI_WriteByte(0xff))); //wait sd card internal program over.
return 0;
}
// Info about the SD card protocol :
// http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
// http://www.cs.ucr.edu/~amitra/sdcard/Additional/sdcard_appnote_foust.pdf
// http://www.microchipc.com/sourcecode/
////////////////////////////////////////////////
//read one block.
unsigned char SD_ReadSingleBlock(unsigned long sector)
{
unsigned char r1,temp;
unsigned int i,j;
unsigned char retry=0;
do
{
r1 = SD_SendCommand(17, sector<<9);//read command.
retry++;
if(retry>10) return 1; //overtime,exit
} while(r1 != 0x00);
cs=0;
while(SPI_WriteByte(0xff)!= 0xfe) //wait to receive the start byte.
{
if(retry++ >100) return 1; //overtime,exit
}
for(i=0; i<512; i++) //read 32 data
{
temp = SPI_WriteByte(0xff); //read the receiving data.
for(j=30;j--;) //loop display for 30 times and ensure the time internal.
{
display(temp); //read data and display
}
}
SPI_WriteByte(0xff); //false 16-bits crc
SPI_WriteByte(0xff);
cs=1;
return 0;
}
THAT WAS THE REASON WHY I NEEDED THE MACHINE WITH THE SRAM
Create a free website at Webs.com