Archive | lpc2148 RSS feed for this section

Interfacing external memory with LPC2148 using I2C Protocol

10 Mar

I am using a LPC2148 development board from NSK Electronics. It has a slot for inserting external memory,I’ve used 24C02 chip.

LPC2148 has an inbuilt module for i2c protocol. All we need to know is how to use these registers.But before you dive into i2c of arm7,you need to learn to program for lpc2148 interrupts.Any interrupt as a matter of fact,because the i2c interrupt generation is very crucial.

Check out the below link  to learn more on interrupts in lpc2148

LPC2148 Interrupt Tutorial

The registers used for i2c are

I2C0CONSET,I2C0CONCLR,I2C0STAT,I2C0DAT

I2C0SCLH & I2C0SCLL used to set the bit frequency. The Pclk clock value I’ve taken is 15MHz.

LPC2148 is the master when writing into EEPROM and when it is reading.

Therefore Master transmit & receive mode.

The I2C0STAT register will tell you the status of the i2c module in arm,on when the interrupt flag SI is set. otherwise it will give you a value 0xf8. Therefore you can read the status only in the ISR which you have written for i2c interrupt.The SI flag gets SET automatically each time and it’s very important to clear the flag each time you enter the ISR.

Don not set all the bits in I2C0CONSET,I2C0CONCLR at one short.Go according to the steps required for i2c communication.

write-i2c

Writing into EEPROM

#include<lpc214x.h>
#include<stdio.h>
#include”appdef.h”
#include”armlcd.h”

int c=1;

static int i=0;
unsigned char buf[12]=”YES YAMAHA”;
__irq void led(void)
{
switch(I2C0STAT)
{
case 0x08 : lcd(‘s’); //start
I2C0CONCLR=BIT3+BIT5;  // clr start & SI bit
I2C0DAT=0xa0;  //device address
break;

case 0x10 : lcd(‘b’);
I2C0CONCLR=BIT3;  // clearing SIbit
break;

case 0x18 : lcd(‘a’);
I2C0CONCLR=BIT3;
I2C0DAT=0x00; // memory address
break;
case 0x28 : lcd(‘k’);
I2C0CONCLR=BIT3;
switch(c)
{
case 1 :
I2C0DAT=buf[i];  // writing data into EEPROM
lcd(‘m’);
i++;
if(i==10) //10 characters
{
c++;
}
break;

case 2: I2C0CONSET=BIT4; // stop bit
lcd(‘p’);
break;

}

break;
case 0x30 : lcd(‘n’);
I2C0CONCLR=BIT3+BIT5;
break;

default: lcd(‘f’);
break;
}

VICVectAddr=0x00;
}

int main()
{
rs_clr();
en_clr();
lcd_init();
rs_set();
en_clr();
lcd(‘i’);
PINSEL0=BIT4+BIT6;  // scl & sda pin
VICVectCntl0=0x29;
VICVectAddr0=(unsigned) led;
VICIntEnable=BIT9;

I2C0CONSET=BIT6;
I2C0CONCLR=BIT3+BIT2+BIT4;
I2C0SCLH=0x4B;   //100 MHz bit freq
I2C0SCLL=0x4B;

I2C0CONSET|=BIT5;  //start bit

}
void lcd_init()
{
unsigned int i;
PINSEL0 = 0x00000000;

lcd_dir_write(); // output port
for (i=0;i<1000;i++);
lcd(0x33);
lcd(0x32);
lcd(0x28);
lcd(0x0e);
lcd(0x01);
lcd(0x06);
lcd(0x80);

for (i=0;i<1000000;i++);
}

void lcd(unsigned char val)
{
lcd1(val>>4);
lcd1(val);
}

void lcd1(unsigned char c)
{
unsigned int i;
IOCLR0 = 0x00f00000;
IOSET0 = (c<<20); // d4 connected to 20th port pin
en_set();
for (i=0;i<1000000;i++);
en_clr();
}

I’ve used lcd in 4bit mode to display my output. At certain places I have passed character to lcd function,just to check for the proper functioning.Helps in debugging.You can take it off,if you want.

Software used:keil and philips utility