9
USING LIQUID CRYSTAL DISPLAYS: AN EXTENDED INFORMATION RESOURCE

General

The use of LCD (liquid crystal display) modules is covered in great detail in this chapter because they form an important part of any project based on the use of the PIC line of microprocessors and the PROBASIC PRO compilers. We will consider the popular 2-line-by-16-character display in detail, but the information is applicable to most LCDs on the market today.

The PICBASIC PRO Compiler offers full support for the 2-line-by-20-character display provided on the LAB-X1 board, as well as for other similar displays controlled by the Hitachi HD44780U and compatible controllers. Before a display can be used, it is necessary to tell the compiler where the display is located in memory. This is done by setting the value of a number of DEFINEs that have been named and predefined in the compiler. These DEFINEs let you write to any LCD at any memory location in your project with the compiler (assuming there are no wiring conflicts). The specific DEFINEs related to the control of the LAB-X1 display are as follows:

The DEFINEs described next are for an LCD controlled from PORTD and PORTE, as is the case for the LAB-X1.

Identify the port connected to the LCD data pins:

 DEFINE         LCD_DREG        PORTD

Decide how many bits of data to use, along with the starting bit. This can be a 0 or a 4 for the data starting bit, and 4 or 8 for the number of bits used:

 DEFINE         LCD_DBIT        0       (or 4)
 DEFINE         LCD_BITS        4       (or 8)

Specify the register that will contain the register selection bit, and the number of the bit that will be used to select the register:

 DEFINE         LCD_RSREG       PORTE
 DEFINE         LCD_RSBIT       0

When we transfer the data, we must enable the transfer by toggling a bit, and the port and bit for doing this are defined with the following two lines:

 DEFINE          LCD_EREG        PORTE
 DEFINE         LCD_EBIT        1

Decide whether we are going to read data from, or write data to, the LCD. This is the read/write bit, and this bit is defined with the following two lines:

 DEFINE         LCD_RWREG       PORTE
 DEFINE         LCD_RWBIT       2

Most of the time we do not need to read data from the LCD, so this bit can be made and left low:

 LOW PORTE.2

Set LCD R/W pin to low (if write-only is to be implemented). If we are not ever going to read from the LCD module, the preceding bit can be set and left low, or it can be tied low with hardware. (Doing it this way will save one control line on the PIC.)

Since the PIC 16F877A has analog capability, like any other similar PIC it will come up in analog mode on startup and reset. The MCU must be changed to digital mode by setting the appropriate A-to-D control register bits before we can use the digital capabilities of the PIC. We need the digital functions of PORTE to control the LCD. This is done with . ..

 ADCON1 = %00000110

This instruction makes all of PORTA and PORTE digital (%00000111 can also be used). Other specifications will provide different results. For a detailed discussion of this, see the datasheet section on A-to-D conversions.

The LCD takes a considerable time to initialize itself after startup, so we have to wait about 500 milliseconds before writing to it. If there are a lot of other tasks that will take place before the first write to the LCD, this time can be reduced. (A trial-and-error approach can be used to determine the minimum time needed.)

 PAUSE 500   ; Wait .5 secs. for LCD to start up

Usually, the first command to the LCD is used to clear the display and write to it on line 1, but I am showing it as two lines, where the first line clears the display and the second line positions the cursor at the first position on the first line and prints the word “Blank.”

 LCDOUT $FE, 1                 ; Clear the LCD
 LCDOUT $FE, $80, “Blank”      ; written to the 1st line 1st position
                               ; of the LCD

All commands (as opposed to characters) sent to the LCD are preceded by the code $FE or decimal 254. Some of the codes are as described in Table 9.1.

TABLE 9.1 LCD CODE LISTINGS

$FE,

$01

Clear Display. (An uncleared display shows dark rectangles in all the spaces, which may appear blotchy and irregular).

$FE,

$02

Go to home. Position one on line one.

$FE,

$0C

All cursors OFF. This is the default condition on startup.

$FE,

$0E

Underline Cursor ON

$FE,

$0F

Underline Cursor OFF. This is the default condition on startup.

$FE,

$10

Mover cursor right one position.

$FE,

$14

Mover cursor left one position.

$FE,

$80

Move cursor to position one of line one.

