lcd displays that are compatible with the hitachi hd44780 driver supplier
The Hitachi HD44780 LCD controller is an alphanumeric dot matrix liquid crystal display (LCD) controller developed by Hitachi in the 1980s. The character set of the controller includes ASCII characters, Japanese Kana characters, and some symbols in two 40 character lines. Using an extension driver, the device can display up to 80 characters.
The Hitachi HD44780 LCD controller is limited to monochrome text displays and is often used in copiers, fax machines, laser printers, industrial test equipment, and networking equipment, such as routers and storage devices.
Compatible LCD screens are manufactured in several standard configurations. Common sizes are one row of eight characters (8×1), and 16×2, 20×2 and 20×4 formats. Larger custom sizes are made with 32, 40 and 80 characters and with 1, 2, 4 or 8 lines. The most commonly manufactured larger configuration is 40×4 characters, which requires two individually addressable HD44780 controllers with expansion chips as a single HD44780 chip can only address up to 80 characters.
Character LCDs may have a backlight, which may be LED, fluorescent, or electroluminescent. The nominal operating voltage for LED backlights is 5V at full brightness, with dimming at lower voltages dependent on the details such as LED color. Non-LED backlights often require higher voltages.
Character LCDs use a 16-contact interface, commonly using pins or card edge connections on 0.1 inch (2.54 mm) centers. Those without backlights may have only 14 pins, omitting the two pins powering the light. This interface was designed to be easily hooked up to the Intel MCS-51 XRAM interface, using only two address pins, which allowed displaying text on LCD using simple MOVX commands, offering cost effective option for adding text display to devices.
Vee (also V0): This is an analog input, typically connected to a potentiometer. The user must be able to control this voltage independent of all other adjustments, in order to optimise visibility of the display that varies i. a. with temperature and, in some cases, height above the sea level. With a wrong adjustment, the display will seem to malfunction.
R/W: In most applications, reading from the HD44780 is not necessary. In that case, this pin can be permanently connected to ground and no processor pins need to be allocated to control it.
In 8-bit mode, all transfers happen in one cycle of the enable pin (E) with all 8 bits on the data bus and the RS and R/W pins stable. In 4-bit mode, data are transferred as pairs of 4-bit "nibbles" on the upper data pins, D7–D4, with two enable pulses and the RS and R/W pins stable. The four most significant bits (7–4) must be written first, followed by the four least significant bits (3–0). The high/low sequence must be completed each time or the controller will not properly receive further commands.
Selecting 4-bit or 8-bit mode requires careful selection of commands. There are two primary considerations. First, with D3–D0 unconnected, these lines will always appear high (binary 1111) to the HD44780 since there are internal pull-up MOSFETs.
The same command is sent three times, Function Set with 8-bit interface D7–D4 = binary 0011, the lower four bits are "don"t care", using single enable pulses. If the controller is in 4-bit mode, the lower four bits are ignored so they cannot be sent until the interface is in a known size configuration.
In all three starting cases, the bus interface is now in 8-bit mode, 1 line, 5×8 characters. If a different configuration 8-bit mode is desired, an 8-bit bus Function Set command should be sent to set the full parameters. If 4-bit mode is desired, binary 0010 should be sent on D7–D4 with a single enable pulse. Now the controller will be in 4-bit mode and a full 4-bit bus Function Set command sequence (two enables with command bits 7–4 and 3–0 on subsequent cycles) will complete the configuration of the Function Set register.
The CGRAM is read/write memory used to encode up to 8 characters in the character generator. It consists of 64 fields at addresses 0 to 3F hex. Each field is 5 bits mapping to a row of pixels of each character. Each 8 fields in the CGRAM are used for each character. The lower 3 bits of the character codes from 0–7 and 8–15 select the groups of 8 fields in the CGRAM memory.
Reading and writing to the DDRAM is done by setting the RS input high during bus transfers. The DDRAM must also be selected by using the Set DDRAM address command which selects the DDRAM for access and also sets the starting address for DDRAM access.
Likewise reading and writing to the CGRAM is done by setting the RS input high during bus transfers. The CGRAM must also be selected by the Set CGRAM address command which selects the CGRAM for access and also sets the starting address for CGRAM access.
The execution times listed in this table are based on an oscillator frequency of 270 kHz. The data sheet indicates that for a resistor of 91 kΩ at VCC=5 V the oscillator can vary between 190 kHz and 350 kHz resulting in wait times of 52.6 µs and 28.6 µs instead of 37 µs. If a display with the recommended 91 kΩ resistor is powered from 3.3 volts the oscillator will run much slower. If the busy bit is not used and instructions are timed by the external circuitry, this should be taken into account.
The original HD44780 character generator ROM contains 208 characters in a 5×8 dot matrix, and 32 characters in a 5×10 dot matrix. More recent compatible chips are available with higher resolution, matched to displays with more pixels.
The 7-bit ASCII subset for the Japanese version is non-standard: it supplies a Yen symbol where the backslash character is normally found, and left and right arrow symbols in place of tilde and the rubout character.
A limited number of custom characters can be programmed into the device in the form of a bitmap using special commands. These characters have to be written to the device each time it is switched on, as they are stored in volatile memory.
Huang, Han-Way (2009). The HCS12 / 9S12: An Introduction to Software and Hardware Interfacing (2nd ed.). Delmar Cengage Learning. ISBN 978-1-4354-2742-6.
I cannot post a link in the first message, so please check the reply I"ll write for this very message, and I"ll post a link to the shop I"d like to use...
The closest thing to a standard is, unfortunately, for LCD panels that have controllers but no drivers. IIRC, a typical interface will have signals for phase polarity, frame clock, line clock, data clock and 4 data bits. Every line of pixels one should clock in enough groups of four pixels to fill the width of the display (extra bits will be ignored), driving the data clock high and low for each group. The drive the line clock high and low to strobe the line. The first line of each frame should have the frame clock high, and the phase polarity signal should toggle every frame.
The line clock signals, and those derived from them, must be sent at a uniform rate. The precise timing of the data clock signals, however, doesn"t matter provided that all the clocks happen for a line happen within the proper window. If you don"t have DMA, it may be possible to keep a small display happy and still have time to do something else, but refreshing the display will be a pain. If you do have DMA, however, and can manage a small CPLD to handle a few aspects of the timing, implementing the display that way may be very rewarding. I"ve done a display panel like that and achieved display-update performance superior to anything I could have done with a conventional display controller. I even achieved 4-level gray-scale by running the display at 100 frames/second and, every three frames, driving the display twice using one buffer and once with another.
As of August 2018 the State of California has changed the requirements of the �Prop 65� law. We now must list on our website any possible chemicals the can cause cancer, birth defects or reproductive problem.
To put it simply we are a small company and do not have the resources to test every single part, so we list every thing as hazardous. Please recycle all electronic parts responsibly and under no circumstance eat, drink or smoke these parts and wash your hands after touching!
Blue 16x2 LCD module featuring 2 rows consisting each of 16 characters. The module is compatible with the Hitachi HD44780 controller, and is commonly used in Arduino and other microcontroller projects.
If you’ve ever attempted to connect an LCD display to an Arduino, you’ve probably noticed that it uses a lot of Arduino pins. Even in 4-bit mode, the Arduino requires seven connections – half of the Arduino’s available digital I/O pins.
The solution is to use an I2C LCD display. It only uses two I/O pins that are not even part of the digital I/O pin set and can be shared with other I2C devices.
As the name suggests, these LCDs are ideal for displaying only characters. A 16×2 character LCD, for example, can display 32 ASCII characters across two rows.
If you look closely, you can see tiny rectangles for each character on the screen as well as the pixels that make up a character. Each of these rectangles is a grid of 5×8 pixels.
At the heart of the adapter is an 8-bit I/O expander chip – PCF8574. This chip converts the I2C data from an Arduino into the parallel data required for an LCD display.
There is a jumper on the board that provides power to the backlight. To control the intensity of the backlight, you can remove the jumper and apply external voltage to the header pin labeled ‘LED’.
If you have multiple devices on the same I2C bus, you may need to set a different I2C address for the LCD adapter to avoid conflicting with another I2C device.
For this purpose, the adapter comes with three solder jumpers/pads (A0, A1, and A2). The address is set when a jumper is shorted with a blob of solder.
An important point to note here is that several companies, including Texas Instruments and NXP Semiconductors, manufacture the same PCF8574 chip. And the I2C address of your LCD depends on the chip manufacturer.
According to the Texas Instruments’ datasheet, the three address selection bits (A0, A1, and A2) are located at the end of the 7-bit I2C address register.
When you short a solder jumper, you pull that address input LOW. If you were to short all three jumpers, the address would be 0x20. So the range of all possible addresses spans from 0x20 to 0x27.
According to the NXP Semiconductors’ datasheet, the three address selection bits (A0, A1, and A2) are located at the end of the 7-bit I2C address register. However, the remaining bits in the address register are different.
When you short a solder jumper, you pull that address input LOW. If you were to short all three jumpers, the address would be 0x38. So the range of all possible addresses spans from 0x38 to 0x3F.
So the I2C address of your LCD is most likely 0x27 or 0x3F. If you’re not sure what your LCD’s I2C address is, there’s an easy way to figure it out. You’ll learn about that later in this tutorial.
Now we are left with the pins that are used for I2C communication. Note that each Arduino board has different I2C pins that must be connected correctly. On Arduino boards with the R3 layout, the SDA (data line) and SCL (clock line) are on the pin headers close to the AREF pin. They are also referred to as A5 (SCL) and A4 (SDA).
After wiring the LCD, you will need to adjust the contrast of the LCD. On the I2C module, there is a potentiometer that can be rotated with a small screwdriver.
Now, turn on the Arduino. You will see the backlight light up. As you turn the potentiometer knob, the first row of rectangles will appear. If you have made it this far, Congratulations! Your LCD is functioning properly.
Before you can proceed, you must install the LiquidCrystal_I2C library. This library allows you to control I2C displays using functions that are very similar to the LiquidCrystal library.
To install the library, navigate to Sketch > Include Library > Manage Libraries… Wait for the Library Manager to download the library index and update the list of installed libraries.
Filter your search by entering ‘liquidcrystal‘. Look for the LiquidCrystal I2C library by Frank de Brabander. Click on that entry and then choose Install.
As previously stated, the I2C address of your LCD depends on the manufacturer. If your LCD has a PCF8574 chip from Texas Instruments, its I2C address is 0x27; if it has a PCF8574 chip from NXP Semiconductors, its I2C address is 0x3F.
If you’re not sure what your LCD’s I2C address is, you can run a simple I2C scanner sketch that scans your I2C bus and returns the address of each I2C device it finds.
However, before you upload the sketch, you must make a minor change to make it work for you. You must pass the I2C address of your LCD as well as the display dimensions to the LiquidCrystal_I2C constructor. If you’re using a 16×2 character LCD, pass 16 and 2; if you’re using a 20×4 character LCD, pass 20 and 4.
The next step is to create an object of LiquidCrystal_I2C class. The LiquidCrystal_I2C constructor accepts three inputs: I2C address, number of columns, and number of rows of the display.
In the setup, three functions are called. The first function is init(). It initializes the interface to the LCD. The second function is clear(). This function clears the LCD screen and positions the cursor in the upper-left corner. The third function, backlight(), turns on the LCD backlight.
The function setCursor(2, 0) is then called to move the cursor to the third column of the first row. The cursor position specifies where you want the new text to appear on the LCD. It is assumed that the upper left corner is col=0 and row=0.
There are many useful functions you can use with LiquidCrystal_I2C Object. Some of them are listed below:lcd.home() function positions the cursor in the upper-left of the LCD without clearing the display.
lcd.scrollDisplayRight() function scrolls the contents of the display one space to the right. If you want the text to scroll continuously, you have to use this function inside a for loop.
lcd.scrollDisplayLeft() function scrolls the contents of the display one space to the left. Similar to the above function, use this inside a for loop for continuous scrolling.
lcd.display() function turns on the LCD display, after it’s been turned off with noDisplay(). This will restore the text (and cursor) that was on the display.
If you find the default font uninteresting, you can create your own custom characters (glyphs) and symbols. They come in handy when you need to display a character that isn’t in the standard ASCII character set.
As previously discussed in this tutorial, a character is made up of a 5×8 pixel matrix; therefore, you must define your custom character within this matrix. You can define a character by using the createChar() function.
To use createChar(), you must first create an 8-byte array. Each byte in the array corresponds to a row in a 5×8 matrix. In a byte, the digits 0 and 1 indicate which pixels in a row should be OFF and which should be ON.
CGROM is non-volatile memory that retains data even when the power is removed, whereas CGRAM is volatile memory that loses data when the power is removed.
The CGROM stores the font that appears on a character LCD. When you instruct a character LCD to display the letter ‘A’, it needs to know which pixels to turn on so that we see an ‘A’. This data is stored in the CGROM.
CGRAM is an additional memory for storing user-defined characters. This RAM is limited to 64 bytes. Therefore, for a 5×8 pixel LCD, only 8 user-defined characters can be stored in CGRAM, whereas for a 5×10 pixel LCD, only 4 can be stored.
Creating custom characters has never been easier! We’ve developed a small application called Custom Character Generator. Can you see the blue grid below? You can click on any pixel to set or clear that pixel. And as you click, the code for the character is generated next to the grid. This code can be used directly in your Arduino sketch.
There’s no limit to what you can create. The only limitation is that the LiquidCrystal_I2C library only supports eight custom characters. But don’t be sad, look at the bright side; at least we have eight characters.
After including the library and creating the LCD object, custom character arrays are defined. The array consists of 8 bytes, with each byte representing a row in a 5×8 matrix.
This sketch contains eight custom-characters. Take, for example, the Heart[8] array. You can see that the bits (0s and 1s) are forming the shape of a heart. 0 turns the pixel off, and 1 turns it on.
In the setup, we use the createChar() function to create a custom character. This function accepts two parameters: a number between 0 and 7 to reserve one of the eight supported custom characters, and the name of the array.
TSW1100 : Tsw1100 Data Capture Board. Connect to a Texas Instrument"s ADC EVM. 7 Provide Power to the ADC EVM. 7 Providing Power to the TSW1100. 7 Connecting to the USB 7 Launching the TSW1100 Software. 7 Information. 9 Setting Up Remote Control of Instruments. 9 Select the ADC Under Evaluation. 9 Configure the Input Waveform (AIN) Conditions Capture the ADC Samples, Perform an FFT,.
OH3000 : Hallogic Hall-effect Sensors. Designed for non-contact switching operations Operates over broad range of supply voltages to 24 V) Operates with excellent temperature stability in harsh environments Drive capability to 7 TTL loads Product Photo Here : These Hall-effect devices contain a monolithic integrated circuit which incorporates a Hall element, a linear amplifier, a threshold.
M3A23TAA : 8 pin DIP, 5.0 or 3.3 Volt, Acmos/ttl, Clock Oscillators. MtronPTI reserves the right to make changes to the product(s) and service(s) described herein without notice. No liability is assumed as a result of their use or application. Please see www.mtronpti.com for our complete offering and detailed datasheets. Contact us for your application specific requirements: MtronPTI 1-800-762-8800. .
AMIS-30421 : Stepper Motor Controller The AMIS30421 is a micro stepping stepper motor bridge controller for large current range bipolar applications. The chip interfaces via a SPI interface with an external controller in order to control two external power NMOS H bridges. It has an on chip voltage regulator, current sensing, self adapting PWM controller and pre driver.
RH-053.3D/H6 : Isolated DC/DC Converters 1W 5Vin +/-3.3Vout +/-152mA SIP7. RECOM Power Econoline RK/H6 & RH/H6 DC/DC Converters RK/H6 & RH/H6: 1Watt SIP7 Single and Dual Output DC/DC Converters feature high 6.4kVDC isolation and an extended operating temperature range up to +90�C without derating, yet are lower cost than standard high isolation converters.
The following documentation describes a potential way to drive HD44780-style 16x2 character LCDs in graphics mode by using a synchronized updating scheme and complementary special characters.
Character LCDs used in industrial machinery, test equipment and hobby projects are popular, long-lived and mostly based on Hitachi HD44780-style controllers (+ drivers) from multiple manufacturers:
The driving scheme for passive matrix displays depends on the arrangement of character groups and format (e.g. 5x8, 5x10, 5x11), but is most often seen to be 1:16-multiplexed with 1/5 level bias.
The 1:2 multiplex scheme below (taken from the NXP PCF2119 datasheet) conveys the idea in a more accessible fashion. STN pixels at the junction of row and column conductor stripes see a differential AC waveform. Small amplitudes don"t cause a pixel to switch, and in this case, pairs of frames must be generated complementarily to create a zero time average (no DC component).
With this in mind, the timing for a display with 1:16 multiplexing and 1/5 bias can be understood as cycling through all 16 rows, where only the first time slot associated with COM1 has the high levels contributing to cell switching.
Although HD44780-like controllers have an 8 bit parallel interface, the instruction decoding and memory access logic appears to be such that one command takes at least 37 µs at 270 kHz nominal clock speed, or 10 clock cycles. The write cursor (pointer) is post-incremented when a write command is performed, so at least one address update needs to precede or follow a burst write operation. Writing 16 consecutive characters costs a minimum of 170 clocks. Filling an 8x2 character region costs at least 180 clocks, highlighting the limitations of what is possible within the time duration of a single-line drive phase of 200 clocks.
In terms of organization, 16x2, 20x2 and 20x4 LCDs use additional drivers to add more column lines, which follow a bias scheme like the one discussed above. The application circuit below shows the daisy-chained configuration for up to 20x4 characters:
Note that only a 8x2 character block is driven by the controller itself. Pixel data for all remaining characters is transferred to daisychained driver ICs via a 3-wire synchronous serial interface.
This will be used later by inserting a resistor into the data (D) line from the controller to the first driver. A GPIO pin connected after the resistor is used for bi-directional interaction. Display controllers use a resistor-programmed internal oscillator, and injected data is synchronized to CL1, CL2 or M.
Just by looking at videos people have taken from their displays, tearing as a pre-requisite can be observed. As the bar graph is updated, blocks indicate data was updated during a frame.
The appetite for graphic memory access is perhaps best visible through the widespread fascination hobbyists and demoscene people have with the measly 8 custom characters available in all controllers. This well-documented feature is used by writing character code 0x00 .. 0x07 into DDRAM. The controller then gets pixel data from CGRAM and uses it analogous to CGROM data.
Although many controller manufacturers offer multiple CGROM variants (font sets) with special characters, there aren"t 2^40 different unique ones (128 GB) to display arbitrary 5x8 pixel blocks - needless to say the 40 bit character code might as well represent the pixel information itself.
If one could swap out a character before each line were serialized and sent to the column drivers however, each of 8 horizontal lines making up a 5x8 pixel character could be loaded from one of 32 characters. This subdivides the representation of an 5x8 arbitrary pixel block into 8 consecutively selected LUT characters. The image below shows placeholders for all LUT characters. The dark gray regions are ignored, while the relevant lines are drawn in black/light gray, depicting the required bit patterns.
These are exact matches, but some pixel combinations are left out. Luckily, there are still 8 custom characters available to complement the CGROM set.
With the exception of the first LUT line, all LUT lines have <= 8 missing characters, so CGRAM codes can be inserted, and CGRAM pixels defined accordingly by copying the sought-after 5-pixel combinations to their corresponding y positions. These are the custom characters derived from the A02 font set (with some artistic license, as 5-pixel lines of the same y position are interchangeable):
The following LUT example depicts how 5x8 graphics content is mapped to 8 LUT characters displayed in sequence, and of which only one line is used to compose the ouput on the LCD panel.
To investigate whether there is a window of opportunity to write LUT codes into DDRAM and to reset the DDRAM cursor periodically and synchronized to the bit pattern generation, an reduced section of the functional block diagram from the HD44780 datasheet is presented below.
DDRAM addresses come from the instruction decoder, as well as from the timing generator (not necessarily indicated in all datasheets). The 8 bit data bus is necessarily controlled by the MPU (or instruction decoder). As the data bus is shared, access is likely to be interleaved.
4-bit line positions (0..7 for 5x8 characters, 0..10 for 5x11) need to come from the timing generator, as the memory outputs are only 5 bit wide towards the serializer.
The timing generator and MPU need to be synchronized to ensure appropriate phasing of data transfers into the serializer unit. Some arrows are rather hand-waivy. The more familiar "reset" signal doesn"t point to anything in particular, and it is implied that it connects to multiple blocks. Both "Instruction decoder" arrows have an unspecified bit width, but they"re not 1 bit wide (not plausible for address data to counter). So essentially there is a possibility that multiple lines are routed to the Timing Generator block, allowing an operation to reset the Timing Generator. Hopefully DISPLAY ON/OFF triggers such a reset.
Other datasheets are even less clear about the actual function or existence of Instruction Decoder outputs and interconnectedness. Maybe a die shot would help to clarify.
This leads to believe that the Parallel/Serial converter unit is also buffered and in part controlled by the MPU / instruction decoder. Depending on the address counter (< 16), CGRAM 5-bit data is used instead of CGROM 5-bit data. Additionally, the order of DDRAM readout is dependent on the display layout stored in the MPU, so the MPU is continuously involved in loading DDRAM data.
The serializer needs to be filled with fresh data for every line, as the line selection already happens during CGRAM / CGROM access and no full CGROM/CGRAM 2D image is copied. The functional block diagram shows a 40 bit shift register connected to the serializer. Strangely, the "parallel/serial converter" has a 40 bit wide output bus, so it essentially stores the eight 5-bit values loaded from CGRAM/CGROM.
The maximum size is 80 displayed characters, each measuring 5x8 pixels, for a total of 3200 pixels. Divide that by the maximum of 16 COM lines and each line has to have 200 pixels. This number shows up above as the "200 clocks" for which one COM line is driven in a 1:16 multiplexing scheme. So without measuring, one can derive that the serializer is clocked at the full oscillator frequency. It seems plausible that the serializer would then run continuously but only fed a part of the time when displays are smaller.
We now also know that the MPU has 5 clock cycles to get the CGROM/CGRAM data into the parallel buffer of the parallel/serial converter, and for a 20x4 display, serializer data loading has to run continuously.
The MPU is thus twice as fast when transferring the data as one could write it into DDRAM. Timing-wise, one needs to start writing right at or behind the internal reading address. Assuming an instruction or data write operation takes 11 clocks, 16 LUT characters + 1 instruction byte can be written and processed, unlocking 16x2 * 5*8 graphics mode. That"s 80x16 (1280) pixels, give or take.
It should also be noted that when limiting oneself to an 8x2 character block and 1/16 multiplexing, DDRAM 0x00 .. 0x07 and 0x40 .. x047 can also be directly filled with custom chracters 0 .. 7. Instead of changing character codes in DDRAM, write operations can update CGRAM patterns in the corresponding custom character lines, creating full pixel access. The second set of rows (COM8..15) start at CGRAM line 0, 1, ... again, making custom characters a just-in-time video buffer.
Furthermore, when injecting data into the serial interface to the daisy-chained extension drivers, only 8 characters + 1 command byte need to be written, further relaxing the timing and creating leeway for "software" synchronization. The latter relies on the assumption that a DISPLAY ON/OFF command resets the row counter in the timing generator. HD44780-like controllers offer an external clock option for jitter- and drift-free operation, but adding wires for extension driver CL1, CL2, M and D lines seems a lot more useful. The timing seems to be too critical to rely on RC oscillator accuracy anyway, and even though that makes it an invasive modification, it is being rewarded with a pathway to 20x4 character graphic mode.
With a 4k7 resistor placed over a cut through the D line between main controller and the first auxiliary driver, a GPIO can be connected on the driver side for bidirectional I/O. CGROM or custom characters can then be read as they are being sent out to column drivers and synchronized to, before the GPIO is switched to push-pull mode, taking over the role as pixel data source.
Presenting pixel data to extension drivers only, and also using them for row driving, seems to have been a product reality around 1985, as the picture below shared by AVRFreaks user ossi evidences:
so there really should be nothing holding us back morally from modifying modern displays for pixel data injection synchronous to a clock provided by a controller.
This is not official manufacturer"s information. It is distilled from information on many different data sheets and from my own experience. I have never used some of these displays. I have extrapolated what I know about the displays that I have used to the ones that I have just read about. I welcome any suggestions and corrections. Contact information is at the bottom of the page.
The HD44780 type controller chip is used with a wide variety of Liquid Crystal Displays. These LCDs come in many configurations each with between 8 and 80 viewable characters arranged in 1, 2, or 4 rows.
The problem is that there is no way to inform the controller of the configuration of the display that it is driving. The controller operates exactly the same way for all displays and it is up to the programmer of the device that is controlling the LCD controller (usually a host microcontroller) to deal with this situation.
The controller contains 80 bytes of Display Data Random Access Memory which is usually referred to as DDRAM. When the controller is used with a 40 x 2 display (forty characters on each of two rows) the operation is quite straightforward and that operation will be explained first. Each of the other configurations introduces one or more quirks so it is best to understand the operation of the 40 x 2 before proceeding to the description of the operation of any of the others.
This is the most common Memory Map for the 80 bytes of DDRAM in the HD44780 controller. There is another rarely encountered configuration that will be presented later.
As you can see the DDRAM consists of two lines of memory with a somewhat mysterious gap (see note 1) in the addressing when going from the first line of memory to the second. The first line has 40 storage locations identified by the addresses 00h through 27h. The second line has another 40 storage locations identified by the addresses 40h through 67h.
Each of these DDRAM memory addresses corresponds to a character position on an attached display, but the specific position varies depending on the configuration of that display. As part of the initialization sequence the display is cleared by storing the ASCII code for a space in each of the 80 memory locations. Subsequently if a different ASCII code is stored in any of those memory locations then the character corresponding to that ASCII code is automatically displayed at a specific location on the display.
You can tell the controller where you want the first ASCII character that you send it to be stored, this is usually address 00h. After receiving that character it will automatically update its address pointer and put the next ASCII character you send into an adjacent memory location with no more addressing work on your part. You can specify whether to increment or decrement the address counter but normally it is incremented, so the next character will be put into address 01h. The LCD controller automatically accounts for the gap in addresses and after storing an ASCII code in address 27h it puts the next code in address 40h. Similarly it increments from address 67h back to 00h.
Here is a simplified diagram of the display on a 40 x 2 LCD Module. Each of the boxes in the diagram represents a location where a character can be displayed.
Here is a copy of the memory map of the controller. Remember, each of the memory locations in the controller chip is directly associated with one of the character locations on the display.
By some miracle of modern technology there is actually a one for one relationship between these two diagrams. If an ASCII code is stored at address 00h in memory the corresponding character will appear at the left end of the top row of the display. If an ASCII code is stored at address 63h in memory the corresponding character will appear five locations in from the right end of the second row of the display.
Here is a diagram showing how the two rows of the display are mapped into the two lines of memory. It is basically a combination of the two diagrams just above.
When the host controller wants to display a string of characters on the display all it has to do is specify a starting DDRAM address and then start sending the string of ASCII codes corresponding to the desired characters to the LCD controller, one after another. The LCD controller takes the first code that it receives, stores it at the specified address, and simultaneously displays the corresponding character on the display. It then increments it"s internal address counter and stores the next ASCII code that it receives in the next DDRAM location which causes the corresponding character to appear in the next location on the display. As mentioned before the LCD controller automatically accounts for the gap in addresses and after storing an ASCII code in address 27h it puts the next code in address 40h. Similarly it increments from address 67h back to 00h.
This display also has 80 characters, but the relationship between the DDRAM addresses and the character locations on the LCD is not quite as straightforward as the LCD with two rows of 40 characters. Here is a diagram of the device.
The memory map is always the same regardless of the display configuration, but in this drawing I have shown a small space between addresses 13h and 14h on the first line and another between addresses 53h and 54h on the second line.
Here is the same memory map, rearranged this time to show how the memory addresses relate to the character positions on a 20 x 4 LCD. Note how the right half of the previous diagram is now below the left half and note the resulting sequence of starting addresses for each display row (00h, 40h, 14h, 54h).
Remember that the LCD controller still considers this to be two lines of RAM. It is important to understand that this way of picturing the DDRAM addresses helps relate the memory addresses to the character locations but does not change the fact that as far as the controller is concerned there are only two lines of memory. In other words, although this diagram shows the DDRAM differently than before, the actual DDRAM configuration and operation is exactly the same as described above for the 40 x 2 display since there is no way of telling the LCD controller that there are now 4 rows of 20 characters instead of 2 rows of 40 characters.
When a long string of ASCII codes is sent to this LCD controller the action is not quite as simple as for the 40 x 2 display. After the first row is full the characters will continue on to the third row. The normal automatic incrementing from 27h to 40h will then cause the display to continue on the second row, and from there it will continue to the fourth row. After that the following characters will appear back on the first row, and so on.
In order to get a coherent display on sequential rows it is necessary to compensate for the design of the LCD controller when programming the host microcontroller. Basically the program on the host microcontroller can keep track of the DDRAM addresses, and when appropriate it can set up a new starting DDRAM address.
For each of the above displays there are 80 addresses in memory and there are 80 character locations on the display so it should be obvious that any time you send an ASCII code to the controller the corresponding character will show up somewhere on the display. If you mess up the address the character may not show up where you expected it, but it will be visible somewhere. If you work back from where it actually appears you can usually figure out where you made your mistake. All of the displays that follow have fewer character locations on the display than memory addresses in the controller. This makes the operation somewhat more complicated and troubleshooting more difficult.
This can be thought of as a truncated 40 x 2 display, but there are some ramifications of this truncation that may not be readily apparent. Here is a drawing of the device.
It is important to understand that, although this diagram shows only the part of the DDRAM that is normally used to display information on the 20 x 2 LCD, the actual memory map and controller operation is exactly the same as described above for the previous displays. Again that is because there is no way of telling the LCD controller that there are only 40 characters on the attached display.
Here is a drawing of the complete memory map. Note that this drawing is the same as the one for the 20 x 4 display except that the addresses on the right side are greyed out.
Although this display has only 40 characters there are still 80 bytes of DDRAM and they are still configured the same as they were before. The greyed out addresses are the locations in DDRAM that do not have corrresponding locations on the display. Any ASCII codes that are written to those locations are not lost, and it is possible to display them by "shifting" the display window, but in normal use as described here they are simply not displayed.
When a long string of ASCII codes is sent to this LCD controller the action is not quite as simple as for either of the 80 character displays. Assume that the host controller is sending a string of characters as described above. Consider what happens after the LCD controller stores an ASCII code in address 13h and displays the corresponding character at the right end of the top row on the LCD. It then stores the next ASCII code in address 14h, which has no corresponding location on this 20x2 display. As more ASCII codes are sent to the LCD controller they are stored in the DDRAM but do not appear on the display until the LCD controller finally increments it"s address counter from 27h to 40h at which time subsequent characters start to appear on the second row of the display. As far as a viewer of the display is concerned there is a gap of 20 missing characters. The same thing will happen on the second row when ASCII codes are stored in addresses 54h - 67h.
In order to prevent any missing characters the program on the host microcontroller can keep track of the DDRAM addresses, and when appropriate it can set up a new starting DDRAM address. On the other hand the display can be shifted to display those missing characters, but the techniques to do that will not be covered here.
This is a commonly found configuration and its operation is almost identical to that of the 20 x 2. The relationship between the DDRAM addresses and the character locations on the LCD is a subset of the example shown above. Here is a drawing of the device.
Once again it is important to understand that although this diagram shows only the part of the DDRAM that is normally used to display information on the 16 x 2 LCD the actual DDRAM configuration and operation is exactly the same as described above for the 40 x 2 display. This is because there is no way of telling the LCD controller that there are only 32 characters on the attached display.
Here is a drawing of the complete memory map. Note that this drawing is the same as the one for the 20 x 2 display except that a different range of addresses on the right side are greyed out.
The operation of this display when a long string of characters is sent to it is that same as described for the 20 x 2 display except that there is a gap of 24 missing characters at the end of each line (instead of 20).
There are actually two different varieties of 16 x 1 LCD displays and the initialization and operation of each is different so it is important to determine which one you have.
When power is first applied to any of the multi-row LCD modules and before the controller is initialized you will see that the character locations corresponding to the first line of memory are dark and the others are light (assuming that the contrast adjustment is properly set). If you apply power to a 16 x 1 LCD module and only the left 8 character locations are dark you have what I will call a type 1 module. If only the right 8 character locations are dark this is also a type 1 module but it is upside down! If all 16 character locations are dark then it is what I will call a type 2 module. This is my own terminology used only for the purpose of keeping them differentiated while describing their operation. The type 1 modules will have only one IC on the back of the pcb while the type 2 will have 2 (I guess this tidbit gives away the source of my "type" designations). This distinction may apply to newer devices with epoxy blobs instead of ICs, but I believe that sometimes one blob may cover more than one equivalent IC function.
From this you can see that although the display has only a single row of characters, as far as the LCD controller is concerned it is using two lines of memory and it must be considered to be a 2 line device when initializing the controller.
Here is a drawing of the complete memory map. Note that this drawing is the same as the one for the 20 x 2 and 16 x 2 displays except that a different range of addresses on the right side are greyed out.
Here you can see that if the host controller sends a long string of characters without periodically adjusting the DDRAM starting address then after each 8 characters are displayed the next 32 will "disappear".
Also, to display a message of more than 8 characters on the 16 character display the host controller will have to readjust the DDRAM address after displaying the first 8 characters.
Here is a drawing of the complete memory map. Note that this memory map is different than all of the previous ones. This is the only device described here that is a true "one-line" display (see note 2) and as such it has a different memory map.
Here you can see that if the host controller sends a long string of characters after the first 16 characters are displayed the next 64 will "disappear".
At the expense of an extra IC you get some slightly easier programming since, in order to display a message of more than 8 characters on the 16 character display, the host microcontroller does not have to readjust the DDRAM address after displaying the first 8 characters.
Since only one line of memory is in use this LCD module should be configured as a 1-line device. As far as I can determine, this changes the multiplex frequency which changes the display brightness and/or contrast. Also, there are some single row LCDs that are capable of displaying a larger 5x10 font instead of the more common 5x7 font.
I"ve stuck this description toward the end because, as you will see, it has some of the characteristics of the 40 x 4 and some of the characteristics of the 16 x 2. Here is a drawing of the device.
Here is the same memory map, rearranged this time to show how the memory addresses relate to the character positions on a 16 x 4 LCD. Note how the center of the previous diagram is now below the left part, the right part is missing, and the resulting sequence of starting addresses for each display row is different than for the 20 x 4 (00h, 40h, 10h, 50h).
Here you can see that if the host controller sends a long string of characters without periodically adjusting the DDRAM starting address then after the first row is full the characters will continue on to the third row. After the third row is full the next eight characters "disappear". The normal automatic incrementing from 27h to 40h will then cause the display to continue on the second row, and from there it will continue to the fourth row. After the fourth row is full the next eight characters will "disappear" and then it"s back to the first row.
The 40 x 4 LCD is treated essentially as two 40 x 2 devices stacked one on top of another in the same glass enclosure. Electrically it uses what amounts to two HD44780 controller chips and it therefore has two separate memory maps each with the same address range. One is used for the top two lines and the other is used for the bottom two lines. The memories are accessed individually by strobing the desired Enable pin of which there are now two. Here is a diagram of the device.
To display a really long string of characters on this display the host controller would start out just like it did for the 40 x 2 display. It would specify a starting DDRAM address (typically 00h) and then start sending the string of ASCII codes corresponding to the desired characters to the LCD controller, one after another, making sure to strobe the enable pin associated with the upper memory bank. After storing an ASCII code in address 67h the LCD controller will automatically increment to address 00h as before and at this time the host controller must stop strobing the enable pin for the upper bank and start strobing the one for the lower bank.
There are other LCD configurations available but I believe that any of them can be handled by a technique similar to one of the examples above. If you have a display that seems to be considerably different from any of these I would like to hear from you.
(1) The mysterious gap is due to considerations resulting from the multiplexing of the display. The DDRAM addressing uses seven bit addressing and the highest bit signifies which row of memory is involved. If you compare the addresses in the first row with those just below in the second row you will see that the only difference is in that one bit.
(2) As implied above the number of rows of characters that can be displayed on the LCD is not the same as the number of lines of memory used by its controller. Only some of the 16x1 displays use "one line" of memory, all of the other displays including most 16x1 displays, use "two lines" of memory.