Discussion in "8051 Discussion Forum" started by    Nals99    Jul 3, 2015.
Fri Jul 03 2015, 02:22 pm
#1
Hi guys...

I'm having some problems to transmit data to a eeprom with TWi peripherical with AT89C51IC2.

I can read from the EEprom, but I can't write.

Here is my code:

#define N 128

unsigned char code addrRead[] = { 0xA0,	0x00, 0xA1};
unsigned char code addrWrite[] = { 0xA1, 0x00, 'T', 'e', 's', 't', 'e', ' ', 'n', 'r', '1', '!'};

unsigned char xdata rBuffer[N], wBuffer[N];
unsigned char bufferIndex, addrIndex;
volatile bit completed, RW;

union int_char{
	int i;
	char ch[2];
};

void TWI_Master_Read()
{
	RW = 0;
	bufferIndex = 0;
	addrIndex = 0;
	SSCON |= 0xC1;				/* habilitar TWI; bit freq: 100kHz; enable TWI */    
	IEN1 |= 0x02;				/* habilitar interrupt TWI */
	SSCON |= 0x20;
}

void TWI_Master_Write()
{
	RW = 1; 
	bufferIndex = 0;
	addrIndex = 0;	
	SSCON |= 0xC1;				/* habilitar TWI; bit freq: 100kHz; enable TWI */      
	IEN1 |= 0x02;				/* habilitar interrupt TWI */
	SSCON |= 0x20;
}

void printMessage()
{
	unsigned char i;
	com_initialize();	// CONFIGURO PORTA SERIE BAUDRATE: 9600bps
	
	EA = 1; 			/* habilitar interrupçoes */
	
	TWI_Master_Write();	
	while (!completed);

	
	TWI_Master_Read();
	while (!completed);
		
	printf ("Message: ");
	delay_ms(100);
	putchar('\n'); putchar('\r');
	for(i=0; i<N; i++){
		putchar(rBuffer[i]);
	}
	putchar('\n'); putchar('\r');
}

void main()
{
	printMessage();
	printf ("Message successfull read!!!");
	putchar('\n'); putchar('\r');
	while (1);
	
}

static void twi_isr() interrupt 8
{
		//////////////////////////////////////////////////////////////////////////////////////
		//																																									//
		//																				READ																			//
		//																																									//
		//////////////////////////////////////////////////////////////////////////////////////
	if (RW==0){
		switch (SSCS) {
			case (0x08):
				SSCON &= ~0x20; // desabilitar flag start
				SSDAT = addrRead[addrIndex++];		
				break;
		
			case (0x18):
				SSDAT = addrRead[addrIndex++];
				break;
		
			case (0x28):
				SSCON |= 0x20; // habilitar flag start
				break; // para assim enviar repeated start
		
			case (0x10):
				SSCON &= ~0x20;	// desabilito flag start
				SSDAT = addrRead[addrIndex++];
				break;
			
			case (0x38):
				addrIndex=0;
				break;
		
			case (0x40):
				SSCON |= 0x04; // activar acknowledge
				break;
			
			case (0x48):
				addrIndex=0;
				break;
		
			case (0x50):
				rBuffer[bufferIndex++] = SSDAT;
				if (bufferIndex < N - 1)
					SSCON |= 0x04; //enquanto nao leu tudo, continuo a retornar ack
				else
					SSCON &= ~0x04;
					completed = 1;
				break;
			
			case (0x58):
				rBuffer[bufferIndex] = SSDAT;
				completed = 1;
				SSCON |= 0x10;
				break;
		}
		SSCON &= ~0x08;                  /* clear interrupt flag */
	}
		//////////////////////////////////////////////////////////////////////////////////////
		//																																									//
		//																			WRITE																				//
		//																																									//
		//////////////////////////////////////////////////////////////////////////////////////
	else{
		switch (SSCS){	
			case (0x08):
				SSCON &= ~0x20; // clear flag start
				SSDAT = addrWrite[addrIndex++];
				
				break;
			
			case (0x10):
				SSCON &= ~0x20;	// clear flag start
				addrIndex=0;
				SSDAT = addrWrite[addrIndex++];
			
				break;		
			
			case (0x18):
				SSDAT = addrWrite[addrIndex++];			
				break;
		
			case (0x20):
				SSCON |= 0x20;
				break;
			
			case (0x28):
				SSDAT = addrWrite[bufferIndex++];
				if ((bufferIndex < N - 1) && (addrWrite[bufferIndex] != NULL))
					;
				else
					SSCON |= 0x10;
				delay_ms(5);
				break;
			
			case (0x30):
				break;
		
			case (0x38):
				break;			
		}
		SSCON &= ~0x08;                  /* clear interrupt flag */
	}
}


The propose of this code is to use it in a IO expander, but for test only I'm doing this in a EEprom, so i can really check if it Reading/witting correctely or not...

Can anyone help me with last 'switch' in the code?

Thanks in advance.
Regards
Nals
Mon Jul 13 2015, 04:08 pm
#2
Your switch case statement looks ok for write, but I don't see "completed" flag getting set anywhere when RW = 1. You need to understand that when writing into EEPROM, you cannot write more than a single page at a time. Also you need to give delay so that after your write cycle finishes, EEPROM starts an internal write operation which takes almost 5ms or more.

I think problem is in the write address your passing:
unsigned char code addrWrite[] = { 0xA1, 0x00, 'T', 'e', 's', 't', 'e', ' ', 'n', 'r', '1', '!'};
// Address should be 0xA0 for write and 0xA1 for read.
the LSB is for RW, RW = 0 for write and RW = 1 for read


Read more about i2c/twi in tutorial section http://www.8051projects.net/wiki/
 Nals99 like this.
Tue Jul 14 2015, 05:43 pm
#3
Problem solved...

Thanks...

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

EdwardFew
Mon Mar 18 2024, 01:14 pm
EmeryPah
Mon Mar 18 2024, 11:51 am
RobertMax
Sun Mar 17 2024, 10:22 pm
DanielJar
Fri Mar 15 2024, 06:52 pm
Tuzaimecor
Fri Mar 15 2024, 02:32 am
PromotionFoode
Thu Mar 14 2024, 08:11 pm
EdwardGeawn
Sun Mar 10 2024, 12:24 pm
ZacharyShado
Sat Mar 09 2024, 10:04 am