Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

i2c communication protocol on lpc2148

Status
Not open for further replies.

embpic

Advanced Member level 3
Advanced Member level 3
Joined
May 29, 2013
Messages
742
Helped
80
Reputation
160
Reaction score
77
Trophy points
1,308
Location
india
Activity points
5,213
i am using keil and lpc2148 and interface with 24lc04 eeprom but facing problem and my code is

Code:
void init_i2c(void);
void i2c_start(void);
void i2c_stop(void);
void i2c_tc(void)__irq;

unsigned char read_d[6]={0},a;
unsigned char status;

void init_i2c(void)
{
 I2C0CONCLR=0x6C;
	I2C0CONSET = 0x40;
	I2C0CONCLR = 0x00;
	I2C0SCLH=80;
	I2C0SCLL=70;
	VICIntEnable |= 0x00000200;
	VICIntSelect |= 0x00000000;
	VICVectCntl0 = 0x00000029;
	VICVectAddr0 = (unsigned long)i2c_tc;
 PINSEL0&=0xFFFFFF0F;
 PINSEL0|=0x00000050;
}

void i2c_start(void)
{
	I2C0CONSET = 0x20;	
}

void i2c_stop(void)
{
	I2C0CONSET = 0x10;	
}

void i2c_tc()__irq
{
	status = I2C0STAT; 
	I2C0CONCLR = 0x28;
	VICVectAddr = 0xff;
}

void write_eeprom(void)
{
	i2c_start();
	while(!(status & 0x08));
	I2C0DAT = 0xA0;
	while(!(status & 0x18));
	I2C0DAT = 0x00;
	while(!(status & 0x28));
	I2C0DAT = 0x00;
	while(!(status & 0x28));
	I2C0DAT = 'A';
	while(!(status & 0x28));
	I2C0DAT = 'B';
	while(!(status & 0x28));
	I2C0DAT = 'C';
	while(!(status & 0x28));
	I2C0DAT = 'D';
	while(!(status & 0x28));
	I2C0DAT = 'E';
	while(!(status & 0x28));
	i2c_stop();
}

void read_eeprom(void)
{
	i2c_start();
	while(!(status & 0x08));
	I2C0DAT = 0xA0;
	while(!(status & 0x18));	
	I2C0DAT = 0x00;
	while(!(status & 0x28));
		I2C0DAT = 0x00;
	while(!(status & 0x28));
	i2c_start();
	while(!(status & 0x10));	
	I2C0DAT = 0xA1;
	while(!(status & 0x40));
 // I2C0CONCLR=0x04;		 //set hardware to send nack
	
	for(a=0;a<4;a++)
	{
	read_d[a] = I2C0DAT;
  I2C0CONSET=0x04;	 		//set hardware to send  ack
	while(!(status & 0x50));
	}
	read_d[4] = I2C0DAT;
   I2C0CONCLR=0x04;		 //set hardware to send nack
	while(!(status & 0x58));
	i2c_stop();
}


i used status as per written in datasheet so what are the corrections in this code.

thanx..

- - - Updated - - -

and my full project is as follows
 

Attachments

  • I2C.rar
    61.5 KB · Views: 175

First of all initialize the variable status to zero.
i.e
Code:
unsigned char status = 0;

Secondly,
Code:
void write_eeprom(void)
{
	i2c_start();
	while(!(status & 0x08));          //stage 1
	I2C0DAT = 0xA0;
	while(!(status & 0x18));         //stage 2
	I2C0DAT = 0x00;
	while(!(status & 0x28));          //stage 3 
	I2C0DAT = 0x00;
	while(!(status & 0x28));         //stage 4
           .
           .
           .                                  // so on
}

In the above code, at stage 1 , when status will equal 0x08, the while condition !(0x08 & 0x08) = !(0x08) = FALSE, BUT
At stage 2, Since status already has Value of 0x08 >> the while condition !(0x08 & 0x18) = !(0x08) = FALSE,
So it will not wait for status to become 0x18 and break immediately. so is true for stage 3 & 4 and so on.
Either you clear Status after every while condition like this :
Code:
while(status != 0x08);          //stage 1
status = 0;	
I2C0DAT = 0xA0;

Or
You can use simple statements something like this:


Code:
	while(status != 0x08);          //stage 1
	I2C0DAT = 0xA0;
	while(status != 0x18);         //stage 2
	I2C0DAT = 0x00;
	while(status != 0x28);          //stage 3

Hope this helps.
 
Last edited:

@salmanliaquat

thanx for replying but processor doesn't get out of write eeprom (function)

- - - Updated - - -

