LCD: Interfacing with PIC Microcontrollers Part 2
By SC Lim
RH2T Mag, Volume 5, Jun 2010
In previous issue, we discussed the general hardware structure, control pins, hardware connection, RAM and registers, and finally the instruction sets of the standard LCD module. Now let’s practice what we’ve learnt!
In this part, we will see the initialization with some of the coding examples in C using Microchip MPLAB IDE and HI-TECH C PRO compiler for the PIC10/12/16 MCU Family. These software are free of charge and the latest releases can be obtained from both Microchip and HI-TECH websites.
Before using the LCD for display purpose, LCD has to be initialized either by the internal reset circuit or sending set of commands to the LCD. User has to decide whether an LCD has to be initialized by instructions or by internal reset circuit. We will discuss both types of initialization here.
Initialization by Internal Reset Circuit
An internal reset circuit automatically initializes the HD44780U when the power is turned on. The Busy Flag (BF) is kept in the busy state until the initialization ends (BF = 1). The busy state lasts for 10ms after VCC rises to 4.5V. The following instructions are executed during the initialization.
- Display clear
- Function set:
DL = 1; 8-bit interface data
N = 0; 1-line display
F = 0; 5 x 8 dot character font
- Display on/off control:
D = 0; Display off
C = 0; Cursor off
B = 0; Blinking off
- Entry mode set:
I/D = 1; Increment by 1
S = 0; No shift
There are certain conditions that have to be met, if user wants to use initialization by internal reset circuit. These conditions are shown in the table below.
Power supply conditions using internal reset circuit
Figure below shows the test conditions which are to be met for internal reset circuit to be active.
The problem with internal reset circuit is that it is highly dependent on power supply. It is not hard to meet this critical power supply conditions but it is often difficult to achieve when simple application are involved. Hence, usually the second method, initialization by instruction is used and is recommended most of the time.
If the electrical characteristics conditions listed under the table Power Supply Conditions using Internal Reset Circuit are not met, the internal reset circuit will not operate normally and will fail to initialize the HD44780U. For such a case, initialization must be performed by the MCU as explained in the next section, Initializing by Instruction.
Initialization by Instructions
Initializing LCD with instructions is relatively simple. Given below is a flowchart that describes the step to follow to initialize the LCD.
The first 3 commands are usually not required but are recommended when you are using 4-bit interface. So actually you can program the LCD starting from sending function set when working with 8-bit interface. Function set command depends on what kind of LCD you are using and what kind of interface you are using (refer to the table in LCD Command section).
For PIC16F877A, the typical configuration settings and the declaration of LCD pins are shown in the figure below.
A typical configuration settings and declaration of LCD pins for PIC16F877A
LCD Entry Mode
From Commands and Instructions set for LCD type HD44780 table attached at the end of this article, you can see that there are two bits which determine the entry mode for LCD:
a) I/D – Increment/Decrement bit
b) S – Display shift.
Since bit 2 is always set, we get four combinations of entry mode which are 0x04 (1002), 0x05 (1012), 0x06 (1102) and 0x07 (1112). So we get different results with these different entry modes. Normally entry mode 0x06 is used, which is no shift and automatic increment. Do try all the possible entry modes and see the results, I am sure you will be surprised.
Programming example for LCD Initialization in C Language
With the help of the above code, you are able to initialize the LCD. The sample code contains a function/subroutine – LCD_busy. This subroutine is used to call for delay so that there should not be any command or data sent to the LCD until it finishes executing the command. More on this delay routine is explained in the next section.
Checking the Busy Flag
As discussed in the previous section, there must be some delay which is needed to be there for LCD to successfully process the command or data. So this delay can be made either with a delay loop of specified time more than that of LCD process time or we can read the busy flag, which is recommended. The reason to use busy flag is that delay produced is almost the amount of time for which LCD need to process. So, it is best suited for every application.
Steps to Read Busy Flag
When we send the command, the BF or DB7 bit of the LCD becomes 1 and as soon as the command is processed the BF = 0. Following are the steps to be kept in mind while reading the Busy flag.
- Select command register
- Select read operation
- Send enable signal
- Read the flag
- So following the above steps we can write the code in C as below…
LCD Busy Flag routine in C Language
If you do not want to read the busy flag you can simply use delay routines to provide the specific amount of delays. You have to make sure the delays are reasonable by referring to Commands and Instructions set for LCD type HD44780 table. The example code can be obtained at Cytron’s SK40C (Enhanced 40 pins PIC Start-up Kit) product page. Busy flag cannot be checked when you are using SK40C because the R/W (Read/Write) pin of LCD is connected to Ground permanently. So read command is unable to be executed and delay routines must be used for the LCD functions. The main reason to have such design is to reserve more PIC I/O pins for other applications.
It is often important to initialize the function or uses function prototypes at the beginning of the program (please refer to source code provided here: www.robothead2toe.com.my)
Now that we are ready with the initialization routine and the busy routine for LCD, we’ll move on to the next section on how to send data and command to the LCD.
Sending Commands to LCD
In order to send commands we simply need to select the command register. Everything is same as we have done in the initialization routine. But we will summarize the common steps and put them in a single subroutine. Following are the steps:
- move data to LCD port
- select command register
- select write operation
- send enable signal
- wait for LCD to process the command
Keeping these steps in mind we can write LCD command routine as:
Routine for LCD send command in C language
Setting Cursor Position on LCD
To set the cursor position on LCD, we need to send the DDRAM address.
The seventh bit is always 1, and bits 0 to 6 are DDRAM address (refer the LCD Commands and Instruction Set section). So if you want to put the cursor on first position the address will be ‘0000000’ in binary and 7th bit is 1. The address will be 100000002 or 0x80, so for DDRAM all address starts from 0x80.
For 2 lines and 16 characters LCD. The address from 0x80 to 0x8F are visible on first line and 0xC0 to 0xCF is visible on second line, the rest of the DDRAM area is still available but is not visible on the LCD, if you want to check this thing, then simply put a long sting greater than 16 character and shift the entire display, you will see all the missing character coming from the back. By this way you can create scrolling line on LCD (see more on shifting display in commands section).
Below is an example for setting cursor position on LCD:
An example for setting cursor at first line, 4th position
Sending Data to LCD
In order to send data we simply need to select the data register. Everything is same as the command routine. Following are the steps:
·move data to LCD port
·select data register
·select write operation
·send enable signal
·wait for LCD to process the data
LCD send data routine in C language
You have seen that it’s really easy to send command and data to LCD. What if we have a string to send to LCD? It’s simple. We will store the LCD string in the ROM of the PIC microcontroller and call the string character by character. A simple example is shown below.
LCD send string routine in C language
If you have been following this article until this stage, you should be able to configure and display characters on your LCD module using a PIC microcontroller. Have fun! The full sample source code can be obtained from Robot. Head to Toe website (www.robothead2toe.com.my). Please follow us in the next issue for more explanation on the advanced features of the LCD, such as creating custom characters and 4-bit data bus interfacing.
1. Hitachi HD66710 Datasheet