$FE,

$C0

Move cursor to position one of line two.

$FE,

$94

Move cursor to position one of line three.

$FE,

$D4

Move cursor to position one of line four.

All these and other codes are described in detail in the Hitachi datasheet (see Table 9.1). You must learn where these are located so you can refer to them when necessary.

These commands apply to all LCDs using the Hitachi HD44780U controller or its equivalent. See the datasheet for this controller for more detailed information. This controller has many commands not shown here, including limited graphic capability (within the characters) and the ability to display Japanese kana characters.

It is useful to have the full 40+ page datasheet on hand whenever doing anything more than sending text to the LCD. The Hitachi 44780 datasheet can be downloaded at no charge from the following Web site:

square www.alldatasheet.com/datasheet-pdf/pdf/63673/HITACHI/HD44780.html

LCD displays require that each line be addressed with its own starting position as indicated earlier. The exception is that most 16-character single-line displays are designed such that the first eight characters start at $80, and the next eight start at $C0, so that the 16 characters appear to be on two lines to the controller though they are displayed as one line on the LCD module. Also note that lines 3 and 4 of four-line displays also have an irregular addressing scheme.

If more characters than can be displayed on a line are sent to the LCD, they will be stored in the memory in the LCD and can be scrolled across the screen when needed. The number of characters that an LCD can store in its display memory is a property of

f0142-01

Figure 9.1 A 2-line-by-16 character LCD module. (One- or two-line LCDs can add a tremendous amount of utility to a project.)

the LCD as determined by the manufacturer. You can also scroll the display up and down if you design the commands, and write the software, to do so. This is not built into the LCD or the controller software. A typical 16 × 2 display is shown in Figure 9.1

Using LCDs in Your Projects

It is generally agreed that most projects benefit from having a one- or two-line display incorporated in them. However, these displays tend to be rather pricey (about $50) when provided with the necessary controlling IC, and quite reasonable (about $5 to $6) when bought without the supporting package. Since a PIC microcontroller can be purchased for about $5, we should be able to have a complete display unit for a marginal cost of around $10 if we can figure out how to program our PIC microcontroller to control the display.

The readily available and inexpensive 2-line-by-16-character LCD ($6 at All Electronics) offers us the ability to display information in a limited but useful way in our projects. Mastering the use of this LCD display means we have gained the expertise to write any character, at any location, at any time, or in response to any event, whenever we want. This chapter addresses this problem in detail and tells you what you need to know and do to make these displays inexpensive additions to all of your projects.

In this chapter, you will learn how to control an LCD. The code you create will be able to be incorporated into almost any PICBASIC PRO program and will control the LCD from any available half port (nibble) and three other free I/O lines. The code will be more linear than it needs to be so you can see exactly what is going on, but once you understand what needs to be done, you can write more compact and sophisticated code that will get the job done the way you want.

Understanding the Hardware and Software Interaction

The hardware we are considering consists of an LCD with an integral controller that is incorporated in the display by the display manufacturer. In our particular case, this is the Hitachi HD44780U controller. Displays are available without this or any other controller, but controlling displays without a controller is way beyond the scope of this book. For our projects, be sure you buy only those units that have this controller built in as a part of the display. Most do.

Controlling the display consists of telling this controller what we want it to do. The instructions are easy to learn and allow you to control each and every pixel and all the functions that the display can perform, with relative ease. You do not have to read or understand the rather extensive 40+ page datasheet that Hitachi provides for this controller, but it is well worth the trouble to download the data sheet and study it. You do not need to download this file either, but you should know where to find it if you need it. We will go over almost everything you need to know to control the display as a part of this exercise. The exercises at the end of the chapter will take it to the next level.

In the LCD display, the imbedded controller provides the interface between the user and the display. The controller is the Hitachi HD44780U. This very powerful controller gives you complete control over the LCD. It allows you to address each and every pixel on the display. It also has a built-in set of ASCII characters for use by the user. Our task is to learn how to use this controller to put what we want, when we want, where we want, in the display.

The other common controller is the Epson SED series controller, whose operation and instruction set is very similar to that of the Hitachi controller. We will not consider the EPSON controller in this book If you do decide to buy a display with this controller to save a few bucks, you should be able to use it after only a small amount of study.