ok it's getting out from the function but yet eeprm functions doesn't work?
if any one have any example post that one

thanx...
 

There is example I2C demo project available on keil website for LPC21XX.
But still i have attached that for your convenience. I have tested it, it works just fine.
 

Attachments

  • EX21-I2C.rar
    46.4 KB · Views: 172
  • Like
Reactions: embpic

    embpic

    Points: 2
    Helpful Answer Positive Rating
As salmanliaquat informed you, you must have code which will allow the I2C peripheral controller to process things to the next state (and your code will have to either be called again to handle the next state transition through polling or through interrupts). Review the example codes he posted, and if you still have problems with understanding how it works, I highly recommend that you download and read this document which I have found very helpful on the entire LPC21xx family which was written by Mr Trevor Martin - it has code examples of how to interface to all the peripherals in the family
**broken link removed**
 

yes sir problem is solved but my other problem remain as it is. that is usb interfacing and i have posted thread for it. this is also my problem to communicate with PC
 

Hai,

i think u got output for I2C protocol in lpc2148. now i am facing problem in that coding . Can please send me the executing code with project. it will be very useful for me.

thanks in advance
 

Hai,

i think u got output for I2C protocol in lpc2148. now i am facing problem in that coding . Can please send me the executing code with project. it will be very useful for me.

thanks in advance

check this code with eeprom interface
 

Attachments

  • I2C EEPROM.rar
    65.8 KB · Views: 140
hai,

i gave connection as per your instruction. now in PC hyper terminal, i got a message that " Read failed & write failed "

Reason may be :

1. your EEPROM is 24LC04 but i am using 24c02c. may be this is the reason for not getting output ????

2. I didn't use pullup resistor for both line. while i work with pic16f877a i use pullup resistor. whether it necessary to use pullup resistor ???
this also may be the reason i didn't get the output.

give me your suggestion .....
 

@embpic,...i am also trying to interface 24c512 to lpc2148 via i2c.i am getting problem in i2c read,...these r da steps i am following in i2c read,....
1.send start -0x08
2.send dev addr+write(0xa0) -0x18
3.send block addr -0x28
4.send block addr(twice for 16 bits addr) -0x28
5.send repeated start -0x10
6.send dev addr+read(0xa1) -0x40
.....
i am getting stuck in step 5 itself,..i am not getting status 0x10 back at all,..instead it is giving back 0x30..
plz can you guide me?
 

post your code for more details. did you use pull up resistor??
 

@embpic,..i m using 4.7k pull up resistor,...following is my code for i2c ..


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
unsigned char status=0;
void i2c0_stat(void) __irq
{                               
  status=I2C0STAT;
  I2C0CONCLR=0x28;              
  VICVectAddr = 0x00;           
}
 
void i2c0_init()
{
    PINSEL0&=0xFFFFFF0F;
 PINSEL0|=0x00000050;
 
 I2C0CONCLR=0x6C;
 I2C0CONSET=0x40;
 I2C0SCLH=80;
 I2C0SCLL=70;
 
  VICIntSelect = 0x00000000;        // Setting all interrupts as IRQ(Vectored)
 VICVectCntl2 = 0x20 | 9;       // Assigning Highest Priority Slot to I2C0 and enabling this slot
 VICVectAddr2 = (unsigned long)i2c0_stat; // Storing vector address of I2C0
 VICIntEnable = (1<<9);
 }
 
void i2c0_start()       //used //to send start condition.
{
    I2C0CONSET=0x20;        
}
 
 
void i2c0_stop()        //used //to send stop condition.
{
    I2C0CONSET=0x10;
}
 
void send_i2c0_byte(void)
{
    i2c0_start();
    while(status != 0x08);
    I2C0DAT = 0xA0;
    while(status != 0x18);
    I2C0DAT = 0x00;
    while(status != 0x28);
    I2C0DAT = 0x00;
    while(status != 0x28);
    I2C0DAT = 12;
    while(status != 0x28);
    i2c0_stop();
}
 
unsigned char read_i2c0_byte(void)          
{
    unsigned char temp;
    i2c0_start();
    while(status != 0x08);
    I2C0DAT = 0xA0;
    while(status != 0x18);
    I2C0DAT = 0x00;
    while(status != 0x28);
    I2C0DAT = 0x00;
    while(status != 0x28);
    i2c0_start();        
    while(status != 0x10); /**********HERE I get status as 0x30,..and program stucks here***********/
    I2C0DAT = 0xA1;
    while(status != 0x40);
    temp = I2C0DAT;
    I2C0CONCLR=0x04;         //set hardware to send nack
    while(status != 0x58);
    i2c0_stop();
    
    return temp;
}

 
Last edited:

