Please help, at89s52 using SPI

Status
Not open for further replies.

andy40185

Member level 5
Joined
Sep 30, 2011
Messages
80
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Activity points
1,810
Please help!!! AT25256 read wrong data!!!

Hi all,

Can the at89s52 support to SPI protocol? If not, how can do it? As I need to use a EEPROM-AT25256 storing the data but I stuck in read part.
I have seen several related program or equivalent info and its also include a initialization(for what?). Why we need it for SPI? I have encountered
this issue for days.

Regards,
Andy
 
Last edited:


The AT89S52 does not have dedicated SPI interface, but it can be implemented by using standard pins .. see attached picture ..
Example (incl. asm code):
**broken link removed**
:wink:
IanP
 

Attachments

  • 8051 and SPI EEprom.JPG
    19.7 KB · Views: 185
I wanna know if a dummy write is needed before the read operation.

Regards,
Andy
 

I wanna know if a dummy write is needed before the read operation.

No, the sequence is clear: to EEProm [SI] --- 8-bit instruction, 16-bit-address ... followed by 8-bit data - from the EEProm [SO] ..
:wink:
IanP
 
Reactions: DrWhoF

    DrWhoF

    Points: 2
    Helpful Answer Positive Rating
I ensure that my program is followed the steps even write or read but I still get wrong data.
 

No, the sequence is clear: to EEProm [SI] --- 8-bit instruction, 16-bit-address ... followed by 8-bit data - from the EEProm [SO] ..
:wink:
IanP
I have not provided the dummy write but I get the wrong data(e.g. 27 is real data then I get 25). Also, I do not know how to provide the dummy write to the slave. Is it like the following steps? CS=0;-->for loop to send 1 byte-->CS=1;
 

Please help, I have tested many times but it's not work.
In this picture, the real data is showed on the bottom while the read data is showed on the top. I only write 5bytes(words) to AT25256A.
 
Last edited:
Reactions: DrWhoF

    DrWhoF

    Points: 2
    Helpful Answer Positive Rating
How do you know the correct data is written into EEProm?
Reading is always easier then writing.
 

To DrWhoF,

okay, would you illustrate the write steps? In my write function, it starts checkbusy[CB()]-->CS=0-->send WREN code-->CS=1-->short delay or not-->
CB()-->CS=0-->send Write code and then send the higher byte address and lower byte address is followed-->send 8bit data-->CS=1-->
CB()-->CS=0-->send WRDI code-->CS=1

Regards,
Andy

I'm hoping for your reply
 

Re: Please help!!! AT25256 read wrong data!!!

I have encountered this issue for days.
you will get a lot more help by posting your code and schematic.
without that others will just guess what the problem is, it can be anything.
 

WP,HOLD connect to VCC(5V)
#define CS P1_0
#define DO P1_1
#define DI P1_2
#define SK P1_3

and my functions are...
Code:
	CS=1;
	CB();
	CS=0;
	delay(3);
	out_cmd(WREN);
	delay(3);
	CS=1;

	CB();
	CS=0;
	delay(3);
	out_cmd(WRSR);
	delay(10);
	out_cmd(0x00);
	delay(3);
	CS=1;	

	CB();
	CS=0;
	delay(3);
	out_cmd(WRDI);
	delay(3);
	CS=1;
Code:
unsigned char read_93c66(unsigned int rd_addr)
{ 
   	unsigned char i;	
   	unsigned char rd_word=0;
	unsigned char rd_address[2];

	rd_address[0] = rd_addr&0x00FF;
	rd_address[1] = rd_addr>>8;

	CB();
	CS=0;
	delay(10);
	out_cmd(READ);
	delay(10);
	out_cmd(rd_address[1]);
	delay(10);
	out_cmd(rd_address[0]);
	delay(3);
	for(i=0;i<8;i++)				
	 {	
		rd_word<<=1;
		SK=0;
       	SK=1;
       	if(DO==1)
	  	  rd_word|=0x01; 
     }
	delay(10);	
    CS=1; 
   return(rd_word);	
} /* read_93c66 */
Code:
void write_93c66(unsigned int wr_addr,unsigned char wr_word)
{ 
	unsigned char wr_address[2];

	wr_address[0] = wr_addr&0x00FF;
	wr_address[1] = wr_addr>>8;

   	CB();
	CS=0;
	delay(3);
   	out_cmd(WREN);
	delay(10); 	
   	CS=1;

	CB();
	CS=0;
	delay(3);
	out_cmd(WRITE);
	delay(10);
	out_cmd(wr_address[1]);
	delay(10);
	out_cmd(wr_address[0]);
	delay(10);
	out_cmd(wr_word);
	delay(10);
	CS=1;

	CB();
	CS=0;
	delay(3);
	out_cmd(WRDI);
	delay(10);
	CS=1;
} /* read_93c66 */
Code:
void out_cmd(unsigned char command)
{
  	unsigned char i;
  	for(i=0;i<8;i++)		
    {
       	if(command & 0x80)
	 		DI=1;
       	else
         	DI=0;	
       	SK=0;
		SK=1;
       	command<<=1;		 
    }  
} /* out_cmd */
Code:
void CB(void)
{
	unsigned char i;
	unsigned char rd_word=0;
	
	do
	{
		CS=0;
		delay(3);
		out_cmd(RDSR);
		delay(3);
		for(i=0;i<8;i++)
		 {
			SK=0;
		   	SK=1;
			rd_word<<=1;
		   	if(DO==1)
		  	  rd_word|=0x01;	
		 }
		delay(10);
		CS=1;
	}while((rd_word&0x01)==0x01);		
} /* CheckBusy */
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…