Interface HD44780 compatible LCDs with RCM4010

Introduction

Rabbit Logo

This article is a follow-up refering to the previous description of how to connect a HD44780 compatible LCD display to Rabbit RCM3720. Only small changes are needed for building a similar LCD connection to a RCM4010 development board.

Github Repository

Rabbit RCM4010 LCD example program2

Wiring

Connecting a HD44780 compatible LCD display to a Rabbit 4000 series module is identical to the previous Rabbit 3000 series. All Parallel port A pins and pins 2,3,4 from parallel port B are available and and can be used identical. Therefore, the wiring schema developed for the RCM3720 LCD displaycan be adopted.

Schema

Code

For using our code examples from the RCM3720 setup, we need to make two small adjustments. For the Rabbit 4000 CPU, parallel port B must be now explicitly set for output. Adding: WrPortI(PBDDR, &PBDDRShadow, 0xFF); after setting port A to output brings the desired result for port B.

Compiler

The Rabbit 4000 system comes with a updated version (v10.05) of the Dynamic C compiler. This newer version stopped recognising our brdInit(); function call due to the missing return parameter declaration being "void". A simple addition of "void" before the function call fixes the issue. The new compiler version now automatically searches through the standard library path. After placing our hd44780lcd.lib in it, we no longer need to update the lib.dir library list manually. That list is now only necessary if we want to add library files that are not in the standard library directory.

Creating custom characters with the HD47780 LCD

Rabbit RCM4010 LCD example program8

The HD44780 series has space for 8 custom-defined characters in addition to its internal character ROM. These characters can be freely defined, allowing to generate pseudo-graphic effects.

Defining the Shape

The shape can be defined by creating a "string" of 8 bytes. Each byte defines one line of the 8 lines available for the character definition font size. The normal font size is 8 lines of 5 dots (8x5). The library function LcdDefCustomChar() takes care of placing the data at the correct memory locaton. The code of example 8 below shows how simple it is to define your own custom character.

Display the Character

Simply by addressing the characters from the LCD character map begining at address 0x00 provides access to our eight self-defined custom characters. The library function LcdPutCustomChar() retrieves the custom character 0-7 from the LCD RAM and places it on the specified line and column.

Example Code

/***************************************************************************/
/* RABBIT_RCM4010_TO_HD44780LCD_EXAMPLE8.C   http://fpga.fm4dd.com/        */
/*                                                                         */
/* Written for HD44780-compatible LCD displays connected to Rabbit 3000    */
/* and 4000 Modules. This example demonstrates how to load and display     */
/* custom defined characters on the LCD. Written and tested under Dynamic  */
/* C Version 10.05. DISPLAYSIZE and DISPLAYLINES unset, defaults to 16x2.  */
/* Code examples and details are described in Rabbit`s document TN211.     */
/*                                                                         */
/*                                                       Frank4dd, @2009   */
/***************************************************************************/
#use hd44780lcd.lib
#define INTERFACE 8
#define DISPLAYSIZE 16
#define DISPLAYLINES 2
/* define custom character bitmaps */
const char custom_xbox[8] = {
  0x00,     //.....
  0x1F,     //#####
  0x1B,     //##.##
  0x15,     //#.#.#
  0x1B,     //##.##
  0x1F,     //#####
  0x00,     //.....
  0x00      //.....
};
const char custom_plug[8] = {
  0x0A,     //.#.#.
  0x0A,     //.#.#.
  0x1F,     //#####
  0x11,     //#...#
  0x11,     //#...#
  0x0E,     //.###.
  0x04,     //..#..
  0x04      //..#..
};
const char custom_battery[8] = {
  0x0E,     //.###.
  0x1F,     //#####
  0x11,     //#...#
  0x11,     //#...#
  0x1F,     //#####
  0x1F,     //#####
  0x1F,     //#####
  0x1F      //#####
};
const char custom_w_circle[8] = {
  0x00,     //.....
  0x0E,     //.###.
  0x11,     //#...#
  0x11,     //#...#
  0x11,     //#...#
  0x0E,     //.###.
  0x00,     //.....
  0x00      //.....
};
const char custom_b_circle[8] = {
  0x00,     //.....
  0x0E,     //.###.
  0x1F,     //#####
  0x1F,     //#####
  0x1F,     //#####
  0x0E,     //.###.
  0x00,     //.....
  0x00      //.....
};
const char custom_smiley[8] = {
  0x00,     //.....
  0x0A,     //.#.#.
  0x00,     //.....
  0x04,     //..#..
  0x11,     //#...#
  0x0E,     //.###.
  0x00,     //.....
  0x00      //.....
};
const char custom_frowny[8] = {
  0x00,     //.....
  0x0A,     //.#.#.
  0x00,     //.....
  0x04,     //..#..
  0x00,     //.....
  0x0E,     //.###.
  0x11,     //#...#
  0x00      //.....
};
const char custom_heart[8] = {
  0x00,     //.....
  0x00,     //.....
  0x0A,     //.#.#.
  0x1F,     //#####
  0x0E,     //.###.
  0x04,     //..#..
  0x00,     //.....
  0x00      //.....
};
void main() {
  void brdInit();                            // Enable development board
  SetPortAOut();                             // Set port A as output port
  WrPortI(PBDDR, &PBDDRShadow, 0xFF);        // Set port B to output

  Lcd_Config();

  LcdDefCustomChar(0, custom_xbox);
  LcdDefCustomChar(1, custom_plug);
  LcdDefCustomChar(2, custom_battery);
  LcdDefCustomChar(3, custom_w_circle);
  LcdDefCustomChar(4, custom_b_circle);
  LcdDefCustomChar(5, custom_smiley);
  LcdDefCustomChar(6, custom_frowny);
  LcdDefCustomChar(7, custom_heart);

  LcdWriteStr(1,"Custom Character");
  pause(2);

  /* place our custom chars on the second line */
  /* with a space in between                   */
  LcdPutCustomChar(0, 2, 1);
  LcdPutCustomChar(1, 2, 3);
  LcdPutCustomChar(2, 2, 5);
  LcdPutCustomChar(3, 2, 7);
  LcdPutCustomChar(4, 2, 9);
  LcdPutCustomChar(5, 2, 11);
  LcdPutCustomChar(6, 2, 13);
  LcdPutCustomChar(7, 2, 15);
  pause(30);

  LcdLineClear(1);
  LcdWriteStr(1,"1234567890123456");
  pause(15);
  Lcd_Off();
}

Running the library on both Rabbit 3000 and Rabbit 4000 modules

Rabbit RCM3720 LCD example program8

The picture shows it, I am running the example8 testprogram unchanged on a Rabbit RCM3720 development kit. Unfortunately the newer Dynamic C compiler version 10.05 coming with the RCM4010 module is not backward compatible and does not compile code for the older RCM3720 system. Therefore I have the 2 compilers (Dynamic C 9.21 and 10.05) parallel installed on my system and I placed the HD44780 library into both compilers.

Support for 20x4 LCD Displays

The HD44780LCD.LIB library has also been updated to support 20x4 displays. I tested it successfully with a Optrex NFQJ-LG-ACN module. The library defaults to a 16x2 display size, but simply by defining DISPLAYSIZE 20 and DISPLAYLINES 4 on top of the program, it can easily handle the larger LCD.

Credits, copyrights, links and software

LGPL

I make the HD44780 LCD library available under the terms of the LGPL.

Reference