You will find that almost all the smaller liquid crystal displays on the market are controlled by the Hitachi controller mentioned earlier. This means that once you learn to control one display, you can control most of them with the code you create. As a matter of fact, we will write the code in a way that will be universal in its application in that we will define variables like the number of character spaces in the display and the number of lines in the display as part of the program setup. (It is also useful and usually much easier to use the DEFINEs created by the PBP compiler to control the display. We will learn how to do this in a later exercise.)

The addresses of the local memory locations (meaning the ones in the LCD) used by the LCD have already been fixed, as has the instruction set we use to write to the LCD, so we do not have to create any of this rather sophisticated code.

You do not need the full datasheet, which is about 40 pages long, but you do need to know the basic command set that controls the data transfer to your particular display. This is usually provided by the organization you buy the LCD from and consists of two or three pages. You will need to refer to the datasheet only if you want to create special characters, or if you want to display bargraphs and the like on the display. The control the Hitachi controller provides is very comprehensive, but you don’t need to be familiar with it to use a display effectively. Everything you need to know will be covered in this exercise, but that should not keep you from learning as much as you can about controlling the displays.

Talking to the LCD

The preceding control codes allow you to configure the display, set display parameters, set the shape and position of the cursor, and so on. To differentiate them from the character commands, each control code must be preceded by a hexadecimal FE or a decimal 254 to tell the controller that the next character sent to the display will be a control code. After receiving one control code and its argument, the Hitachi controller resets to the data mode automatically.

The controller supports the ASCII standard. All uppercase and lowercase characters and numerals are supported, as are punctuation marks and the standard text support characters. (The controller also supports the display of a set of Japanese kana characters.)

It is also possible to design your own font for use with the displays (though five by seven [or even ten] dots and two lines does limit what can be done). All the information needed to do so is contained in the Hitachi HD44780U datasheets. Greek characters and certain scientific notations would be useful for most scientific applications.

The Hardware

Let’s take a closer look at the LCD hardware.

Study the datasheet that came with the LCD. Find the pin-out descriptions and study them. The 16 pins are usually identified as shown in Table 9.2.

Looking at the datasheet provided with the 2-line-by-16-character displays, we find that the control implementation can take place if we have both a port and a few lines available to control the LCD. It does not have to be controlled from any predefined lines. We can select all the lines needed to support the display in our project and they can be on any port we have available. The only requirement seems to be that the four/eight data line be either the contiguous top, or the bottom half, of a port. This is not a particularly demanding requirement other than that it means the smaller PICs cannot be used if we will require many I/O lines in our project. The other three lines needed can be on any of the other ports, and do not all need to be on the same port. Since we are considering

TABLE 9.2 LCD CODE LISTING PIN-OUT IDENTIFICATION OF THE LCD PINS FROM THE DATASHEET

PIN NO.

SYMBOL

 

1

VSS

Logic ground

2

VDD

Logic power 5 volts

3

VO

Contrast of the display, can usually be grounded.

4

RS

Register select ) These are

5

R/W

Read/Write     ) the 3 control

6

E

Enable            ) lines

7

DB0

)

8

DB1

)

9

DB2

) This is

10

DB3

) one port or

11

DB4

) 8 lines          ) half of the port

12

DB5

) of data         ) can also

13

DB6

)                    ) be used

14

DB7

)                    ) see PBP manual

15

BL

Backlight power     )These two lines can

16

BL

Backlight ground     )usually be ignored

only one PIC in this book, in our case this means we will use the 16F877A. I have included the circuitry and code for this in the Program 9.1 and Figure 9.1 so you can see exactly what needs to be done.

To keep it simple, let’s use PORTA and PORTB, because these ports are available on even the smaller MCUs, and if we use a dedicated MCU to control our LCD, it will in all probability be a smaller more inexpensive 18- or 20-pin MCU. Let’s use the lines as follows:

Lines 1 to 3 of PORTA as the control lines and

Lines 0 to 7 of PORTB as the data lines

We can redefine these to be more rational addresses whenever we want, and none of the programming will have to change. Just DEFINE what ports and lines you want to use at the top of the program, and the aliases assigned to them will identify them as needed.

