hitachi hd44780 lcd display made in china
CFAG19232C-TMI-TT Rev.014 should work as a drop in replacement for the CFAG19232C-TMI-TT Rev.011. The only changes to the module effected the LCD bias circuit. Since the module is shipped with fixed (controlled by ST7920) contrast, we do not anticipate any issues migrating to the new revision.
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.
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.
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 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 HD66727, dot-matrix liquid crystal display controller and driver LSI incorporating a key scan function, displays alphanumerics, katakana, hiragana, and symbols. It can be configured to drive a dotmatrix liquid crystal display and control key scan functions under the control of an I2C bus or a clocksynchronized serial microprocessor. A single HD66727 is capable of displaying up to four 12-character lines, 40 segments, and 12 annunciators, and controlling up to a 4-by-8 key matrix, and driving three LED. The HD66727 incorporates all the functions required for driving a dot-matrix liquid crystal display such as display RAM, character generator, and liquid crystal drivers, and it also incorporates a booster for the LCD power supply and key scan functions.
- Clear display, display on/off control, icon and mark control, character blink, white-black inverting blinking cursor, icon and mark blink, return home, cursor on/off, white-black inverting raster-row
The HD44780 is a controller for display developed by Hitachi commonly used to manage alphanumeric dot matrix LCD. This controller is a standard de-facto for this kind of display. It is often used in industrial test equipment, networking equipment, vending machine and in embedded projects.
Compatible LCD screens are manufactured in several standard configurations. Common sizes are one row of eight characters (1x8), as well as 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 40x4 characters, which requires two individually addressable HD44780 controllers with expansion chips as a single HD44780 chip can only address up to 80 characters. A common smaller size is 16×2, and this size is readily available as surplus stock for makers and prototyping work.
We want to provide a full library for HD44780 compatible with ChibiOS/HAL 3.0 ad a demo explaining gradually how software has been designed. This task requires a preliminary read of HD44780 datasheet.
In this article we are going to use a 16x2 LCD driven by HD44780. This display usually comes with a monochromatic backlight and a 16 PIN header connector.
In our case we have connected the LCD to an STM32 Nucleo-64. The first two PINs are required to power up the chip. Our connections are VSS to GND and VDD to 5V. The contrast regulator PIN (V0) has been connected to a 20k potentiometer which is between 3.3V and GND.
All the information about HD44780 working principle are extracted by the documentation previously introduce. We are going to summarise them in order to achieve our goal which is design a flexible library.
It was an afternoon, I had pulled out an Arduino Leonardo and an LCD Keypad Shield. I wanted to build something Wi-Fi connected, so I grabbed an ESP8266 Wi-Fi Shield as well and thought I’d be on my way. Even if the AT-command set mode wasn’t great, I was only looking to build something simple.
Getting a little ahead of myself, I had no stackable pin headers, so I decided to stuff the Wi-Fi Shield behind the LCD Keypad Shield and just solder it to the slightly-long headers it already had. That went just fine and so I tried snapping it onto the Leonardo – aside from a slight port-clearance issue, it sat “well enough”.
After tearing a few (useless) pads off the board and still resorting to a heat-gun, I managed to separate the two but not without some casualties – the LCD had taken a good dose of heat resulting in some noticeable discolouration, so I don’t know if that was still good or not.
I still had a really beaten up LCD shield module that had been through many ordeals and seemed to be bin material. But then, I thought I might as well give it a go – by desoldering as much of the broken pins out and replacing just the pins necessary, I decided to give it a shot.
The LCD was still alive, but with a slight bright spot on the top row. That’s quite amazing. But then, I thought it would be nice to make something less “random and confusing” – why not make something aesthetically eye-catching.
Keeping myself occupied for the afternoon, I decided that I would take the random-character-sketch and instead do something a little less random and a little more artistic. That’s when I came up with the idea of illustrating “Words vs Numbers” on an LCD. As I had an old Arduino Mega 2560 that had a bunch of blown I/O pins due to an accident with some scrap wire and an even larger 20×4 LCD that was doing absolutely nothing for the past six years, I decided it would be nice to just cobble it together for some fun.
The new project would:Put numbers in random positions on the display on a regular basis, rather than doing random characters sequentially as my LCD test did. This would create a sparkling that would look like “noise” on a background of numbers that might be somewhat reminiscent of The Matrix.
Write random words to random positions on the display on a regular basis. This would be taken from a list of common English words – fitting as many in as possible to increase variety.
With some white coloured hook-up wire (as that was what I had left), a half-damaged Arduino Mega 2560 clone board, a 10kohm precision trimpot, an old LCD display and a lot of hot glue … we have this monstrosity.
This code was kept as simple as possible and was something I ended up writing within half an hour. The idea is to use LiquidCrystal library for parallel LCD interfacing, using random() to generate the necessary random values seeded by an analogRead() value from an unconnected pin. The loop sets the cursor to a random position within the LCD and writes a random character within the range (defined as numbers) to that position. It delays a fixed amount of time, and counts every loop. After a fixed number of loops, we turn on the “blink” feature so the block cursor shows (to make the word printing more obvious) and pull a random string from the string table in PROGMEM. This is written to a random position on the screen character by character (ensuring it fits into the screen), followed by a five-times-length delay to give the eye some time to identify and read the word before it is “destroyed” by further random writes. The blink feature is turned off when returning back into the random number writing loop.
The full code for both an Arduino Leonardo (or other 32kB microcontrollers) and Arduino Mega 1280/2560 (or 64kB+ microcontrollers) can be downloaded: randomlcd.zip
It’s not something really amazing or perhaps even unique, but more a result of a lot of frustration. Borne out of some code I wrote to just test an LCD which I had tortured, I decided to extend it with the help of a few online corpuses to print random words over a sea of random numbers. But now that I’ve built it, I do like it – it seems rather visually interesting at times to just pick a word out from the “sea” of numbers before it disappears.
Character based LCD displays are great: they are inexpensive, and it is rather simple to use them compared to graphical displays. Yes, they only can display text and custom symbols, but this is usually what I need. And pretty much all character displays are using the Hitachi HD44780 protocol, so it is a de-facto industry standard.
These displays have one big disadvantage: they need to be compatible with the original Hitachi interface and protocol. First display were mostly one line only, and had only few characters, typically up to 16. The protocol worked either with one or two lines on the display. Today’s display have usually two lines, with 16 characters. But what if I need more?
These HD44780 displays can run in 4bit or 8bit mode, and in the smallest configuration (4bit mode) the connection to the microcontroller only needs 6 wires:
The original protocol had a big problem: there is no handshaking between microcontroller and display. If the microcontroller writes to the display, it needs to wait until the display has finished the operation until a new write operation can start. So the micrcontroller needs to wait some time, depending on the display speed. To overcome this problem, later displays had added the R/W (Read/Write) signal which allows the microcontroller to read the status from the display (if the display is ready to accept new data). So if you consider to use a display, make sure it has that R/W line implemented.
So writing at address 0x00 would be the first character on line 1, 0x01 the second, and so on. Writing at address 0x40 would be the first character on the second line, and so on. That would allow up to 64 characters per line. A 16-character display would show the characters e.g. from address 0x00-0x0F. The other bytes in the address map could be used to ‘scroll’ the text to the right/left using special display commands:
As this feature has not been used much, and there was a bigger customer needs for having 4 lines of text, some vendors decided to change the memory map to support 4 lines (see “Character LCD with 4 Lines”):
If I want now to have 4 lines with more than 16 characters, something different is needed. My display driver (LCDHTA, see “HD44780 2×16 Character Display for Kinetis and Freedom Board“) worked fine, but not for a 4×40 display which was used by a reader of this blog :-(: the NewHaven NHD-0440WH-ATFH-JT Display:
Until I realized: they have put 2 display controller together! This display is not really a 4×40 character display, it is two 2×40 displays in a single display packaging :-). This is the same as if I would combine two displays on the same bus like this:
As I did not had the Newhaven 4×40 display available to verify the driver, I wired two 2×16 displays together. And with this, I was able to build a 4×16 (potentially 4×64) character display:
The Hitachi HD44780 is very common and can be considered as ‘industry standard’. But as with any standards, it comes with limitations, and standards sometimes make it hard to move the technology to the next level. And sometimes it causes kind of strange solutions as creating a 4 line display with two display controllers on it. Switching the Ex lines I can now support up to for 4 lines and up to 64 characters for each line. And if needed, I can extend that concept for more lines/displays.
In the previous chapter, we have discussed how a character LCD is interfaced with a PIC microcontroller in 8-bit mode, where we used predefined characters stored in the LCD to display our data. In this article, we will learn more about the LCD and how we can create and use custom characters.
DDRAM or “Data Display Random Access Memory” is the working data buffer of the display. Each character on the display has a corresponding DDRAM location and the byte loaded in DDRAM controls which character is displayed.
CGROM or “Character Generation Read Only Memory” holds all the standard patterns for the 5 x 7 dot matrix characters. For instance, if you want to display character “A”, you would send ASCII code 65 (decimal) to the DDRAM. The display controller looks up the pattern of dots to display for this code in the CGROM and lights up the ones appropriate for “A”. The CGROM contents depend on the particular character set and model of display, US, Chinese etc. and cannot be changed.
CGRAM or “Character Generation Random Access Memory” allows the user to define special supplementary non-standard character types that are not in the CGROM. You can load your own dot pattern shapes and call these up for display.
For making custom patterns we need to write values to the CGRAM area defining which pixel to glow. These values are to be written in the CGRAM address starting from 0x40. CGRAM has a total of 64 Bytes. For LCD using 8×5 dots for each character, you can define a total of 8 user defined patterns (1 Byte for each row and 8 rows for each pattern).
Custom characters are assigned fixed display codes from 0 to 7 for pattern stored in the location pointed by CGRAM address 0x40, 0x48, 0x56… and so on. So, if the user wants to display second pattern (pattern stored at CGRAM address 0x48), simply call the data function with value 1 as an argument at a desired location in the LCD.
To display the sequence in the LCD, we need to specify the position on LCD and which pattern to display at the position. Provide adequate delay in between frames to observe the sequence distinctly.
Marlin deals with a variety of different displays and needs to display a lot of different languages in different scripts on them, within their capabilities. The system described here solves some of the related problems that need to be overcome with in a limited environment.
Marlin 1.0 and 1.1 currently support: HD44780 (and similar) with Kana charset A00 HD44780 (Page 17) These are very common, but sadly not very useful when writing in European languages.
HD44780 (and similar) with Western charset A02 HD44780 (Page 18). These are rare, but fairly useful for European languages. Also a limited number of Cyrillic symbols is available.
On all these displays you can define 8 custom symbols to display at once. In Marlin these characters are used on the Boot Screen, and on the Info Screen for the Bed Temp, Degree symbol, Thermometer, “FR” (feed-rate), Clock, and Progress Bar. On the SD Card listing screens some of these characters are re-used again for Up-level, Folder, and Refresh.
Graphical displays provide complete freedom to display whatever we want, so long as we provide a program for it. Currently we deal with 128x64 Pixel Displays and divide this area into ~5 Lines with ~22 columns. So we need monospace fonts with a bounding box of about 6x10. Until now we’ve been using a custom Marlin font similar to ISO10646-1 but with special symbols at the end, which made ‘ü’ and ‘ä’ inaccessible at 6x10 size.
All these languages (except English) normally use extended symbols not contained in US-ASCII. Even the English translation uses some Symbols not in US-ASCII (e.g., ‘\002’ for Thermometer, STR_h3 for ‘³’). In the code itself symbols may be used without taking into account the display they’re written on.
The upshot of all this is that on Western displays you’ll see a ‘~’ while on Cyrillic an “arrow coming from top - pointing to left” (which is quite the opposite of what the programmer wanted). The Germans want to use “ÄäÖöÜüß”, the Finnish at least “äö”. Other European languages want to see their accents too. For other scripts like Cyrillic, Japanese, Greek, Hebrew, … you have to find totally different symbol sets.
The Japanese translator dealt with two scripts, introducing a special font for Graphical Displays and making use of the Japanese extended character displays. Thus he ended up with two pretty unreadable language.h files full of ‘\xxx’ definitions. Other languages either tried to avoid words that included special symbols or just used the basic symbols without the accents, dots… whatever.
Make output functions that count the number of chars written and switch the font to Marlin symbols and back when needed. (ultralcd_impl_DOGM.h) (ultralcd_impl_HD44780.h)
Make three fonts to simulate the HD44780 charsets on dogm-displays. With these fonts the translator can check how the translation will look on character-based displays.
Make ISO fonts for Cyrillic and Katakana - because they don’t need a mapping table, are faster to deal with, and have a better charset than the HD44780 fonts. (Less compromise!)
Direct HD44780 Translation Symbols outside the normal ASCII-range (32-128) are written as “\xxx” and point directly into the font of the hardware declared in Configuration.h.
If you make extensive use, your file will look like language_kana.h and your language file will only work on one of the displays (in this case DISPLAY_CHARSET_HD44780 == JAPANESE).
If you want to make use of more than a few symbols outside standard ASCII or want to improve the portability to more types of displays, use UTF-8 input. Which means defining another mapper.
The mapper_tables do their best to find a similar symbol in the HD44780fonts (for example, replacing small letters with the matching capital letters). But they may fail to find a match and will output a ‘?’. There are combinations of language and display which simply have no corresponding symbols - like Cyrillic on a Japanese display or _vice-versa. In those cases the compiler will throw an error.
In short: Choose a mapper that works with the symbols you want to use. Use only symbols matching the mapper. On Full Graphic Displays all symbols should be fine. Using the graphical display, you can test for bad substitutions or question-marks that would appear on character displays by defining SIMULATE_ROMFONT and trying the different variants.
If you get a lot of question marks on the Hitachi-based displays with your new translation, maybe creating an additional language file with the format language_xx_utf8.h is the way to go.
In this file specify the mapper (e.g., MAPPER_NON) and font (e.g., DISPLAY_CHARSET_ISO10646_1) and translate some of the strings defined in language_en.h. (Remove #ifndef #endif from the defines.)
If there’s no existing mapper for your language then things get a bit more complex. With the Hitachi-based displays you can’t make something useful without a matching charset. For graphical display… let’s take the example of Greek: Find a matching charset. (Greek and Coptic)
If you discover enough useful symbols in one of the HD44780 fonts you can provide a mapping table. For example WESTERN contains ‘alpha’, ‘beta’, ‘pi’, ‘Sigma’, ‘omega’ ‘My’ - which is not enough to make USEFUL table - I think.
If you want to integrate an entirely new variant of a Hitachi-based display. Add it to Configuration.h and define mapper tables in utf_mapper.h. You may need to add a new mapper function.
The length of strings (for menu titles, edit labels, etc.) is limited. “17 characters” was a crude rule of thumb. Obviously 17 is too long for a 16x2 display. So, language files are free to check the LCD width and provide shorter strings in the following manner:
On 16x2 displays, strings suited to a 20x4 display will be chopped to fit. So if shorter string isn’t provided, at least make similar strings different early in the string. (‘Someverylongoptionname x’ -> ‘x Somverylongoptionname’)
To find out which character set your hardware uses, set #define LCD_LANGUAGE test and compile Marlin. In the menu you’ll see two lines from the upper half of the character set: JAPANESE displays “バパヒビピフブプヘベペホボポマミ”
If you get an error message about “missing mappers” during compilation - lie about your display’s hardware font to see at least some garbage, or select another language.
LCD_LANGUAGE: The LCD language and encoding to compile in. For example, pt-br_utf8 specifies Portuguese (Brazil) in UTF-8 format with a mapper. For a faster, lighter, but non-accented translation you might choose pt-br instead.
SIMULATE_ROMFONT: Languages can opt to use the HD44780 ROM font special characters on graphical display. This method can be used for accented Western, Katakana, and Cyrillic if they don’t supply their own fonts, or just for testing character-based mappers on a graphical display.
DISPLAY_CHARSET_ISO10646_1: To support a graphical display, a language file must specify either SIMULATE_ROMFONT or a display character set. This specific option selects the Western font for use on graphical display. Others include ISO10646_5, ISO10646_KANA, ISO10646_GREEK, ISO10646_CN, ISO10646_TR, and ISO10646_PL. If no character set is specified, Marlin assumes ISO10646_1.
MAPPER_ONE_TO_ONE: Most character sets on graphical displays (including SIMULATE_ROMFONT) map the character index directly to its position in the upper half of the font. This is possible for character sets that have only 2 contiguous pages of Unicode containing all the special characters. Other mappers use logic or a lookup table to locate the glyph.