Simple Port I/O I/O ports can be used as parallel ports for exchanging information with an external device. The number of bits that are grouped together depends upon the application Figure 1 demonstrates the simplest form of using I/O ports for parallel IO. This configuration assumes that the external device requires bi-directional communications and it assumes that separate pins on the external device are used for receiving and sending data. As noted on Figure 1, the only way for the external device to know when the microprocessor has changed the data is to compare successive readings of the microprocessors output port. The same is true for the microprocessor detecting changes of output from the external device.
Figure 1. Configuration of using two ports for parallel IO
Handshaking Techniques More sophisticated devices require synchronization. Synchronization techniques notify the microcontroller when new data is at an input port and notify external devices when new data is at an output port. Synchronization takes two forms, strobes and state or level handshaking. In general, handshaking negotiates secure and reliable transfer of data commonly called communications. It involves both knowledge and acknowledge. The sender needs a signal from the receiver to know when the receiver is ready to accept the data. The sender supplies a signal line that is used to tell the receiver two distinct pieces of information: then the receiver can read valid data and when the write cycle has finished. The receiver uses a signal line to tell the sender when it is ready to receive data and when it has read the data. These handshaking requirements are summarized in the timing
1 Excerpts taken from http://hcs12text.com/part013a.html#Using%20Ports%20H%20and%20J%20for%20Parallel%20I/O
2 diagram shown in Figure 2. When handshaking uses hardware wires, bits in a status register or bits within a stream of communications to implement the interaction between sender and receiver as shown in Figure 2, the handshaking is called explicate. Some handshaking schemes assume that the receiver is always ready and can accept the data within specified timing constrains. Such handshaking schemes are called implicate or time-implicate handshaking.
S e n d e r R e c e i v e r Time R e c e i v e r
R e a d y N e w
D a t a
R e a d y R e c e i v e r
D a t a
A c c e p t e d T r a n s a c t i o n C o m p l e t e d
Figure 2. Signal action for fully explicate handshaking.
In strobe synchronization, an additional control signal accompanies the data. In the case of an input strobe, the external device pulses the strobe control line when new data is present. A latch, either within or connected to the microcontroller captures the data, and typically asserts an interrupt as shown in Figure 3. The microcontroller must read the data before the next input strobe occurs. In the case of an output strobe, the microcontroller generates a pulse on the strobe control line after it writes new data. The external device uses the strobe to capture the data being sent. The external device must be ready for new data the next time the strobe line is pulsed. In some cases the circuitry to generate the output strobe is built into the microcontroller. In other cases the strobe can be generated via software using another output port pin. Strobes may be either positive (normally low pulsed high) or negative (normally high pulsed low). Generally strobe handshaking assumes that the transaction is concluded on the trailing edge of the strobe pulse. Relative to the transaction edge, the data must be held constant. The period that the data must be held constant prior to the transaction edge is called the data setup time. The period that the data must be held constant after to the transaction edge is called the data hold time. 3 State or level handshaking is used to indicate when the data lines are valid (not in transition). Data valid (DAV) handshaking can be indicated by either a high or low state depending upon the application. The data setup time is relative to the assertion of the DAV signal and the data hold time is relative to the DAV signal returning to its inactive state.
Figure 3. Strobe handshaking Handshaking synchronization solves the problem of data being sent before the receiving end is ready. A second (acknowledgment or busy) control line as shown in Figure 4 is used by the receiving device to signal the sending device that it is ready for the next data transmission. For handshaking with an output device, an extra input port pin is used to receive the busy indication from the external device. This input is polled and no new data is sent unless the pin is not asserted (not busy). A potential race condition exists if the microcontroller tests the busy bit before the output device asserts busy, however if busy is asserted automatically by the output device hardware, the microcontroller will not be able to test the bit quickly enough. 4
Figure 4. Handshaking write strobe with Busy control
Figure 5 below shows handshaking for an input device. The signals are the same but the roles of the microcontroller and external device are reversed. In this case a latch was added so that busy would be asserted immediately when data is received. The microcontroller pulses an output port pin to reset the busy latch when it is ready for the next data byte.
Figure 5. Handshaking from external device
5 Potential race conditions can be avoided by employing full handshaking. Full handshaking uses both edges of the strobe and busy signals. Figure 6 shows the scheme for an input device. The microcontroller indicates to the device when it is ready for data. This is the inverse of the Busy signal we have seen before. The input device provides the data and indicates its availability by raising its strobe signal, Data Available (DAV). Unlike the preceding cases, the strobe signal is held high until the data recipient, the microcontroller, acknowledges receipt by lowering its request for data signal. The input device then knows that the data has been successfully received, removes the data, and waits for the next data request.
Figure 6. Processor poll for data available
When IO ports are used to provide both data and handshaking controls and the control signals are managed using software, the process is called bit banging. The states of the handshaking signals are explicitly assigned in software as opposed to the handshaking signal generated using hardware as shown in Figure 5. Another form of handshaking embed the busy or ready signals into the data flow. Examples of this is the interface to the character LCD modules based on the Hitachi HD44780 that will be discussed below. 6 Example: LCD Driven from IO Ports 2
1. Introduction to LCDs Advances in the features, miniaturization, and cost of LCD (Liquid Crystal Display) controller chips have made LCDs usable not only in commercial products but also in hobbyist projects. By themselves, Liquid Crystal Displays can be difficult to drive because they require multiplexing, AC drive waveforms, and special voltages. LCD modules make this driving simpler by attaching hardware to the raw glass LCD to assist in some or all of these rudimentary driving tasks. LCD modules can be split into two groups: those that have built-in controller and driver chips, and those that have only driver chips. LCD displays that do not have controllers are typically used with powerful hardware, such as a laptop computer, where a video controller is available to generate the complex drive signals necessary to run the display. Most color and large (greater than 320x240) monochrome displays are of this type. The category of display modules that have built-in controllers can be split again into character LCD modules and graphic LCD modules. Character modules can display only text and perhaps some special symbols, while graphic modules can display lines, circles, squares, and patterns in addition to text. Some examples of graphic LCD controller chips are the Toshiba T6963, Seiko-Epson SED1330, and Hitachi HD61202. Here, we will be primarily concerned with character LCD modules that have the Hitachi HD44780 controller built-in. Nearly every pixel-based alphanumeric LCD module made today uses the Hitachi HD44780 LCD controller chip, or a derivative such as the Seiko-Epson SED1278. This apparent standardization in character LCDs has become extremely beneficial to design engineers and hobbyists. Dozens of manufacturers produce literally hundreds of models of LCD modules using this controller chip. The smallest of these displays is only one line of 8 characters; the largest is four lines of 40 characters each. Other common sizes are 16x1, 20x1, 20x2, 20x4, 40x1, and 40x2 (characters x lines). Fortunately, all HD44780-based displays (of any size) use the same standard 14- wire interface. Therefore, code and hardware made for one size/type display can be painlessly adapted to work for any HD44780 compatible device. Information about these displays can be easily obtained on the web by including HD44780 in your search keywords. Because of their widespread use, these displays can be purchased surplus with typical prices of $3 for small displays to $20 for large ones.
2. Interfacing your LCD module
The microcontroller/microprocessor interface to HD44780 LCD modules (hereafter generically referred to as character LCD modules) is almost always 14 pins. Table 1 shows the basic pinout. You may find that some displays have additional pins for backlighting or other purposes, but the first 14 pins still serve as the interface.
7 The first three pins provide power to the LCD module. J1.5 and/or J2.5 provides the power GND and is connected to the digital ground. Pin J1.6 and/or J2.6 is for the VCC power and should be connected to +5V power. is the LCD Display Bias. Some displays that are specially made to work over a large temperature range may require a negative voltage to achieve readable contrast. Pins J2.1 J2.2 and J2.3 are the control lines for the LCD. These lines indicate what kind of transaction you are proposing to do over the data lines DB0-7. The state of RS indicates whether you wish to transfer commands or display data. The R/W line indicates whether you intend to read or write. Finally, the E line tells the display when you are actually ready to perform the transaction. The control lines RS, R/W, and E, along with the data lines DB0-7 are standard digital logic inputs or outputs. Remember than when performing reads you must set the port connected to DB0-7 to be input.
Figure 7 . Cerebot MX7ck interface with LCD on ECE 341 project PCB
Table 1. LCD pin out list
As shown in Figure 7, the system used in the ECE 341 lab uses JB pint 1 through 4 and 7 through 10 of the Cerebot MX7ck processor for data lines and JC pins 1 through 3 of JC for the handshaking and controls lines. The handshaking and control lines are 8 outputs from the Cerebot MX7ck can be bit-banged to implement the required control. The RS and R/W line are the control signals that are connect to the Cerebot MX7ck edge connector JC pins 1 and 2. The E (enable) line is the handshaking signal for this interface and it is controlled by the Cerebot MX7ck connector JC pin 3. Additional details concerning the exact sequence required to execute a data transfer to or from the LCD will discussed in later sections of this chapter. The contrast adjust can be used to make the LCD more readable as viewed from various angles of incidence. Some character LCD models use pin 15 for enabling additional lines. These units actually have dual controllers with shared RS and RW control lines but with separate enable handshaking signals. Although the handshaking described here is implemented using direct bit control (bit banging) the code provided for Lab 6 uses the PMP (Peripheral Master Port) interface to control the LCD. Refer to the chapter 10 of the text for additional details.
3. Accessing your LCD module
Character LCD modules are accessed through only two registers, the Command Register, and the Data Register. When you perform a read or write with RS low, you are accessing the Command Register and giving the module instructions. When you read or write with RS high, you are accessing the Data Register and reading or writing characters/data from or to the display.
Table 2 contains pseudo-code examples of reads and writes to the two registers. The pseudo-code can be implemented on any microcontroller and assumes that DBPORT is the port to which DB0-7 are connected. Since some microcontrollers are very fast, delays may be required between the steps described in the pseudo-code. See the concise datasheet on the course web page for more information.
Table 2. LCD register access pseudo code
4. Initializing and programming your LCD
Character LCDs based on the Hitachi HD44780 controller have two address pointers. The display RAM (DDRAM) pointer contains the address of the position where the cursor is located and /or where the next character entered will be located. When data is written to the LCD with the RS control line asserted high, the information on the data 9 lines will be displayed on the LCD. 3 Data is entered as ASCII encoded text. 4 Non ASCII data will be displayed as either special graphics characters built into the LCD or special programmable characters. 5 Writing bit patterns to the character generator RAM (CGRAM) creates programmable characters. Character LCDs must be initialized after power-on and before writing data to the display. The initialization must consist of at least a Function Set command, preferably followed by an Entry Mode Set, Display Control, and a Clear Display. Issuing each of these commands after the Function Set ensures that you know the state of your display. Instructions on how to issue and use these commands can be found by looking at the concise datasheet, or at the HD44780 controller datasheet for more information. Below is an example initialization sequence and hello world program assuming youve programmed the C functions LCDCommandWr(unsigned char command); to write commands to the LCD, and LCDputc(unsigned char data); to write data to the LCD:
Listing 1. Peseudo code for initializing and writing to the LCD // initiatize lcd LCDCommandWr(0x38); // function set: // Busy flag is not valid sw_delay_ms(5); // User supplied software delay function // 8-bit interface, 2 display lines, 5x7 font LCDCommandWr (0x06); // entry mode set: // Busy flag is not valid sw_delay_ms(1); // User supplied software delay function
// turn display on, cursor on, no blinking LCDCommandWr (0x10); // shift mode / direction: // wait for not busy see Listing 5. while(ck_bf_addr() & 0x80); // increment automatically, no display shift LCDCommandWr (0x0E); // display control: // wait for not busy see Listing 5. while(ck_bf_addr() & 0x80); LCDCommandWr (0x01); // clear display, set cursor position to zero
Using the user supplied LCDputc function (see Listing 4), characters can be sent to the LCD by executing the following list of C instructions
// write hello world to the display LCDputc(H); LCDputc(e); LCDputc(l); LCDputc(l); LCDputc(o); LCDputc( ); LCDputc(W); LCDputc(o);
After initialization, the text can also be displayed on the LCD using the function: LCDputs(Hello World);
Where the function LCDputs is defined as:
Listing 2. C function for writing a string of ASCII tect to the LCD Void LCDputs(char *s) { while(*s) LCDputc(*s++); }
Refer to http://home.iae.nl/users/pouweha/lcd/lcd.shtml 6 for additional details on the HD44780 based character LCD
5. Interface between the LCD module and the Cerebot MX7ck Microprocessor Table 3 and Table 4 shows the control line states and the data values to implement LCD controls described in part 4 above. The function, LCDCommandWr , must set the RS and RW lines low prior to asserting the LCD enable pin high. The data must be written to port E prior to asserting the LCD enable pin low. Figure 10 Shows the timing required to write to and read from the LCD unit. Table 5 defines the timing parameters identified in Figure 10. The four LCD initializing commands can now be interpreted in light of the instruction set shown in Table 3. The LCDCommandWr function writes data to the LCD with the RS and RW controls low. After setting the data lines and control bits, the enable bit is toggled high and back low. The enable line must be set back low for the LCD to record the new control and display data. The first command in Listing 1, LCDCommandWr(0x38); calls a function that sets the data bits for 38h .The LCD register is selected by the bit position of the most significant high bit of the data bus, which, for this case is D5. D4 controls the number of data lines used for interfacing between the microprocessor and the LCD unit. (Character LCD units can operate using either 4 or 8 bit data busses. This will be discussed in greater detail later in this chapter.) For the LCD models used in the ECE 341 lab, D3 must be set to a one and bit D2 is a dont care and may be either zero or one. The second command in Listing 1, LCDCommandWr(0x06); calls the same function described in the paragraph above to set the entry mode. When set high, bit D1 specifies that the address pointer to the LCD display RAM should be incremented after each new display character is written to the LCD. If this bit were not set, the address pointer would decrement after each new character and the text would appear to be entered from right to left.. With bit D0 set to a zero, all of the characters on the display remain fixed in their positions. If bit D0 is set high, the display would shift. The direction of shift would be specified by the Cursor/Display Shift instruction.
Table 3. HD44780 instruction set Instruction Code Description Execution time** RS R/ W D7 D6 D5 D4 D3 D2 D1 D0 Clear display 0 0 0 0 0 0 0 0 0 1 Clears display and returns cursor to the home position (address 0). 1.64mS Cursor home 0 0 0 0 0 0 0 0 1 * Returns cursor to home position (address 0). Also returns display being shifted to the original position. DDRAM contents remains unchanged. 1.64mS Entry mode set 0 0 0 0 0 0 0 1 I/D S Sets cursor move direction (I/D), specifies to shift the display (S). These operations are performed during data read/write. 40uS Display On/Off control 0 0 0 0 0 0 1 D C B Sets On/Off of all display (D), cursor On/Off (C) and blink of cursor position character (B). 40uS Cursor/display shift 0 0 0 0 0 1 S/ C R/ L * * Sets cursor-move or display-shift (S/C), shift direction (R/L). DDRAM contents remains unchanged. 40uS Function set 0 0 0 0 1 DL N F * * Sets interface data length (DL), number of display line (N) and character font(F). 40uS Set CGRAM address 0 0 0 1 CGRAM address Sets the CGRAM address. CGRAM data is sent and received after this setting. 40uS Set DDRAM address 0 0 1 DDRAM address Sets the DDRAM address. DDRAM data is sent and received after this setting. 40uS Read busy- flag and address counter 0 1 BF CGRAM / DDRAM address Reads Busy-flag (BF) indicating internal operation is being performed and reads CGRAM or DDRAM address counter contents (depending on previous instruction). 0uS Write to CGRAM or DDRAM 1 0 write data Writes data to CGRAM or DDRAM. 40uS Read from CGRAM or DDRAM 1 1 read data Reads data from CGRAM or DDRAM. 40uS Remarks: - DDRAM = Display Data RAM. - CGRAM = Character Generator RAM. - DDRAM address corresponds to cursor position. - * = Don't care. - ** = Based on F osc = 250kHz. Table 4. Bit names for commands listed in Table 3 Bit name Setting / Status I/D 0 = Decrement cursor position 1 = Increment cursor position S 0 = No display shift 1 = Display shift D 0 = Display off 1 = Display on C 0 = Cursor off 1 = Cursor on B 0 = Cursor blink off 1 = Cursor blink on 12 Bit name Setting / Status S/C 0 = Move cursor 1 = Shift display R/L 0 = Shift left 1 = Shift right DL 0 = 4-bit interface 1 = 8-bit interface N 0 = 1/8 or 1/11 Duty (1 line) 1 = 1/16 Duty (2 lines) F 0 = 5x7 dots 1 = 5x10 dots BF 0 = Can accept instruction 1 = Internal operation in progress
The third command in Listing 1, LCDCommandWr(0x10); calls the function to enter a command that sets the cursor or display shift and the direction. With bits D3 and D2 both set low, the cursor will shift right after each display character has been entered. If D3 is set high, all of the display characters will shift the direction specified by D2 instead of the cursor. The fourth command in Listing 1, LCDCommandWr(0x0E); calls the function to enter a command that controls that turns the display off or on and controls the cursor display mode. When bit D2 is set high, the LCD display is turned on. When bit D1 is set high, the LCD cursor is turned on and when bit D0 is set high, the LCD cursor will blink on and off. The final command in Listing 1, LCDCommandWr(0x01); calls the function to enter a command that clears the LCD, puts the cursor in the left column, and sets the display address pointer to zero. To this point, all data has been written to the LCD. Data in both the CGRAM and the DDRAM can also be read if both the RS and the RW bits are asserted high. If the LCD is read with the RS bit set low, (the RW bit must still be set high to read the LCD) the address pointer of either the DDRAM or the CGRAM can be read as well as the LCD busy flag. In order to read or write the CGRAM address, a Set CGRAM Address command must first be written to the LCD. Likewise, reading or writing to the DDRAM requires that the Set DDRAM Address command be sent to the LCD. Sending the Clear Display command accomplishes that same instruction as setting the DDRAM to zero. The Busy flag is the most significant bit when reading either the DDRAM or the CGRAM. The LCD should not be written to as long as the busy flag is high. The busy flag must be read with the direction of the Cerebot MX7ck processor set for input and the control bits set as for reading the DDRAM or CGRAM. The Cerebot MX7ck Port E bits 0 through 7 must be read while the LCD enable bit is high. The enable line must always be set back low again before any new data can be read from the LCD. Data from the LCD cannot change as long as the enable line is in the high state regardless of any internal changes of address or busy flag. One final point to note from Table 3 is the instruction execution times listed in the far right column. These execution times represent the worst case conditions during which the busy flag will be read as high.
13 5. Managing the LCD
Eight basic functions are required to efficiently manage the LCD. These are: initializing, writing commands, reading the address and busy flag, positioning the cursor and writing display character data. There is also a software delay required during the LCD initialization sequence. The collaboration diagram shown in Figure 8 describes the relationship of these six functions. Other functions may be necessary if you go beyond displaying simple text messages on the LCD. The actions of the six basic functions will be explained in detail below. Application Program LCD Text Display LCD Initialization LCD Write Commands SW Delay LCD Read BF and Address LCD Display Character P o s it io n Setup Control code A d d r e s s
/
B F Control code delay ASCII Char Text string A S C I I
C h a r B F LCD Cursor Position P o s itio n C o n tr o l c o d e B F
Figure 8. Collaboration diagram for basic LCD control functions Initialize LCD This function must write a sequence of commands to the LCD with RS bit low. The basic setup is described by the code in Listing 1 but lack the prescribed delays between each write command. This delay is necessary because the busy flag is not valid until after the initializing sequence has completed. It is recommended that a 30ms delay follow the set entry mode command and 2 ms following all subsequent commands in the initializing sequence. Generally, each of the commands are written by calling a specific function that asserts the RS and RW bits low as discussed in the following section. 14 Write Command after initialization To write an LCD command, execute the following sequence:
Listing 3. Write command sequence of tasks 1. Check busy flag until not busy and read DDRAM address (usually accomplished in a separate function see Figure 8.) 2. RS (Port B bit 15) and RW (Port D bit 4) pins are asserted low 3. Port E bits 0 through 7 direction is set for output 4. Write the command data to Port E 5. The LCD enable pin (Port D bit 5) is asserted high 6. The LCD enable pin (Port D bit 5) is asserted low
This sequence of operations meets the ordering requirements shown in Figure 10. The timing constraints from Figure 10 and Table 5 require that a minimum of 40 ns (t SU ) be between steps 2 and 4. (Steps 3 and 4 can be executed in reverse order provided that the RS and RW signals are asserted 40 ns before the enable signal is asserted high.) As long as the data is written to Port E prior to step 5, the data lines can be written at any time hence the data setup time is specified by the parameter (t W - t tD ) Most of the minimum timing requirements listed in Table 5 are easily met when the RS, RW, and Enable controls are bit-banged on relatively slow microprocessors. However, the Enable cycle time specification requires a 500 ns interval between two consecutive rising edges. It is possible that the PIC32 processor will violate that constraint unless a delay function is employed. The Enable signal line must be held high at least 220 ns and the data lines must not change for 20 ns after the Enable line has returned to a low to satisify the data hold requirements..
LCD_Cmd_Wr Wait for not Busy Set RS=0 RW=0 Set Port A as Output Write Command to Port A Pulse En control Return After LCD initialization
Figure 9. Flow diagram for the LCDCmdWr function.
15
Figure 10. LCD Writer Cycle Timing Diagram
Table 5. LCD control timing for timing diagram shown in Figure 10
Write Display Character The sequence for writing display data to the LCD is much the same as writing LCD control commands. There are, however, two notable exceptions. The first exception is the need to filter out ASCII control characters. The LCD control actions to implement common ASCII control characters are listed in Table 7.
16 Table 6. LCD controls actions to implement ASCII control characters. Hex Value Name Action LCD Control Sequence 0X00 NULL Do nothing LCD will display programmable graphich character at CGRAM address 0 0x08 Back space Move cursor one position to the left. (\010) 1. Test address for 1 st position of line 1 a. Yes do nothing b. No Continue 2. Test address for 1 st position of Line 2 a. Yes set DDRAM address for end of line 1 b. No decrement DDRAM Address and write new address to LCD 3. If backspace is non destructive a. No do nothing b. Yes write space character and repeat steps 2 and 3 above. 0x0A New line \n Send LCD instruction for clear display (0x01) 0x0C Form Feed New Page (\011) Same as New Line above (\n) 0X0D Carriage return \r Send LCD instruction to put cursor in home position (0x02) 0x07 Bell Ring the bell Make funny noises (manual command)
In general, the LCD character display requires the following sequence. The timing requirements shown in Figure 1 and Table 5 must be observed. From personal experience, I can guarantee that your LCD will have inconsistent and erratic behavior (including the display) unless the sequences and timing constraints are observed.
Listing 4. Sequence of tasks for writing a display character or ASCII control character 1. Check busy flag until not busy and read DDRAM address 2. Test character for control character a. send appropriate write control function b. exit function 3. Test address for end of line a. send new DDRAM address to write control b. test busy flag until not busy ignore cursor address c. continue to write display character 4. Assert RS (Port B bit 15) high 5. Assert RW (Port D bit 4) low 6. Set Port E bits 0 through 7 for output pins 7. The data is written to Port E 8. Assert the LCD enable pin (Port D bit 5) high 9. Assert the LCD enable pin (Port D bit 5) low 10. Set Port E bits 0 through 7 for input
17 Read Busy Flag This function must be called after writing every of a display characters or control instructions following the initialization sequence. The LCD must be read with the RW bit set high and the RS bit set low. The timing requirements shown in Figure 1 and Table 5 must be observed for this operation as well. Since reading the busy flag also results in reading the DDRAM or CGRAM address, the function can return the data as a single byte or as two separate variables. The following steps are needed to read the busy flag.
Listing 5. Sequence of tasks for reading the busy flag 1. Assert RS (Port B bit 15) low 2. Assert RW (Port D bit 4) high 3. Set Port E bits 0 through 7 for input 4. Assert the LCD enable pin (Port D bit 5) high 5. Read Port E 6. Assert the LCD enable pin (Port D bit 5) low
Should the LCD need to be read again, such as may be required when polling the busy flag, steps 4 through 6 must be repeated in sequence otherwise the LCD output will not change. The timing for the read operation shown in Figure 11 uses parameters defined in Table 5.
Figure 11. LCD read cycle timing LCD_read_bf Set Port A for Input Set EN, RS=0 RW=1 Set E=1 Read Port A Set E=0 Return BF|Addr
Figure 12. Flow diagram for the LCD check busy and read cursor address function.
18 6. Programmable Graphics Character Generation 7
When you send the ASCII code for a character like "A" to an LCD module, the module's controller looks up the appropriate 5x8-pixel pattern in ROM (read-only memory) and displays that pattern on the LCD. That character-generator ROM contains 192 bit maps corresponding to the alphabet, numbers, punctuation, Japanese Kanji characters, and Greek symbols. The ROM is part of the main LCD controller (e.g., HD44780, KS0066, etc.), is mask-programmed, and cannot be changed by the user. The manufacturers do offer alternative symbol sets in ROM for European and Asian languages, but most U.S. distributors stock only the standard character set shown in the LCD Serial Backpack manual. Alphanumeric LCD controllers do not allow you to turn individual pixels on or off-they just let you pick a particular pattern (corresponding to an ASCII code) and display it on the screen. If you can't change the ROM and you can't control pixels, how do you create graphics on these LCDs? Easy. There's a 64-byte hunk of RAM (random-access memory) that the LCD controller uses in the same way as character-generator (CG) RAM. When the controller receives an ASCII code in the range that's mapped to the CG RAM, it uses the bit patterns stored there to display a pattern on the LCD. The main difference is that you can write to CG RAM, thereby defining your own graphic symbols. A character LCD that uses the HD44780 controller allow for eight programmable characters. The character patterns must be first written to the CGRAM of the LCD. First, the CGRAM must be select by setting the CGRAM address for the character that is to be programmed. Each eight consecutive addresses starting at CGRAM address zero are assigned to one programmable graphical character. Each bit of the data at each address sets the pixel on (1) or off (0). The pixels on a particular row at the right of the character display have the lowest binary value. The rows of pixels start at the top and move down the character as the addresses increase in value as shown in Figure 13.
7 Excerpts taken from http://www.geocities.com/dinceraydin/lcd/custom.htm 19
Figure 13. Example bit map for a programmable graphical character.
A WEB based character calculator can be use to help determine the list of bytes that need to be written to the CGRAM. 8
9 Be advised that the calculator referenced in 9 only generates seven bytes of data and does not specify data for the bottom row of pixels. Writing to CG RAM is a lot like moving the cursor to a particular position on the display and displaying characters at that new location. The steps are:
Listing 6. Steps to program graphical characters Reset RS and R/W pins of the LCD to prepare the LCD to accept instructions Set the CG RAM address by sending an instruction byte from 64 to 127 (locations 0-63 in CG RAM). Switch to DATA MODE by changing setting the RS pin Send bytes with the bit patterns for your symbol(s). The LCD controller automatically increments CG RAM addresses, just as it does cursor positions on the display. To leave CG RAM, switch to COMMAND MODE to set address counter to a valid display address (e.g. 128, 1st character of 1st line); the clear-screen instruction (byte 1); or the home instruction (byte 2). Now bytes are once again being written to the visible portion of the display. To see the custom character(s) you have defined, print ASCII codes 0 through 7.