With this in mind, let’s create the software to control a 2-line-by-16-character display. Once we are happy with what we have created, we can migrate the code to other microcontrollers.

Note We could also use a one-line (about $5) display, but that would inhibit learning about going to line 2, scrolling the display up and down, and so forth. To experiment with these features, we need to have a display with at least two lines.

Setting Out Our Design Intent

square Control the 16 × 2 display with a PIC 16F877A microcontroller (the code for the smaller MCUs will be the same).

square Design the software so it can be an integral part of the software for any project.

square Use standard control codes so the project is a virtual plug-in replacement for other displays and in other PICs. (Only minor modifications if any will be required.)

square Use a minimum number of external components, allowing this software project to move between PIC controllers of all descriptions. All we want to do is include the code in our project and connect the display to the selected ports.

square Use the project’s regulated 5-volt power supply for everything.

Note The PIC 16F877A has 33 I/O lines, the display will use 7 of them, so we will have 26 lines left over for our project. Since we don’t need all these lines, we could have used the 16F84A. No program changes should be needed, other than changing the line and port addresses in the DEFINES, when we move to the PIC 16F84A.

HARDWARE NEEDED

We will need the following parts for this project:

square Experimental solderless breadboard

square PIC microcontroller: 16F877A or 16F84A

square One bare 2-line-by-16 character display module (with a Hitachi controller)

square One 4 MHz crystal

square Two 22 pf capacitors

square Regulated 5-volt power supply from the breadboard

square One 470-ohm 0.25-watt resistor

square Some 22-gauge insulated single-strand hookup wire

square 1-kohm 0.12-watt pull-up resistor

PROGRAMMER NEEDED

The programmer needed should be either the microEngineering serial programmer, a parallel programmer, or the new USB programmer.

SOFTWARE NEEDED

The software needed includes the PICBASIC PRO Compiler and its manual.

INFORMATION NEEDED

Information needed includes:

square LCD datasheets that came with the LCD

square The PIC 16F877A datasheet (or the datasheet for the 16F84)

We will go through the software a step at a time, and when done, it will be your job to clean up the software and speed up its operation—for example, to optimize it for the microcontroller you will use in your project(s).

We must pick a specific display to work with so we can develop real working software for it. The display I picked sells for $6 or so and is available with a datasheet from All Electronics. AZ Displays also sells one that seems to be identical—called Model ACM 1602K. The short form datasheets are similar, but the AZ one is in a crisp PDF format and can be downloaded from their Web site for free. Doing so will mean you can have this information open in a window on your computer.

First, we need to investigate how many pins we will need on our PIC microcontroller to interact with our display. This is summarized in Table 9.3.

TABLE 9.3 LCD PIN OUTS (PIN OUT IDENTIFICATION OF THE LCD PINS FROM THE DATASHEET)

PIN NO.

SYMBOL

LEVEL

DESCRIPTION AND NOTES

1

VSS

0V

Ground for logic supply

2

VDD

5.0V

Logic power supply, regulated

3

VO

—-

LCD contrast. Can be grounded

4

RS

H/L

H: Data code L: Instruction code

5

R/W

H/L

H: Read mode L: Write mode. Can be tied low in hardware

6

E

H, H>L

Enable signal, pulsed from H to L. Hold at H.

7

DB0

H/L

Data bit 0

8

DB1

H/L

Data bit 1

9

DB2

H/L

Data bit 2

10

DB3

H/L

Data bit 3

11

DB4

H/L

Data bit 4

12

DB5

H/L

Data bit 5

13

DB6

H/L

Data bit 6

14

DB7

H/L

Data bit 7

15

BL

5.0

Plus 5V. Power for back lighting the display.

16

BL

Gnd

Ground for back lighting power.

TABLE 9.4 LCD PIN OUTS (LCD PINS NOT CONTROLLED BY THE MICROPROCESSOR ARE MARKED OUT)

PIN NO.

SYMBOL

PIC PIN

DESIGNATION

a0148-01

a0148-02

a0148-03

a0148-04

a0148-05

a0148-06

a0148-07

a0148-08

a0148-09

a0148-10

a0148-11

a0148-12

4

RS

1

RA2 PortA

5

R/W

2

RA3 ”

6

E

18

RA1 ”

