Parallel LCD with coyote-2500

Hi guys, I’m new when using rabbit’s products. I need to use a standard parallel 16x2 LCD. Although I’ve written a library for such a task for others CPUs (freescale, msp, avr) and they are working great, I’ve felt when trying with the coyote’s board, and I haven’t found any code for controlling a lcd in such a board. Can you help me with this duty?? or if you know a place where I can get the code, please tell me. The hardware is like this:

Output 00 lcd-b4
Output 01 lcd-b5
Output 02 lcd-b6
Output 03 lcd-b7
Output 04 lcd-rs
Output 05 lcd-e

Each pin is working as it should (tested individually when debuging my code). I’ve tried any kind of delay for the initializing code unsuccesfully :frowning: .

If you have any idea please let me know. Thanks in advanced :slight_smile:

It’s me again

I found an example code (LCD2.C) for the BL-1800 jack rabbit board in

http://www.rabbitsemiconductor.com/support/downloads/downloads_prod.shtml

and I made some changes of my own to fit my board (coyote-2500)

Now at least characteres show up in the LCD, but they are meaningless, eg., if a I send an ‘a’ it prints ‘F’, if I send ’ ’ (space) it prints “||” and so on. And when sending control characteres (blank lcd, return home, etc), it seems to lost its way.

I’ve tried some configs and delays, but none of them make it works as it must.

Here it is the adapted code. Pinout is the same as above. Thanks in advanced

void fn4Clear(void);

/*********************************************************************
fnMsDelay - delay some number of milliseconds
input parameter: int number of milliseconds to delay
return value: none
errors: none
*/
void fnMsDelay ( int iDelay )
{ unsigned long ul0;
ul0 = MS_TIMER; // get current timer value
while ( MS_TIMER < ul0 + (unsigned long) iDelay );
}

/*********************************************************************
fnUsDelay - delay some number of micro seconds - very approximate!!
about 11usec per iteration with the 7.3MHz crystal. The formula
used here was determined experimentally.
*/
void fnUsDelay ( int iDelay )
{ int i;
iDelay /= 11;
for ( i=0; i>= 4; // put upper nibble into lower 4 bits
fn4OneNib ( cNib ); // send upper nibble
fn4OneNib ( i ); // send lower nibble
fnUsDelay (100);
}

/*********************************************************************
fn4LCD_Init - Initialize the LCD for the following operating parameters:
4 bit mode, 2 lines, 5x10
turn on display and cursor: non-blinking
incr address and shift cursor with each character
*/
void fn4LCD_Init ()
{

iDataFlag = COMMAND;				// show command mode
fnMsDelay ( 500 );				// wait for LCD to reset itself

fn4OneNib ( 3 );					// 8 bit mode
fnMsDelay ( 10 );

fn4OneNib ( 3 );					// 8 bit mode
fnMsDelay ( 2 );

fn4OneNib ( 3 );					// 8 bit mode
fnMsDelay ( 2 );

fn4OneNib ( 2 );					// 4 bit mode

fnMsDelay (2);

fn4Byte ( 0x28 ); fnMsDelay ( 1 );
fn4Byte ( 0x0e ); fnMsDelay ( 1 );
fn4Byte ( 0x01 ); fnMsDelay ( 3 );
fn4Byte ( 0x42 ); fnMsDelay ( 1 );

/*
fn4Byte ( 0x2c ); fnMsDelay ( 1 );

fn4Byte ( 0x0e ); fnMsDelay ( 1 );

fn4Byte ( 0x01 ); fnMsDelay ( 3 );

fn4Byte ( 0x06 ); fnMsDelay ( 1 );

fn4Byte ( '\B00000010' ); fnMsDelay ( 3 );

*/

//fn4Byte ( '\B00000110' );		// incr address and shift cursor with each character

}

/*********************************************************************
fn4Display - display a line of text on the LCD
argument: address of null terminated text string
*/
void fn4Display ( char *szp )
{
char c;

//printf("%s

",szp);

iDataFlag = DATA;					// next bytes are data
while ( *szp ){
	c=*(szp++);
	fn4Byte ( c );
	fnMsDelay (3);
}

}

void fn4Clear ( void )
{ iDataFlag = COMMAND; // set up for command
fn4Byte ( 0x01 ); // clear the display
fnMsDelay (3); // insure at least 2 msec
}

void fn4Line2 ( void )
{ iDataFlag = COMMAND; // set up for command
//fn4Byte ( 0xC0 ); // set RAM address to Line 2
//note: this value may vary for different displays

fn4Byte ( 0x40 );


fnMsDelay (3);						// insure at least 2 msec

}

const char cad[]=“abzdefghijklmnop”;

void main ()
{

brdInit();

fn4LCD_Init ();

while (1)
{
	fn4Clear();
	fn4Byte ( 0x02 ); fnMsDelay ( 3 );
	//fn4Display ( "0123456789" );
	fn4Display ( cad );
	//fnMsDelay (500);
	//fn4Clear();
	fn4Byte ( 0x02 ); fnMsDelay ( 3 );
	fn4Display ( "abcd" );
	fnMsDelay (500);
}

}

Hi, thanks to all of you that read the post (altough nobody answers =) )