here is my code
Code:
#include  <lpc214x.h>		   //Includes LPC2148 register definitions

#define MAX_BUFFER_SIZE 16
#define DEVICE_ADDR 0xA0
#define BLK_0 0x00
#define BLK_1 0x02
#define MAX_BLOCK_SIZE 256

#define LED1_ON() IO1SET=(1<<16)		//I2C write indicator
#define LED2_ON() IO1SET=(1<<17)		//I2C read indicator
#define LED3_ON() IO1SET=(1<<18)		//Comm failure indicator
#define LED4_ON() IO1SET=(1<<19)		//Comm success indicator

#define LED1_OFF() IO1CLR=(1<<16)	
#define LED2_OFF() IO1CLR=(1<<17)
#define LED3_OFF() IO1CLR=(1<<18)
#define LED4_OFF() IO1CLR=(1<<19)

#define Fosc            12000000                    
#define Fcclk           (Fosc * 5)                  
#define Fcco            (Fcclk * 4)                 
#define Fpclk           (Fcclk / 4) * 1            

#define  UART_BPS	9600	 //Set Baud Rate here



void Delay(unsigned char j);
void Init_UART0(void);
void UART0_SendByte(unsigned char data);
void UART0_SendStr(const unsigned char *str);
void Send_Start(void);
void Send_Stop(void);
unsigned char Send_I2C(unsigned char *Data,unsigned char Len);
unsigned char Read_I2C(unsigned char *Data,unsigned char Len);
unsigned char Page_Write(unsigned char BLOCK_NUMBER,unsigned char BLOCK_ADDR);
unsigned char Page_Read(unsigned int BLOCK_NUMBER,unsigned char BLOCK_ADDR);
unsigned char I2C_Status(unsigned char status_code);


unsigned char I2C_WR_Buf[MAX_BUFFER_SIZE]={"  Nex Robotics  "};
unsigned char I2C_RD_Buf[MAX_BUFFER_SIZE];
unsigned char Status=0;
unsigned char Status_Flag=0;

void  Delay(unsigned char j)
{  
 unsigned int  i;
 for(;j>0;j--)
 {
  for(i=0; i<60000; i++);
 } 
}



void  Init_UART0(void)
{  
   unsigned int Baud16;
   U0LCR = 0x83;		            // DLAB = 1
   Baud16 = (Fpclk / 16) / UART_BPS;  
   U0DLM = Baud16 / 256;							
   U0DLL = Baud16 % 256;						
   U0LCR = 0x03;
}
				

void UART0_SendByte(unsigned char data)
{  
   U0THR = data;				    
   while( (U0LSR&0x40)==0 );
   return;	    
}
                               

void  UART0_SendStr(const unsigned char *str)	 //A function to send a string on UART0
{  
   while(1)
   {  
      if( *str == '\0' ) break;
      UART0_SendByte(*str++);	    
   }
}


void Send_Start()
{
 I2C0CONSET=0x20; 
}


void Send_Stop()
{
 I2C0CONSET=0x10;
}



// This function sends sequential data to the EEPROM 24LC04
// The buffer size for EEPROM 24LC04 is 16 bytes
// The Len parameter should not exceed this value
unsigned char Send_I2C(unsigned char *Data,unsigned char Len)
{
 while(Len)
 {
  I2C0DAT=*Data;
  if(I2C_Status(0x28))
  {
   return 1;
  }
  Len--;
  Data++;
 }
 return 0;
}


// This function reads random data from the EEPROM 24LC04

unsigned char Read_I2C(unsigned char *Data,unsigned char Len)
{
 while(Len)
 {
  if(Len==1)  //Last byte
  {
   I2C0CONCLR=0x04;		 //set hardware to send nack
   if(I2C_Status(0x58))	//last byte has been received and NACK has been returned
   {
    return 1;
   }
   *Data=I2C0DAT;
  }
  else
  {
   I2C0CONSET=0x04;	 		//set hardware to send  ack
   if(I2C_Status(0x50))	//Byte has been received ACK has been returned
   {
    return 1;
   }
   *Data=I2C0DAT;	
  } 
  Data++;
  Len--;
 }
 return 0;
}


unsigned char I2C_Status(unsigned char status_code)
{
 while(Status_Flag==0);
 Status_Flag=0;
 if(Status!=status_code)
 {
  return 1;
 }
 else
 {
  return 0;
 }
}