7

DB0

6

RB0 PortB

8

DB1

7

RB1 ”

9

DB2

8

RB2 ”

10

DB3

9

RB3 ”

11

DB4

10

RB4 "     )

12

DB5

11

RB5 "     ) Half the port can also be used

13

DB6

12

RB6 "     ) See PBP manual

14

DB7

13

RB7 "     )

a0148-13

a0148-14

a0148-15

a0148-16

a0148-17

a0148-18

a0148-19

a0148-20

Table 9.4 indicates that our microcontroller does not need to be connected to lines 1, 2, 3, 15, and 16 in that these have to do with power connections and not with data I/O. In the preceding case, we will use an 8-bit data buss, and the connection to the PIC 16F877A will be as shown in Figure 9.1.

We can get by with 11 lines, and possibly even 10 if we decide to do without the ability to read from the display memory. This is not usually the case, however, because there are times when we need to set this line high for reading the LCD’s busy flag in order to minimize the time used by LCD routines. Nevertheless, we can add about a 20-milliseconds delay to take care of the busy time. We also need to be able to read the display memory if we want to scroll the display up and have access to what is on display lines one and two. Since this would be true for all applications, we have to stay with the 11 lines for 8-bit control. (We would not have to read the display if we kept track of what we had put in the display somewhere else in the memory.)

The eight data lines form a convenient byte, and we can assign one of the ports not being used for anything else. This leaves three lines:

square The E line, which needs to be toggled to transfer data to the LCD

square The RS line, which selects the register

square The (R/W), which sets the read/write status of the operations

Using eight lines for data allows us to generate all the codes and all the characters that the chip has in its memory, but more importantly, it allows the data transfer to be performed in one step. We can also use a 4-bit protocol and transfer half a byte at a time. Using four lines for our control scheme means the LCD can be controlled from just one port (seven lines will be used, leaving us one line to spare). The datasheets tell us that whether we use four lines or eight, they all must be part of one port, and if we are using four lines, they must be the contiguous four high, or the contiguous four low, bits of a port—meaning we cannot use just any random lines for the data buss. The data transfer for the 4-bit protocol must use the 4 high bits on the LCD, and we must send the data from the PIC to the display with the high data nibble first and the low data nibble last. This little gem is not spelled out in the instructions, but it’s what must be done.

The datasheet also tells us that the display initializes itself on power-up. We can reinitialize it under our control, but it is done automatically on startup and we cannot inhibit that. All we have to do is “not do anything” for about half a second for the self-initialization to complete. The busy flag is set high during startup and initialization, but is indeterminate immediately after initialization starts and for 16.4 milliseconds after the supply voltage reaches 4.5 volts, so we cannot determine how long we have to wait after powering up to start doing what we want. We will set a 0.5-second wait/pause in our program at startup. If that is not long enough, we will come back and increase the waiting time. Wait time is a must. If you do not wait, the system will not start up properly.

Automatic initialization sets the following conditions for the display:

square Display cleared

square Set for 8 bit interface

square Set for 1 line of display

square Set for 5 × 7 dot matrix display

square Display is turned off

square Cursor is turned off

square Blink is turned off

square Increment between characters is set to 1 (cursor moves over one space automatically)

square Shift is off

The preceding may not be exactly what we want for our purposes, so we will go through an initialization sequence as specified by the instructions. We do not have to go through all the steps, but we will, so we have a complete record of what needs to be done for future projects.

The instructions tell us that the following six instructions must be sent to the display during an initialization sequence. The first three instructions are identical but require different waits after each is sent to the display.

TABLE 9.5 LCD STARTUP (SEQUENCE STEPS AND TIMING DELAYS)

STEP

RS LINE

R/W LINE

DATA BYTE

ENABLE LINE

1

1 high

0 low

0011xxxx

Toggle H to L

1A

wait for 4.1 msec

2

1 high

0 low

0011xxxx

Toggle H to L

2A

wait for 100 κsec

3

1 high

0 low

0011xxxx

Toggle H to L

3A

wait for 1 msec

4

1 high

0 low

001110xx

Toggle H to L

5

1 high

0 low

00000001

Toggle H to L

6

1 high

0 low

00000110

Toggle H to L

