Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
02/26/09 12:48
Read: times


 
#162884 - code update
Responding to: ???'s previous message
Here is the program. I have implemented byte/sequential read/write operations and current read operation. Now it is reading the first two bytes of the test string.

#define SCL P1_6
#define SDA P1_7
#define EEPROM_READ_ADDR  0XA1
#define EEPROM_WRITE_ADDR 0XA0
#define HIGH  1
#define LOW   0
#define ACK   LOW
#define NACK  HIGH
#define SUCCESS HIGH
#define ERROR LOW

#define TEST_NUM 0x81

__sbit __at (0x96) P1_6 ;
__sbit __at (0x97) P1_7 ;


/* I2C functions */
void start()
{
	/* I2C START condition */
	SCL = SDA = HIGH;
	NOP;
	SDA = LOW;
	NOP;
	SCL = LOW;
}

void stop()
{
	/* I2C STOP condition */
	SDA = LOW;
	SCL = HIGH;
	NOP;
	SDA = HIGH;
	NOP;
	SCL = LOW;
}

unsigned char clock()
{
	/* A subroutine to generate a clock pulse and return the
	 * status of the data bus during the clock period */
	unsigned char status = 0;
	SCL = HIGH;
	NOP;
	while(!SCL);		/* eliminate ripples */
	status = SDA;
	SCL = LOW;
	return (status);
}

unsigned char write(unsigned char byte)
{
	/* I2C WRITE operation, Write a byte on SDA and return the
	 * acknowledgement */
	unsigned char mask = 0x80;
	unsigned char status= ACK;
	
	for ( ; mask > 0 ;  ) {
		SDA = (byte & mask) ? ( SET ):( CLEAR ) ;
		mask >>= 1;
		clock();
	}
 	return (clock());	/* return the status of SDA line on
				 * the 9th pulse */
}

unsigned char read(unsigned char status)
{
	/* I2C READ operation, read one byte from the transmitter and
	 * give ack/nack to it */
	unsigned char byte = 0;
	unsigned char count, level = 0;
	SDA = HIGH;		/* configure SDA as input */
	for ( count = 0; count < 8; count++ ) {
		byte <<= 1;
		level = clock();
		byte |= level;		
	}
	SDA = status;		/* status = 1 :- NACK
				 * status = 0 :- ACK */
	clock();
	return byte;
}

/* EEPROM functions */
unsigned char byte_write( unsigned int addr, unsigned char val )
{
	/*  A write operation requires two 8-bit data word addresses
	 *  following the device address word and acknowledgment. Upon
	 *  receipt of this address, the EEPROM will again respond
	 *  with and then clock in the first 8-bit data
	 *  word. Following receipt of the 8-bit data word, the EEPROM
	 *  will output . The addressing device, such as a
	 *  microcontroller, then must terminate the write sequence
	 *  with a stop condition. At this time the EEPROM enters an
	 *  internally-timed write cycle, tWR, to the nonvolatile
	 *  memory.  All inputs are disabled during this write cycle
	 *  and the EEPROM will not respond until the write is
	 *  complete */

	unsigned char status = ERROR;
	
	start();
	
	if ( write(EEPROM_WRITE_ADDR) == ACK ) {
		if ( write( (addr & 0xFF00) >> 8 ) == ACK ) {
			if ( write( (addr & 0x00FF) ) == ACK ) {
				if ( write(val) == ACK ) {
					status = SUCCESS;
				}
				else
					print_on_lcd("write val failed!!");
			}
			else
				print_on_lcd("write low byte failed!!");	
		}
		else
			print_on_lcd("write high byte failed!!");		
	}
	else
		print_on_lcd("write device id failed!!");
	

	stop();
	
	delay_millisec(10); 		/* Twr = 10ms max */

	return status;
}


unsigned char page_write(unsigned int addr, const unsigned char *str )
{
	/* A page write sequence. A maximum of 128 bits are
	 * permissable beyond which a page over write occurs */

	unsigned char status = ERROR;
	unsigned char bytes;

	start();

	if ( write(EEPROM_WRITE_ADDR) == ACK ) {
		if ( write( (addr & 0xFF00) >> 8 ) == ACK ) {
			if ( write( (addr & 0x00FF) ) == ACK ) {
				for ( bytes = 0; str[bytes]; bytes++ ) {
					if (bytes <= 127) {
			/* check for page overflow*/
						if ( write(str[bytes]) != ACK ) {
							print_on_lcd("page write to EEPROM failed!!");
							status = ERROR;
							goto STOP;
						}
					}
					else { /* This byte needs to be
						* written to the next
						* page*/
						
						stop(); /* stop the
							 * operation  */
						
						delay_millisec(10);
						status = page_write( addr+1, str); 
						/* perform a page
						 * write again */
						return status;
					}
				}
				write(''); /* write nul character at
					      * at the end of the
						string */
			
				status = SUCCESS;
			}
			else
				print_on_lcd("write low byte failed!!");	
		}
		else
			print_on_lcd("write high byte failed!!");		
	}
	else
		print_on_lcd("write device id failed!!");


 STOP:
	stop();

	delay_millisec(10);
	return status;
}