unsigned char Page_Write(unsigned char BLOCK_NUMBER,unsigned char BLOCK_ADDR)
{
 Send_Start();
 if(I2C_Status(0x08))	//Start has been transmitted
 {
  return 1;
 }

 I2C0DAT=DEVICE_ADDR | BLOCK_NUMBER;	// Send Address
 if(I2C_Status(0x18))					//Device address, block num and write has been transmitted
 {
  return 1;
 }

 I2C0DAT=BLOCK_ADDR;	// Send block address
 if(I2C_Status(0x28))	//Block address has been transmitted
 {
  return 1;
 }

 if(Send_I2C(I2C_WR_Buf,MAX_BUFFER_SIZE))			//Send Data
 {
  Send_Stop();
  return 1;
 }
 Send_Stop();
 return 0;
}


unsigned char Page_Read(unsigned int BLOCK_NUMBER,unsigned char BLOCK_ADDR)
{
 Send_Start();
 if(I2C_Status(0x08))	//Start has been transmitted
 {
  return 1;
 }

 I2C0DAT=DEVICE_ADDR | BLOCK_NUMBER;	// Send Address
 if(I2C_Status(0x18))	//Device address, block num and write has been transmitted
 {
  return 1;
 }

 I2C0DAT=BLOCK_ADDR;
 if(I2C_Status(0x28))	//Block address has been transmitted
 {
  return 1;
 }

 Send_Start();		     // Repeat Start
 if(I2C_Status(0x10))	//Repeated Start has been transmitted
 {
  return 1;
 }

 I2C0DAT=DEVICE_ADDR | BLOCK_NUMBER | 0x01;			//Device address, block num and read has been transmitted
 if(I2C_Status(0x40))	//
 {
  return 1;
 }
 if(Read_I2C(I2C_RD_Buf,MAX_BUFFER_SIZE))			//Receive 16bytes of Data from EEPROM
 {
  Send_Stop();
  return 1;
 }
 Send_Stop();
 return 0;
}


void  __irq I2C0_Status(void)
{ 
  Status_Flag=0xFF; 			//update status flag
  Status=I2C0STAT;				//Read Status byte
  I2C0CONCLR=0x28;				
  VICVectAddr = 0x00;   		//Acknowledge Interrupt
}	


void I2C_Init()
{
 PINSEL0&=0xFFFFFF0F;
 PINSEL0|=0x00000050;

 I2C0CONCLR=0x6C;
 I2C0CONSET=0x40;
 I2C0SCLH=80;
 I2C0SCLL=70;

 /*  Init VIC for I2C0	*/
 VICIntSelect = 0x00000000;		// Setting all interrupts as IRQ(Vectored)
 VICVectCntl0 = 0x20 | 9;		// Assigning Highest Priority Slot to I2C0 and enabling this slot
 VICVectAddr0 = (unsigned long)I2C0_Status; // Storing vector address of I2C0
 VICIntEnable = (1<<9);	

}

int  main(void)
{  
 PINSEL0 = 0x00000005;		// Enable GPIO on all pins
 PINSEL1 = 0x00000000;
 PINSEL2 = 0x00000000;
 IO1DIR = (1<<19) | (1<<18) | (1<<17) | (1<<16);		// Set P1.16, P1.17, P1.18, P1.19 as Output
 LED1_OFF();LED2_OFF();LED3_OFF();LED4_OFF();
 Init_UART0();
 I2C_Init();
 
 LED1_ON();  //Write Indicator
 if(Page_Write(BLK_1,0x00))
 {
  UART0_SendStr("Write Failed");
  LED3_ON();
 }
 LED1_OFF();

 Delay(1);

 LED2_ON();	//Read indicator
 if(Page_Read(BLK_1,0x00))
 {
  UART0_SendStr("Read Failed");
  LED3_ON();
 }
 else
 {
  UART0_SendStr(I2C_RD_Buf);
  LED4_ON();
 }
 LED2_OFF();
 while(1)
 {
  
 }	
 
 
}
 

@embpic,..i tried your code with lpc2148 and at24c04,...its not working,...i also tried by changing e2prom ic,..its showing error of write failed and read failed,..what could be the problem ??
I have worked on same lpc2148 board with i2c,..interfacing digital accelerometer mma8451 and i was successful in that,that i2c library is also not working,..i have also checked hardware connections,..they are also perfect,,....what could be done now ?
 

i will work code soon bcoz this is old code and not checked.
 

Dear user

check out step by step, first check the pinsel configurations, whether u r using polling or interrupt , if it is interrupt , properly enable Interrupt and vector slot for the isr function, also check the voltage of the i2c bus it must be 3.3v use resistor configurations as 1K or 3.3 K

Regards
Sundar
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top