These instructions are commands rather than data, so the RS (register select) line must be held high while we initialize. See Table 9.5.

The six lines of code in Table 9.5 are explained in detail as follows:

                 “x” in a bit = don’t care
 00110000        ; code to initialize the LCD (this is entered
                 ; 3 times, 1st time)
                 ; load for a command function
                 ; wait at least 4.1ms
                 ;
 00110000        ; code to initialize the LCD     (2nd time)
                 ; load for a command function
                 ; wait at least 100us
                 ;
 00110000        ; code to initialize the LCD     (3rd time)
                 ; load for a command function
                 ; wait at least 1 millisecond
                 ;
 00111000        ; put in 8 bit mode, 2 line, 5X7 dots
                 ; 0
                 ; 0
                 ; 1 =req’d
                 ; 1 =8 bit data transfer
                 ; 1 =2 lines of display
                 ; 0 =5x7 display
                 ; x
                 ; x
                 ; load for a command function
                 ; 
 00010100        ; set cursor shift etc
                 ; 0
                 ; 0
                 ; 0
                 ; 1 =req’d
                 ; 0 =cursor shift off
                 ; 1 =shift to right, or left (0)
                 ; x
                 ; x
                 ; load for a command function
                 ;
 00001111        ; LCD display status, cursor, blink etc
                 ; 0
                 ; 0
                 ; 0
                 ; 0
                 ; 1 =req’d
                 ; 1 =display on
                 ; 1 =cursor on so we can see it
                 ; 1 =blink on so we can see it
                 ; load for a command function
                 ;
 00000110        ; lcd entry mode set, increment, shift etc
                 ; 0
                 ; 0
                 ; 0
                 ; 0
                 ; 0
                 ; 1 =req’d
                 ; 1 =increment cursor in positive dir
                 ; 0 =display not shifted
                 ; load for a command function

At the end of these instructions, the display will have been initialized the way we want it.

There is also this business about the busy flag that we need to be thinking about. The display takes time to do whatever we ask it to do, and the time varies with what we asked it to do. We can wait a few milliseconds between instructions to make sure it has had enough time for the task to complete, or we can monitor the busy flag and as soon as it is not busy we can send the next instruction. Since time is always at a premium, and we want to run as fast as we can, it means we must consider monitoring the busy flag. (This is important because addressing the LCD is one of the most time-consuming parts of most programs, and these small processors are running at only some 20 MHz.)

THE BUSY FLAG

The instruction sheet tells us that the busy flag is bit 5 at location 11100011 in the LCD. Meta Code for waiting for the busy bit in the LCD to clear is as follows:

Busycheck:

    Read busybyte

    Isolate busybit

    If it is busy then goto Busycheck

Return

We isolate the bit and if it is not low, we read the flag byte again. We do this again and again till the bit goes low. As soon as it does, we can write to the LCD and go on with the program.

We also have an interest in having our display be compatible with code generated by the PICBASIC PRO Compiler. Looking at the instructions for the LCDOUT command, we find that the compiler would prefer that the hardware be set up for the following conditions:

square Four data bits DB4 to DB7 connected to PORTA.0 to PORTA.3

square Chip enable at PORTA.3

square Register select at PORTA.4

square Two lines of display are assumed, but we should specify that

If we cannot meet the preceding requirement, we must set the addresses out as DEFINEs in each and every program we write (or we can use an “INCLUDE” statement that includes a program that does this for us). It’s only a few lines of code, but we will have to add the code every time, and it compromises compatibility with other systems that will no doubt be set up to meet the compiler standard. It may turn out that the microcontroller you choose will need to have this done in any case, but if it can be avoided, it should be done at this stage of our learning process.

The next thing we need to decide is whether we are going to use the software as an integral part of a program that is running on a larger microcontroller where we can use all ten address lines for the display, or do we want the software to run on a smaller dedicated microcontroller that will need only one serial line to control the display but will have to be added to the total project as a part of hardware we design. For now, let’s agree that we will go with a dedicated controller just to run the display. The software for running on a larger controller will be a subset of what we develop so no work is lost here.

The task on the input side is to design the software that will take the serial information received on one pin and output it as 4-bit characters to the LCD with the select, read/write, and enable lines. The work needed to do read the data in is done by the compiler with the SERIN instruction.