unsigned char byte_read( unsigned int addr )
{
	/* A random read requires byte write sequence to load in the
	 * data word address. Once the device address word and data
	 * word address are clocked in and acknowledged by the EEPROM,
	 * the microcontroller must generate another start
	 * condition. The microcontroller now initiates a current
	 * address read by sending a device address with the
	 * Read/Write select bit high. The EEPROM acknowledges the
	 * device address and serially clocks out the data word. The
	 * microcontroller does not respond with but does generate a
	 * following stop condition */
	
	unsigned char val = ERROR;

	start();
	if ( write(EEPROM_WRITE_ADDR) == ACK ) {
		if ( write( (addr & 0xFF00) >> 8 ) == ACK ) {
			if ( write( (addr & 0x00FF) ) == ACK ) {
				/* Dummy write successful */
				start();

				if ( write(EEPROM_READ_ADDR) == ACK) {
					val = read(NACK);
				}
				else
					print_on_lcd("write device Read id failed!!!");
			}
			else
				print_on_lcd("write addr low byte failed!!!");

		}
		else
			print_on_lcd("write addr high byte failed!!!");
	}
	else
		print_on_lcd("write device_write id failed!!!");

	stop();

	return val;
}

/* Current address Read */

unsigned char current_read()
{
	/* read a byte from the last address read/written + 1 */

	unsigned char byte = ERROR;
	
	start();

	if ( write(EEPROM_READ_ADDR) == ACK ) {
		byte = read(NACK);
	}
	else
		print_on_lcd("write(read id) failed!! ");

	stop();

	return byte;
}

/* Sequential read */
unsigned int seq_read( unsigned int size, __idata unsigned char *buf, unsigned int addr)
{
	/* read sequentially 'size' bytes to buffer 'buf' starting
	 * from address 'addr' */
	unsigned int num = 0;	/* count the number of bytes read */
	unsigned char byte = 0;
	
	buf[num] = byte_read(addr);
	num++;
	
	start();
	
	if ( write(EEPROM_READ_ADDR) == ACK ) {
		for (  ; size -1 ; size--, num++ ) {
			buf[num] = read(ACK);
			num++;
		}
		buf[num] = read(NACK); /* for last byte to be read */
		num++;
	}
	else
		print_on_lcd("Device not selected!");

	stop();
	return (num);
}

/* main program */

main()
{
	unsigned char addr = 0;
	unsigned int i = 0;
	__idata unsigned char buf[128] = ""; /* A null string */
	
	init_lcd();

	print_on_lcd("EEPROM test");
		
	if ( page_write( 0x00, "testing byte read operation") != SUCCESS ) /* writing a test string to memory */
		print_on_lcd("page_write() failed!!!");
	print_on_lcd("seq_read()");
	display_word( seq_read( 30, buf, 0x00) );
	print_on_lcd(buf);

	print_on_lcd("byte_read()");
	for ( i = 0; i < 30 ; i++){
		buf[i] = byte_read(i);
	}
	print_on_lcd(buf);
	while (1);	
}
 




List of 19 messages in thread
TopicAuthorDate
AT24C512 Sequential Read failed!!            01/01/70 00:00      
   the IIC engine is identical ...            01/01/70 00:00      
      Sample code            01/01/70 00:00      
   what are the symptoms?            01/01/70 00:00      
      symptoms            01/01/70 00:00      
   A common mistake...            01/01/70 00:00      
   Your code looks fine            01/01/70 00:00      
      It took me ages !            01/01/70 00:00      
         uint8_t range            01/01/70 00:00      
         confusion            01/01/70 00:00      
            you use uint8_t in your read_seq ()            01/01/70 00:00      
            Do you want the full corrected source code ?            01/01/70 00:00      
               my own code            01/01/70 00:00      
                  An explanation            01/01/70 00:00      
                     code update            01/01/70 00:00      
                        diff is your friend            01/01/70 00:00      
                           size -1            01/01/70 00:00      
                        write program, rather than code...            01/01/70 00:00      
                           It's Working            01/01/70 00:00      

Back to Subject List