Forums

LPC2378 LCD driver

Started by Nagasrinivas October 26, 2011
Hi,

I am trying to write a LCD driver for lpc2378. Below is the code I wrote:

/********************************/
/* LCD Driver Module for LPC2378*/
/* by Naga */
/********************************/
/*** This LCD accepts data in ***/
/*** groups of four bits ********/

#include"lpc23xx.h"

/******** Declarations **********/

#define BIT0 (1<<0)
#define BIT1 (1<<1)
#define BIT2 (1<<2)
#define BIT3 (1<<3)

#define SHIFT_EN 0 /* Connected to P0.0 */
#define SHIFT_RS 8 /* Connected to P0.8 */
#define SHIFT_BIT0 25 /* Connected to P0.25 */
#define SHIFT_BIT1 18 /* Connected to P1.18 */
#define SHIFT_BIT2 23 /* Connected to P1.23 */
#define SHIFT_BIT3 27 /* Connected to P1.27 */

#define LCD_DATA_MASK (BIT0|BIT1|BIT2|BIT3)

#define POWER_DELAY 100000
#define CLEAR_DELAY 5000
#define BIT_DELAY 2000
const unsigned char lcd_init [5] = {0x33,0x32,0x2C,0x06,0x0C};
char name[] = {'N','A','G','A','\0'};

/****** Function Prototypes *****/

void init(void);
void delay(unsigned int);
void command_data(unsigned char, int);
void clear_screen(void);
void lcd_print(char*);

/******** main ******************/

int main()
{
/* Register to set pins P0.0 and P0.8 as GPIO pins */
PINSEL0 = 0x00;

/* Register to set the pin P0.25 as GPIO pin */
PINSEL1 = 0x00;

/* Register to set pins P1.18, P1.23, P1.27 as GPIO pins */
PINSEL3 = 0x00;

/* Register to set the directions of the pins P0.1, P0.8, P0.25 as outputs*/
IO0DIR = ((1 << 25)|(1 << 8)|(1 << 0));

/* Register to set the directions of pins P1.18, P1.23, P1.27 as outputs */
IO1DIR = ((1 << 27)|(1 << 23)|(1 << 18));

/* Call init function to intialize the lcd */
init();

/* Function to clear the screen */
//clear_screen();

while(1)
{
/* Function to print something on the LCD */
//lcd_print(name);
clear_screen();
}
}

void init(void)
{
unsigned int i;

/* After cd is powered up, give it time to PINtle */
delay(POWER_DELAY);

/* Send commands to initalize the lcd */
for(i=0; i<5; i++)
{
command_data(lcd_init[i], 0);
delay(10000);
}

}