Program 9.1 does just this, and is provided by microEngineering Labs on their Web site.

Program 9.1 For a PIC 16F84A (Program to simulate back pack [by microEngineering Labs])

 ; PicBasic Pro program to simulate an LCD Backpack
 ; Define LCD registers and bits
 DEFINE LCD_DREG PORTD    ;
 DEFINE LCD_DBIT 4        ;
 DEFINE LCD_RSREG PORTE   ;
 DEFINE LCD_RSBIT 0       ;
 DEFINE LCD_EREG PORTE    ;
 DEFINE LCD_EBIT 1        ;
                          ;
 CHAR VAR BYTE            ; Storage for serial character
 MODE VAR BYTE            ; Storage for serial mode
 RCV VAR PORTB.7          ; Serial receive pin
 BAUD VAR PORTA.0         ; Baud rate pin - 0 = 2400, 1 = 9600
 STATE VAR PORTA.1        ; Inverted or true serial data - 1 = true 
                          ;
 ADCON1 = %00000111       ; Set PORTA and PORTE to digital
 LOW PORTE.2              ; LCD R/W line low (W)
 PAUSE 500                ; Wait for LCD to startup
                          ;
 MODE = 0                 ; Set mode
 IF (BAUD == 1) THEN      ;
  MODE = 2                ; Set baud rate
 ENDIF                    ; 
                          ;
 IF (STATE == 0) THEN     ;
   MODE = MODE + 4        ; Set inverted or true
 ENDIF                    ;
                          ;
 LCDOUT $FE, 1            ; Initialize and clear display 
                          ;
 LOOP:                    ;
   SERIN RCV, MODE, CHAR  ; Get a char from serial input
   LCDOUT CHAR            ; Send char to display
 GOTO LOOP                ; Do it all over again
 END                      ; end program

This program is for the 16F84A, but it can be used on the 16F877A with appropriate DEFINEs. You have set these DEFINEs many times before now, so this should not be a problem.

The preceding program is for a 16F84A PIC. If you load this program into the PIC, you can connect the 16F84A to the LCD, and any serial information that comes in on PORTB.7 will be displayed on the LCD. Now you can control the LCD from one line on the main processor. (The selected pin does not have to be PORTB.7. Any free pin can be specified as the input data pin in the program.)

The wiring diagram for the 16F84A is shown in Figure 9.2.

f0154-01

Figure 9.2 Wiring diagram: LCD backpack using a PIC 16F84. (The data can be programmed to come in at any free line. It does not have to be on pin B7. You set the line you want to use in Program 9.1.)

Liquid Crystal Display Exercises

These liquid crystal exercises are to be performed on the LAB-X1 board.

1. Write a program to put the 26 letters of the alphabet and the ten numerals in the 40 spaces that are available on line 1. Insert four spaces between the numbers and the alphabet to fill in the four remaining spaces. Once all the characters have been entered, scroll the 40 characters back and forth endlessly though the 20 spaces visible on line 1.

2. Write a program to bubble the 26 capital letters of the alphabet through the numbers 0 to 9 on line 2 of the LCD. (This means: First, put the numbers on line 2. Then, “A” takes the place of the “0” and all the numbers move over. Then, the “A” takes the place of the “1” and the “0” moves back to position 1 and so on till it gets past the 9. Then, the “B” starts it way across the numbers, and so forth.)

3. Write a program to write the numbers 0 to 9 upside down on line 1. Wait 1 second and then flip the numbers right side up one by one. Provide a time delay between changes. Loop.

4. Write a program to identify the button pressed on the button pad by displaying its row number on line 1 and its column on line 2. Identify each line so you know what is being displayed where. Scroll the two lines up every time a button is pressed. Add delays in the scroll so you can actually see the scrolling take place.

The full instruction table for the LCD is shown in Table 9.6

TABLE 9.6 THE LCD CODE TABLE

t0155-01

t0156-01

Table 9.6 is for the 16-character-by-2-line LCD display sold by “Images Inc. SI” of New York for about $10 plus postage, and is the module used in all the preceding experiments and those shown in the related diagrams. All Electronics has one for $6.

Almost all LCDs with back packs use the preceding scheme.