I finally made the LCD to work!! I don’t understand how rabbit hadles the ports (what the manual says is different of that seen in the board), and I don’t want to know, hopefully this is the first and last time I use rabbit’s boards, but for those that may face the same problem here it is what I did.

The code and hardware is the same as above, however, the function “void fn4OneNib ( char cNib )” should be changed (actually is the same code, but in different order) for this one:

void fn4OneNib ( char cNib )
{
cNib &= 0x0F;upper 4 bits

digBankOut(0,cNib);


if(iDataFlag==0)
	digOut(4,0);
else
    digOut(4,1);

digOut(5,1);
fnUsDelay (50);
digOut(5,0);

fnUsDelay (100);

}

The trick was to change the position of the instruction

digBankOut(0,cNib);

to the beggining of the body of the funtion, 'cause in the original code whenever that instruction executes it changes the state of RS and E control bits (output 4 and 5, accordingly my hardware, see the first post)), so it send neither command nor control commands, but garbage.

Also I made a little changed in the function “void fnUsDelay ( int iDelay )” :

void fnUsDelay ( int iDelay )
{ int i;
//iDelay /= 11; // original for the jack rabbit (7.5MHz crystal)
iDelay /= 50; // this is for the coyote (30 MHZ crystal, I guess so)
for ( i=0; i

Hi guys, this is the complete code that works with the coyote-2500 in 4-bit config (this is for a 20x4 LCD, but it should work strightforward with the standard 16x2 LCD), plus the “gotoxy()” function that I added. I hope it may help someone else.

---------------------------code------------------

const char lcdRAMAddr[]={0,0x40,0x14,0x54};

void fn4Clear(void);

/********************************************************************/
void fnMsDelay ( int iDelay )
{ unsigned long ul0;
ul0 = MS_TIMER;
while ( MS_TIMER < ul0 + (unsigned long) iDelay );
}

/********************************************************************/
void fnUsDelay ( int iDelay )
{ int i;
//iDelay /= 11;
iDelay /= 50;
for ( i=0; i>= 4;
fn4OneNib ( cNib );
fn4OneNib ( i );
fnUsDelay (100);
}

/*********************************************************************/
void fn4LCD_Init ()
{

iDataFlag = COMMAND;
fnMsDelay ( 500 );

fn4OneNib ( 3 );					// 8 bit mode
fnMsDelay ( 10 );

fn4OneNib ( 3 );					// 8 bit mode
fnMsDelay ( 2 );

fn4OneNib ( 3 );					// 8 bit mode
fnMsDelay ( 2 );

fn4OneNib ( 2 );					// 4 bit mode

fnMsDelay (2);

fn4Byte ( 0x28 ); fnMsDelay ( 1 );
fn4Byte ( 0x0e ); fnMsDelay ( 1 );
fn4Byte ( 0x01 ); fnMsDelay ( 3 );
fn4Byte ( 0x42 ); fnMsDelay ( 1 );

}

/*********************************************************************/
void fn4Display ( char *szp )
{
char c;

iDataFlag = DATA;
while ( *szp ){
	c=*(szp++);
	fn4Byte ( c );
	fnMsDelay (3);
}

}
/*********************************************************************/
void fn4Clear ( void )
{ iDataFlag = COMMAND;
fn4Byte ( 0x01 );
fnMsDelay (3);
}

/*********************************************************************/
void fn4Line2 ( void )
{ iDataFlag = COMMAND;
fn4Byte ( 0x40|0x80 );
fnMsDelay (3);
}

/*********************************************************************/
void gotoxy(char x, char y)
{
char a;

a=lcdRAMAddr[y];

iDataFlag = COMMAND;
fn4Byte ( (a+x)|0x80 );
fnMsDelay (3);

}

const char cad[]=“defghijklmnopqrst”;
/*********************************************************************/
void main ()
{

brdInit();

fn4LCD_Init ();

while (1)
{
	fn4Clear();


	fn4Display ( cad );

	gotoxy(0,1);


	fn4Display ( cad );

	gotoxy(0,2);
	fn4Display ( "efgh" );

	gotoxy(10,3);
	fn4Display ( "ijkl" );

	fnMsDelay (500);
}

}