void delay(unsigned int delay)
{
unsigned int i, j;
for(i=0; i {
for(j=0;j<40;j++);
}
}

void command_data(unsigned char data, int mask)
{
unsigned char upp_nib, low_nib;

/* upper nibble */
upp_nib = data >> 4;
upp_nib = upp_nib & LCD_DATA_MASK;

/* To enable LCD to distinguish between commands and data */
if(mask)
IO0PIN = 1 << SHIFT_RS;
else
IO0PIN = 1 << SHIFT_RS;
/* After we get the upper nibble, set or clear the respective registers */

/* BIT0 */
if(upp_nib & BIT0)
IO0PIN = 1 << SHIFT_BIT0;
else
IO0PIN = 1 << SHIFT_BIT0;

/* BIT1 */
if(upp_nib & BIT1)
IO1PIN = 1 << SHIFT_BIT1;
else
IO1PIN = 1 << SHIFT_BIT1;

/* BIT2 */
if(upp_nib & BIT2)
IO1PIN = 1 << SHIFT_BIT2;
else
IO1PIN = 1 << SHIFT_BIT2;

/* BIT3 */
if(upp_nib & BIT3)
IO1PIN = 1 << SHIFT_BIT3;
else
IO1PIN = 1 << SHIFT_BIT3;

delay(BIT_DELAY);

/* Enable signal transition, necessary for LCD to detect the signals */

IO0PIN = 1 << SHIFT_EN;
delay(BIT_DELAY);
IO0PIN = 1 << SHIFT_EN;

/* lower nibble */
low_nib = data & LCD_DATA_MASK;

/* After we get the upper nibble, set or clear the respective registers */

/* BIT0 */
if(low_nib & BIT0)
IO0PIN = 1 << SHIFT_BIT0;
else
IO0PIN = 1 << SHIFT_BIT0;

/* BIT1 */
if(low_nib & BIT1)
IO1PIN = 1 << SHIFT_BIT1;
else
IO0PIN = 1 << SHIFT_BIT1;

/* BIT2 */
if(low_nib & BIT2)
IO1PIN = 1 << SHIFT_BIT2;
else
IO1PIN = 1 << SHIFT_BIT2;

/* BIT3 */
if(low_nib & BIT3)
IO1PIN = 1 << SHIFT_BIT3;
else
IO1PIN = 1 << SHIFT_BIT3;

delay(BIT_DELAY);

/* Enable signal transition, necessary for LCD to detect the signals */
IO0PIN = 1 << SHIFT_EN;
delay(BIT_DELAY);
IO0PIN = 1 << SHIFT_EN;
}

void clear_screen(void)
{
command_data(0x01,0);
delay(CLEAR_DELAY);
command_data(0x02,0);
delay(CLEAR_DELAY);
}

/*void lcd_print(char *name)
{
unsigned int i = 0;
while(name[i]!='\0')
{
command_data(name[i],1);
delay(DATA_DELAY);
}
}*/

But I cannot even get the LCD initialized forget about printing something. I would really appreciate any help that would enable to make some progress.

Sincerely,
Naga.

An Engineer's Guide to the LPC2100 Series

Mate, I could not read your code, It is full of register access making it
heavy to read, sorry, but I think I can help you, I've got a demo of my own
with a LCD peripherical routine to drive a TFT 24bits screen, if you'd like
to have a look on it, this is the link for downloading:
http://code.google.com/p/selivre/downloads/detail?name=Drawing%20Demo-platform-rev1.tar.gz#makechanges

tell me if you get in trouble with my demo code.

2011/10/25 Nagasrinivas

> **
> Hi,
>
> I am trying to write a LCD driver for lpc2378. Below is the code I wrote:
>
> /********************************/
> /* LCD Driver Module for LPC2378*/
> /* by Naga */
> /********************************/
> /*** This LCD accepts data in ***/
> /*** groups of four bits ********/
>
> #include"lpc23xx.h"
>
> /******** Declarations **********/
>
> #define BIT0 (1<<0)
> #define BIT1 (1<<1)
> #define BIT2 (1<<2)
> #define BIT3 (1<<3)
>
> #define SHIFT_EN 0 /* Connected to P0.0 */
> #define SHIFT_RS 8 /* Connected to P0.8 */
> #define SHIFT_BIT0 25 /* Connected to P0.25 */
> #define SHIFT_BIT1 18 /* Connected to P1.18 */
> #define SHIFT_BIT2 23 /* Connected to P1.23 */
> #define SHIFT_BIT3 27 /* Connected to P1.27 */
>
> #define LCD_DATA_MASK (BIT0|BIT1|BIT2|BIT3)
>
> #define POWER_DELAY 100000
> #define CLEAR_DELAY 5000
> #define BIT_DELAY 2000
>
> const unsigned char lcd_init [5] = {0x33,0x32,0x2C,0x06,0x0C};
> char name[] = {'N','A','G','A','\0'};
>
> /****** Function Prototypes *****/
>
> void init(void);
> void delay(unsigned int);
> void command_data(unsigned char, int);
> void clear_screen(void);
> void lcd_print(char*);
>
> /******** main ******************/
>
> int main()
> {
> /* Register to set pins P0.0 and P0.8 as GPIO pins */
> PINSEL0 = 0x00;
>
> /* Register to set the pin P0.25 as GPIO pin */
> PINSEL1 = 0x00;
>
> /* Register to set pins P1.18, P1.23, P1.27 as GPIO pins */
> PINSEL3 = 0x00;
>
> /* Register to set the directions of the pins P0.1, P0.8, P0.25 as
> outputs*/
> IO0DIR = ((1 << 25)|(1 << 8)|(1 << 0));
>
> /* Register to set the directions of pins P1.18, P1.23, P1.27 as outputs */
> IO1DIR = ((1 << 27)|(1 << 23)|(1 << 18));
>
> /* Call init function to intialize the lcd */
> init();
>
> /* Function to clear the screen */
> //clear_screen();
>
> while(1)
> {
> /* Function to print something on the LCD */
> //lcd_print(name);
> clear_screen();
> }
> }
>
> void init(void)
> {
> unsigned int i;
>
> /* After cd is powered up, give it time to PINtle */
> delay(POWER_DELAY);
>
> /* Send commands to initalize the lcd */
> for(i=0; i<5; i++)
> {
> command_data(lcd_init[i], 0);
> delay(10000);
> }
>
> }
>
> void delay(unsigned int delay)
> {
> unsigned int i, j;
> for(i=0; i > {
> for(j=0;j<40;j++);
> }
> }
>
> void command_data(unsigned char data, int mask)
> {
> unsigned char upp_nib, low_nib;
>
> /* upper nibble */
> upp_nib = data >> 4;
> upp_nib = upp_nib & LCD_DATA_MASK;
> /* To enable LCD to distinguish between commands and data */
> if(mask)
> IO0PIN = 1 << SHIFT_RS;
> else
> IO0PIN = 1 << SHIFT_RS;
>
> /* After we get the upper nibble, set or clear the respective registers */
>
> /* BIT0 */
> if(upp_nib & BIT0)
> IO0PIN = 1 << SHIFT_BIT0;
> else
> IO0PIN = 1 << SHIFT_BIT0;
>
> /* BIT1 */
> if(upp_nib & BIT1)
> IO1PIN = 1 << SHIFT_BIT1;
> else
> IO1PIN = 1 << SHIFT_BIT1;
>
> /* BIT2 */
> if(upp_nib & BIT2)
> IO1PIN = 1 << SHIFT_BIT2;
> else
> IO1PIN = 1 << SHIFT_BIT2;
>
> /* BIT3 */
> if(upp_nib & BIT3)
> IO1PIN = 1 << SHIFT_BIT3;
> else
> IO1PIN = 1 << SHIFT_BIT3;
>
> delay(BIT_DELAY);
>
> /* Enable signal transition, necessary for LCD to detect the signals */
>
> IO0PIN = 1 << SHIFT_EN;
> delay(BIT_DELAY);
> IO0PIN = 1 << SHIFT_EN;
>
> /* lower nibble */
> low_nib = data & LCD_DATA_MASK;
>
> /* After we get the upper nibble, set or clear the respective registers */
>
> /* BIT0 */
> if(low_nib & BIT0)
> IO0PIN = 1 << SHIFT_BIT0;
> else
> IO0PIN = 1 << SHIFT_BIT0;
>
> /* BIT1 */
> if(low_nib & BIT1)
> IO1PIN = 1 << SHIFT_BIT1;
> else
> IO0PIN = 1 << SHIFT_BIT1;
>
> /* BIT2 */
> if(low_nib & BIT2)
> IO1PIN = 1 << SHIFT_BIT2;
> else
> IO1PIN = 1 << SHIFT_BIT2;
>
> /* BIT3 */
> if(low_nib & BIT3)
> IO1PIN = 1 << SHIFT_BIT3;
> else
> IO1PIN = 1 << SHIFT_BIT3;
>
> delay(BIT_DELAY);
>
> /* Enable signal transition, necessary for LCD to detect the signals */
> IO0PIN = 1 << SHIFT_EN;
> delay(BIT_DELAY);
> IO0PIN = 1 << SHIFT_EN;
> }
>
> void clear_screen(void)
> {
> command_data(0x01,0);
> delay(CLEAR_DELAY);
> command_data(0x02,0);
> delay(CLEAR_DELAY);
> }
>
> /*void lcd_print(char *name)
> {
> unsigned int i = 0;
> while(name[i]!='\0')
> {
> command_data(name[i],1);
> delay(DATA_DELAY);
> }
> }*/
>
> But I cannot even get the LCD initialized forget about printing something.
> I would really appreciate any help that would enable to make some progress.
>
> Sincerely,
> Naga.
>
>
>


It is clear the OP is driving a character-based HD44780 display. A 24-bpp
driver won't help one iota, so he'll be in trouble from the start.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
SolderCore running Defender... http://www.vimeo.com/25709426

> -----Original Message-----
> From: l... [mailto:l...] On
> Behalf Of Felipe de Andrade Neves L.
> Sent: 26 October 2011 15:27
> To: l...
> Subject: Re: [lpc2000] LPC2378 LCD driver
>
> Mate, I could not read your code, It is full of register access making
> it heavy to read, sorry, but I think I can help you, I've got a demo of
> my own with a LCD peripherical routine to drive a TFT 24bits screen, if
> you'd like to have a look on it, this is the link for downloading:
> http://code.google.com/p/selivre/downloads/detail?name=Drawing%20Demo-
> platform-rev1.tar.gz#makechanges
>
> tell me if you get in trouble with my demo code.
>
> 2011/10/25 Nagasrinivas
>
> > **
> >
> >
> > Hi,
> >
> > I am trying to write a LCD driver for lpc2378. Below is the code I
> wrote:
> >
> > /********************************/
> > /* LCD Driver Module for LPC2378*/
> > /* by Naga */
> > /********************************/
> > /*** This LCD accepts data in ***/
> > /*** groups of four bits ********/
> >
> > #include"lpc23xx.h"
> >
> > /******** Declarations **********/
> >
> > #define BIT0 (1<<0)
> > #define BIT1 (1<<1)
> > #define BIT2 (1<<2)
> > #define BIT3 (1<<3)
> >
> > #define SHIFT_EN 0 /* Connected to P0.0 */ #define SHIFT_RS 8 /*
> > Connected to P0.8 */ #define SHIFT_BIT0 25 /* Connected to P0.25 */
> > #define SHIFT_BIT1 18 /* Connected to P1.18 */ #define SHIFT_BIT2 23
> > /* Connected to P1.23 */ #define SHIFT_BIT3 27 /* Connected to P1.27
> > */
> >
> > #define LCD_DATA_MASK (BIT0|BIT1|BIT2|BIT3)
> >
> > #define POWER_DELAY 100000
> > #define CLEAR_DELAY 5000
> > #define BIT_DELAY 2000
> >
> > const unsigned char lcd_init [5] = {0x33,0x32,0x2C,0x06,0x0C}; char
> > name[] = {'N','A','G','A','\0'};
> >
> > /****** Function Prototypes *****/
> >
> > void init(void);
> > void delay(unsigned int);
> > void command_data(unsigned char, int); void clear_screen(void); void
> > lcd_print(char*);
> >
> > /******** main ******************/
> >
> > int main()
> > {
> > /* Register to set pins P0.0 and P0.8 as GPIO pins */
> > PINSEL0 = 0x00;
> >
> > /* Register to set the pin P0.25 as GPIO pin */
> > PINSEL1 = 0x00;
> >
> > /* Register to set pins P1.18, P1.23, P1.27 as GPIO pins */
> > PINSEL3 = 0x00;
> >
> > /* Register to set the directions of the pins P0.1, P0.8, P0.25 as
> > outputs*/ IO0DIR = ((1 << 25)|(1 << 8)|(1 << 0));
> >
> > /* Register to set the directions of pins P1.18, P1.23, P1.27 as
> > outputs */ IO1DIR = ((1 << 27)|(1 << 23)|(1 << 18));
> >
> > /* Call init function to intialize the lcd */ init();
> >
> > /* Function to clear the screen */
> > //clear_screen();
> >
> > while(1)
> > {
> > /* Function to print something on the LCD */ //lcd_print(name);
> > clear_screen(); } }
> >
> > void init(void)
> > {
> > unsigned int i;
> >
> > /* After cd is powered up, give it time to PINtle */
> > delay(POWER_DELAY);
> >
> > /* Send commands to initalize the lcd */ for(i=0; i<5; i++) {
> > command_data(lcd_init[i], 0); delay(10000); }
> >
> > }
> >
> > void delay(unsigned int delay)
> > {
> > unsigned int i, j;
> > for(i=0; i > > {
> > for(j=0;j<40;j++);
> > }
> > }
> >
> > void command_data(unsigned char data, int mask) { unsigned char
> > upp_nib, low_nib;
> >
> > /* upper nibble */
> > upp_nib = data >> 4;
> > upp_nib = upp_nib & LCD_DATA_MASK;
> >
> >
> > /* To enable LCD to distinguish between commands and data */
> > if(mask)
> > IO0PIN = 1 << SHIFT_RS;
> > else
> > IO0PIN = 1 << SHIFT_RS;
> >
> > /* After we get the upper nibble, set or clear the respective
> > registers */
> >
> > /* BIT0 */
> > if(upp_nib & BIT0)
> > IO0PIN = 1 << SHIFT_BIT0;
> > else
> > IO0PIN = 1 << SHIFT_BIT0;
> >
> > /* BIT1 */
> > if(upp_nib & BIT1)
> > IO1PIN = 1 << SHIFT_BIT1;
> > else
> > IO1PIN = 1 << SHIFT_BIT1;
> >
> > /* BIT2 */
> > if(upp_nib & BIT2)
> > IO1PIN = 1 << SHIFT_BIT2;
> > else
> > IO1PIN = 1 << SHIFT_BIT2;
> >
> > /* BIT3 */
> > if(upp_nib & BIT3)
> > IO1PIN = 1 << SHIFT_BIT3;
> > else
> > IO1PIN = 1 << SHIFT_BIT3;
> >
> > delay(BIT_DELAY);
> >
> > /* Enable signal transition, necessary for LCD to detect the signals
> > */
> >
> > IO0PIN = 1 << SHIFT_EN;
> > delay(BIT_DELAY);
> > IO0PIN = 1 << SHIFT_EN;
> >
> > /* lower nibble */
> > low_nib = data & LCD_DATA_MASK;
> >
> > /* After we get the upper nibble, set or clear the respective
> > registers */
> >
> > /* BIT0 */
> > if(low_nib & BIT0)
> > IO0PIN = 1 << SHIFT_BIT0;
> > else
> > IO0PIN = 1 << SHIFT_BIT0;
> >
> > /* BIT1 */
> > if(low_nib & BIT1)
> > IO1PIN = 1 << SHIFT_BIT1;
> > else
> > IO0PIN = 1 << SHIFT_BIT1;
> >
> > /* BIT2 */
> > if(low_nib & BIT2)
> > IO1PIN = 1 << SHIFT_BIT2;
> > else
> > IO1PIN = 1 << SHIFT_BIT2;
> >
> > /* BIT3 */
> > if(low_nib & BIT3)
> > IO1PIN = 1 << SHIFT_BIT3;
> > else
> > IO1PIN = 1 << SHIFT_BIT3;
> >
> > delay(BIT_DELAY);
> >
> > /* Enable signal transition, necessary for LCD to detect the signals
> > */ IO0PIN = 1 << SHIFT_EN; delay(BIT_DELAY); IO0PIN = 1 << SHIFT_EN;
> }
> >
> > void clear_screen(void)
> > {
> > command_data(0x01,0);
> > delay(CLEAR_DELAY);
> > command_data(0x02,0);
> > delay(CLEAR_DELAY);
> > }
> >
> > /*void lcd_print(char *name)
> > {
> > unsigned int i = 0;
> > while(name[i]!='\0')
> > {
> > command_data(name[i],1);
> > delay(DATA_DELAY);
> > }
> > }*/
> >
> > But I cannot even get the LCD initialized forget about printing
> something.
> > I would really appreciate any help that would enable to make some
> progress.
> >
> > Sincerely,
> > Naga.
> >
> >
> >
>
>
>
>
>
>
>
>
>
lol, my fault.

2011/10/26 Paul Curtis

> **
> It is clear the OP is driving a character-based HD44780 display. A 24-bpp
> driver won't help one iota, so he'll be in trouble from the start.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
> SolderCore running Defender... http://www.vimeo.com/25709426
>
> > -----Original Message-----
> > From: l... [mailto:l...] On
> > Behalf Of Felipe de Andrade Neves L.
> > Sent: 26 October 2011 15:27
> > To: l...
> > Subject: Re: [lpc2000] LPC2378 LCD driver
>
> >
> > Mate, I could not read your code, It is full of register access making
> > it heavy to read, sorry, but I think I can help you, I've got a demo of
> > my own with a LCD peripherical routine to drive a TFT 24bits screen, if
> > you'd like to have a look on it, this is the link for downloading:
> > http://code.google.com/p/selivre/downloads/detail?name=Drawing%20Demo-
> > platform-rev1.tar.gz#makechanges
> >
> > tell me if you get in trouble with my demo code.
> >
> > 2011/10/25 Nagasrinivas
> >
> > > **
>
> > >
> > >
> > > Hi,
> > >
> > > I am trying to write a LCD driver for lpc2378. Below is the code I
> > wrote:
> > >
> > > /********************************/
> > > /* LCD Driver Module for LPC2378*/
> > > /* by Naga */
> > > /********************************/
> > > /*** This LCD accepts data in ***/
> > > /*** groups of four bits ********/
> > >
> > > #include"lpc23xx.h"
> > >
> > > /******** Declarations **********/
> > >
> > > #define BIT0 (1<<0)
> > > #define BIT1 (1<<1)
> > > #define BIT2 (1<<2)
> > > #define BIT3 (1<<3)
> > >
> > > #define SHIFT_EN 0 /* Connected to P0.0 */ #define SHIFT_RS 8 /*
> > > Connected to P0.8 */ #define SHIFT_BIT0 25 /* Connected to P0.25 */
> > > #define SHIFT_BIT1 18 /* Connected to P1.18 */ #define SHIFT_BIT2 23
> > > /* Connected to P1.23 */ #define SHIFT_BIT3 27 /* Connected to P1.27
> > > */
> > >
> > > #define LCD_DATA_MASK (BIT0|BIT1|BIT2|BIT3)
> > >
> > > #define POWER_DELAY 100000
> > > #define CLEAR_DELAY 5000
> > > #define BIT_DELAY 2000
> > >
> > > const unsigned char lcd_init [5] = {0x33,0x32,0x2C,0x06,0x0C}; char
> > > name[] = {'N','A','G','A','\0'};
> > >
> > > /****** Function Prototypes *****/
> > >
> > > void init(void);
> > > void delay(unsigned int);
> > > void command_data(unsigned char, int); void clear_screen(void); void
> > > lcd_print(char*);
> > >
> > > /******** main ******************/
> > >
> > > int main()
> > > {
> > > /* Register to set pins P0.0 and P0.8 as GPIO pins */
> > > PINSEL0 = 0x00;
> > >
> > > /* Register to set the pin P0.25 as GPIO pin */
> > > PINSEL1 = 0x00;
> > >
> > > /* Register to set pins P1.18, P1.23, P1.27 as GPIO pins */
> > > PINSEL3 = 0x00;
> > >
> > > /* Register to set the directions of the pins P0.1, P0.8, P0.25 as
> > > outputs*/ IO0DIR = ((1 << 25)|(1 << 8)|(1 << 0));
> > >
> > > /* Register to set the directions of pins P1.18, P1.23, P1.27 as
> > > outputs */ IO1DIR = ((1 << 27)|(1 << 23)|(1 << 18));
> > >
> > > /* Call init function to intialize the lcd */ init();
> > >
> > > /* Function to clear the screen */
> > > //clear_screen();
> > >
> > > while(1)
> > > {
> > > /* Function to print something on the LCD */ //lcd_print(name);
> > > clear_screen(); } }
> > >
> > > void init(void)
> > > {
> > > unsigned int i;
> > >
> > > /* After cd is powered up, give it time to PINtle */
> > > delay(POWER_DELAY);
> > >
> > > /* Send commands to initalize the lcd */ for(i=0; i<5; i++) {
> > > command_data(lcd_init[i], 0); delay(10000); }
> > >
> > > }
> > >
> > > void delay(unsigned int delay)
> > > {
> > > unsigned int i, j;
> > > for(i=0; i > > > {
> > > for(j=0;j<40;j++);
> > > }
> > > }
> > >
> > > void command_data(unsigned char data, int mask) { unsigned char
> > > upp_nib, low_nib;
> > >
> > > /* upper nibble */
> > > upp_nib = data >> 4;
> > > upp_nib = upp_nib & LCD_DATA_MASK;
> > >
> > >
> > > /* To enable LCD to distinguish between commands and data */
> > > if(mask)
> > > IO0PIN = 1 << SHIFT_RS;
> > > else
> > > IO0PIN = 1 << SHIFT_RS;
> > >
> > > /* After we get the upper nibble, set or clear the respective
> > > registers */
> > >
> > > /* BIT0 */
> > > if(upp_nib & BIT0)
> > > IO0PIN = 1 << SHIFT_BIT0;
> > > else
> > > IO0PIN = 1 << SHIFT_BIT0;
> > >
> > > /* BIT1 */
> > > if(upp_nib & BIT1)
> > > IO1PIN = 1 << SHIFT_BIT1;
> > > else
> > > IO1PIN = 1 << SHIFT_BIT1;
> > >
> > > /* BIT2 */
> > > if(upp_nib & BIT2)
> > > IO1PIN = 1 << SHIFT_BIT2;
> > > else
> > > IO1PIN = 1 << SHIFT_BIT2;
> > >
> > > /* BIT3 */
> > > if(upp_nib & BIT3)
> > > IO1PIN = 1 << SHIFT_BIT3;
> > > else
> > > IO1PIN = 1 << SHIFT_BIT3;
> > >
> > > delay(BIT_DELAY);
> > >
> > > /* Enable signal transition, necessary for LCD to detect the signals
> > > */
> > >
> > > IO0PIN = 1 << SHIFT_EN;
> > > delay(BIT_DELAY);
> > > IO0PIN = 1 << SHIFT_EN;
> > >
> > > /* lower nibble */
> > > low_nib = data & LCD_DATA_MASK;
> > >
> > > /* After we get the upper nibble, set or clear the respective
> > > registers */
> > >
> > > /* BIT0 */
> > > if(low_nib & BIT0)
> > > IO0PIN = 1 << SHIFT_BIT0;
> > > else
> > > IO0PIN = 1 << SHIFT_BIT0;
> > >
> > > /* BIT1 */
> > > if(low_nib & BIT1)
> > > IO1PIN = 1 << SHIFT_BIT1;
> > > else
> > > IO0PIN = 1 << SHIFT_BIT1;
> > >
> > > /* BIT2 */
> > > if(low_nib & BIT2)
> > > IO1PIN = 1 << SHIFT_BIT2;
> > > else
> > > IO1PIN = 1 << SHIFT_BIT2;
> > >
> > > /* BIT3 */
> > > if(low_nib & BIT3)
> > > IO1PIN = 1 << SHIFT_BIT3;
> > > else
> > > IO1PIN = 1 << SHIFT_BIT3;
> > >
> > > delay(BIT_DELAY);
> > >
> > > /* Enable signal transition, necessary for LCD to detect the signals
> > > */ IO0PIN = 1 << SHIFT_EN; delay(BIT_DELAY); IO0PIN = 1 << SHIFT_EN;
> > }
> > >
> > > void clear_screen(void)
> > > {
> > > command_data(0x01,0);
> > > delay(CLEAR_DELAY);
> > > command_data(0x02,0);
> > > delay(CLEAR_DELAY);
> > > }
> > >
> > > /*void lcd_print(char *name)
> > > {
> > > unsigned int i = 0;
> > > while(name[i]!='\0')
> > > {
> > > command_data(name[i],1);
> > > delay(DATA_DELAY);
> > > }
> > > }*/
> > >
> > > But I cannot even get the LCD initialized forget about printing
> > something.
> > > I would really appreciate any help that would enable to make some
> > progress.
> > >
> > > Sincerely,
> > > Naga.
> > >
> > >
> > >
> >
> >
> >
> >
> >
> >
> >
> >
> >
Hi,

I am trying to write a LCD for LPC2378. Following is the code I wrote:

/********************************/
/* LCD Driver Module for LPC2378*/
/* by Naga */
/********************************/
/*** This LCD accepts data in ***/
/*** groups of four bits ********/

#include"lpc23xx.h"

/******** Declarations **********/

#define BIT0 (1<<0)
#define BIT1 (1<<1)
#define BIT2 (1<<2)
#define BIT3 (1<<3)

#define SHIFT_EN 0 /* Connected to P0.0 */
#define SHIFT_RS 8 /* Connected to P0.8 */
#define SHIFT_BIT0 25 /* Connected to P0.25 */
#define SHIFT_BIT1 18 /* Connected to P1.18 */
#define SHIFT_BIT2 23 /* Connected to P1.23 */
#define SHIFT_BIT3 27 /* Connected to P1.27 */

#define LCD_DATA_MASK (BIT0|BIT1|BIT2|BIT3)

#define POWER_DELAY 100000
#define CLEAR_DELAY 5000
#define BIT_DELAY 2000
const unsigned char lcd_init [5] = {0x33,0x32,0x2C,0x06,0x0C};
char name[] = {'N','A','G','A','\0'};

/****** Function Prototypes *****/

void init(void);
void delay(unsigned int);
void command_data(unsigned char, int);
void clear_screen(void);
void lcd_print(char*);

/******** main ******************/

int main()
{
/* Register to set pins P0.0 and P0.8 as GPIO pins */
PINSEL0 = 0x00;

/* Register to set the pin P0.25 as GPIO pin */
PINSEL1 = 0x00;

/* Register to set pins P1.18, P1.23, P1.27 as GPIO pins */
PINSEL3 = 0x00;

/* Register to set the directions of the pins P0.1, P0.8, P0.25 as outputs*/
IO0DIR = ((1 << 25)|(1 << 8)|(1 << 0));

/* Register to set the directions of pins P1.18, P1.23, P1.27 as outputs */
IO1DIR = ((1 << 27)|(1 << 23)|(1 << 18));

/* Call init function to intialize the lcd */
init();

/* Function to clear the screen */
//clear_screen();

while(1)
{
/* Function to print something on the LCD */
//lcd_print(name);
clear screen();
}
}

void init(void)
{
unsigned int i;

/* After cd is powered up, give it time to PINtle */
delay(POWER_DELAY);

/* Send commands to initalize the lcd */
for(i=0; i<5; i++)
{
command_data(lcd_init[i], 0);
delay(10000);
}

}

void delay(unsigned int delay)
{
unsigned int i, j;
for(i=0; i {
for(j=0;j<40;j++);
}
}

void command_data(unsigned char data, int mask)
{
unsigned char upp_nib, low_nib;

/* upper nibble */
upp_nib = data >> 4;
upp_nib = upp_nib & LCD_DATA_MASK;

/* To enable LCD to distinguish between commands and data */
if(mask)
IO0PIN = 1 << SHIFT_RS;
else
IO0PIN = 1 << SHIFT_RS;
/* After we get the upper nibble, set or clear the respective registers */

/* BIT0 */
if(upp_nib & BIT0)
IO0PIN = 1 << SHIFT_BIT0;
else
IO0PIN = 1 << SHIFT_BIT0;

/* BIT1 */
if(upp_nib & BIT1)
IO1PIN = 1 << SHIFT_BIT1;
else
IO1PIN = 1 << SHIFT_BIT1;

/* BIT2 */
if(upp_nib & BIT2)
IO1PIN = 1 << SHIFT_BIT2;
else
IO1PIN = 1 << SHIFT_BIT2;

/* BIT3 */
if(upp_nib & BIT3)
IO1PIN = 1 << SHIFT_BIT3;
else
IO1PIN = 1 << SHIFT_BIT3;

delay(BIT_DELAY);

/* Enable signal transition, necessary for LCD to detect the signals */

IO0PIN = 1 << SHIFT_EN;
delay(BIT_DELAY);
IO0PIN = 1 << SHIFT_EN;

/* lower nibble */
low_nib = data & LCD_DATA_MASK;

/* After we get the upper nibble, set or clear the respective registers */

/* BIT0 */
if(low_nib & BIT0)
IO0PIN = 1 << SHIFT_BIT0;
else
IO0PIN = 1 << SHIFT_BIT0;

/* BIT1 */
if(low_nib & BIT1)
IO0PIN = 1 << SHIFT_BIT1;
else
IO0PIN = 1 << SHIFT_BIT1;

/* BIT2 */
if(low_nib & BIT2)
IO0PIN = 1 << SHIFT_BIT2;
else
IO0PIN = 1 << SHIFT_BIT2;

/* BIT3 */
if(low_nib & BIT3)
IO0PIN = 1 << SHIFT_BIT3;
else
IO0PIN = 1 << SHIFT_BIT3;

delay(BIT_DELAY);

/* Enable signal transition, necessary for LCD to detect the signals */
IO0PIN = 1 << SHIFT_EN;
delay(BIT_DELAY);
IO0PIN = 1 << SHIFT_EN;
}

void clear_screen(void)
{
command_data(0x01,0);
delay(CLEAR_DELAY);
command_data(0x02,0);
delay(CLEAR_DELAY);
}

/*void lcd_print(char *name)
{
unsigned int i = 0;
while(name[i]!='\0')
{
command_data(name[i],1);
delay(DATA_DELAY);
}
}*/
But so far I haven't been even able to initialize the LCD. I would be grateful if anyone can help me make some progress.

Sincerely,
Naga.

P.S: I will be posting pics of the circuit soon.

I looked over the code and one thing jumps out at me. You use a lot of
IO0PIN =

You do realize that you just set every other bit to zero, right?

A better was to SET a pin is:
IO0SET =

To clear a pin:
IO0CLR =

I don't know if this applies to your code but you might want to think about it. I don't recall ever using IO0PIN
Richard

I was compelled to use IO0PIN register. Let's say we make the following assigments:

IO0SET = 1<<5;
IO0CLR = 1<<5;

Now if I want to set that pin again I cannot just set that bit in IO0SET register. I will have to check if the corresponding bit in IO0CLR is set or not. Reason being that IO0CLR is given more "importance" over IOxSEt (reference table 132). This unnecessarily complicates the code. Hence the use of IOxPIN and I can set the pins to any value instantaneously.

Though I did not get the "You do realize that you just set every other bit to zero, right?" part. What did you mean by that ?

--
Naga.
--- In l..., "rtstofer" wrote:
> I looked over the code and one thing jumps out at me. You use a lot of
> IO0PIN = You do realize that you just set every other bit to zero, right?
>
> A better was to SET a pin is:
> IO0SET = To clear a pin:
> IO0CLR = I don't know if this applies to your code but you might want to think about it. I don't recall ever using IO0PIN >
> Richard
>

--- In l..., "Nagasrinivas" wrote:
>
> I was compelled to use IO0PIN register. Let's say we make the following assigments:
>
> IO0SET = 1<<5;
> IO0CLR = 1<<5;
>
> Now if I want to set that pin again I cannot just set that bit in IO0SET register. I will have to check if the corresponding bit in IO0CLR is set or not. Reason being that IO0CLR is given more "importance" over IOxSEt (reference table 132). This unnecessarily complicates the code. Hence the use of IOxPIN and I can set the pins to any value instantaneously
This is most definitely NOT true. The set and clear registers are just a one shot event. The hardware just sets or clears the bit and that's it. Those set and clear registers retain no state whereas the PIN register does.

I guess I don't see any priority mentioned in Table 132 and it wouldn't make sense to have any. It is only possible for one operation to take place at any one time.

>
> Though I did not get the "You do realize that you just set every other bit to zero, right?" part. What did you mean by that ?
Let's say you want to set a bit (call it EN) and then set another bit (call it WR):

IO0PIN = (1 << EN) // sets the enable bit
IO0PIN = (1 << WR) // sets the write bit but clears the enable bit

When you write to IO0PIN, you are writing the entire 32 bit register and clearing everything that isn't specified as '1' on the right hand side of the = sign.

Richard

some clarification that might help:

in the "old days", controlling an I/O port was typically a task left to the programmer to handle. so, a "port register" (e.g., Io0PIN) was provided that was an "image" of the binary value most recently stored to the port pin drivers. so, if you wanted every other pin HI, you might write something like "PORT1 = 0x55" (examples here all use an 8-bit port for brevity). this meant that if you wanted to set bit 3 of port #1 to HI, you had to say something like "PORT1 |= 0x08". this allows you to set 1 pin while leaving the other 7 pins at their existing state. if you said "PORT1 = 0x08" instead, you would set bit 3 of the port, but clear every other bit, because you were setting the actual port outputs to exactly 0x08. to clear the same single pin, then, you would say "PORT1 &= ~0x08" to mask out bit 3 while leaving the other bits as is. this method had two problems. first, it was inefficient because it required you to do a read-modify-write cycle. second, some architectures had what were essentially "write-only" port registers. that is, if you wrote to PORT1, it would store the bits into a latch feeding the pin drivers, but if you read PORT1, it would read-back the actual pin voltage levels. so, if you wrote a 0x01 to PORT1, and it drove a load so heavy that the voltage level was pulled down to say 0.5 volts, when you read back PORT1, you might get 0x00 instead of 0x01, thus causing read-modify-write operations to fail. this forced you to store a "copy" of your output in RAM somewhere, like "My_Port1 = 0x01; PORT1 = My_Port1; ...(later)... My_Port1 |= 0x08; PORT1 = My_Port1;" yikes!

some architectures responded eventually with "set" and "clear" registers, which indirectly control the "port output" register. in the case of your LPC device, Io0SET and Io0CLR feed into Io0PIN. The former is a "write-only" register that acts like the "set" inputs to an 32-bit flip-flop representing the Io0PIN register, while Io0CLR is a "write-only" register that acts like the "reset" inputs to the same 32-bit flip-flop. so, if you use those registers to set or clear individual pins on the port, you no longer have to keep track of the state of the rest of the pins. any "0" written to the Io0SET or Io0CLR registers has no effect, while any "1" written will either set or clear that single bit in the Io0PIN register. no more read-modify-write inefficiency, and no more worry about whether reading the actual "port output" register is reading back the content of the latch itself (i.e., the last value you wrote) or reading back the actual voltage level of the pin (i.e., as if it represented the actual "inputs" applied to the port pins).

so, the moral is that you should never be "compelled" to use Io0PIN -- Io0SET and Io0CLR are there not to make your life miserable (which they would, if they worked as you described), but to make it easy and carefree. try it yourself in your code: write a 0x55 to Io0PIN, then check the port pin levels. then write 0x08 to Io0SET and measure the pins again: one additional pin should be HI. then read Io0SET itself, and you should see that it does not contain the 0x08 you just wrote there, because this register does not "remember" what you write there -- it simply serves to control the Io0PIN register indirectly.

oh, and be glad you weren't born 50 years ago... :)
--- In l..., "Nagasrinivas" wrote:
>
> I was compelled to use IO0PIN register. Let's say we make the following assigments:
>
> IO0SET = 1<<5;
> IO0CLR = 1<<5;
>
> Now if I want to set that pin again I cannot just set that bit in IO0SET register. I will have to check if the corresponding bit in IO0CLR is set or not. Reason being that IO0CLR is given more "importance" over IOxSEt (reference table 132). This unnecessarily complicates the code. Hence the use of IOxPIN and I can set the pins to any value instantaneously.
>
> Though I did not get the "You do realize that you just set every other bit to zero, right?" part. What did you mean by that ?
>
> --
> Naga.
> --- In l..., "rtstofer" wrote:
> >
> >
> > I looked over the code and one thing jumps out at me. You use a lot of
> > IO0PIN =
> >
> > You do realize that you just set every other bit to zero, right?
> >
> > A better was to SET a pin is:
> > IO0SET =
> >
> > To clear a pin:
> > IO0CLR =
> >
> > I don't know if this applies to your code but you might want to think about it. I don't recall ever using IO0PIN > >
> > Richard
>

On Thu, 2011-10-27 at 00:05 +0000, garycordelli wrote:
> oh, and be glad you weren't born 50 years ago... :)

And ages between 40 and 50, does that count ? ;-)
Just as a little remark apart from the IOxPIN instruction
usage being incorrect is that the following

> if(upp_nib & BIT0)
> IO0PIN = 1 << SHIFT_BIT0;
> else
> IO0PIN = 1 << SHIFT_BIT0;

is essentially the same as the next 1 line

IO0PIN = 1 << SHIFT_BIT0;

That's the same for all the if(){}else{} constructions
in the piece of source code posted by the OP.

roelof