Monday, December 1, 2014

Interfacing a MC122032B6W Graphic LCD

Sometime ago I bought a graphic LCD.I leaved it in  corner until I had time to test it. Now it is the time and I will post the low level interface details. In this case I have used an Arduino Leonardo because nothing beats the Arduino platform to get a program up and running in no time.

Advertisement image of the LCD

LCD Information Details

The LCD features 122 (horizontal) x 32 (vertical) dots. The interface uses 20 connections for data and power. So it is not a low pin count serial SPI LCD. We would need a lot of lines to make it work.

In the following figure I show with a red dot the origin position on the LCD below the pin #1.

0,0 coordinate on the LCD

To start working with the LCD we need its datasheet. It should include all the required information although, in this case it is not the case.
The following figure shows the LCD pinout on the datasheet.

LCD Pinout
Pins 1, 2 and 3 correspond to Vss, Vdd (5V) and the contrast adjustment V0. These pins follow the usual connections in Character LCDs:

Supply and Contrast
The backlight LED is associated to pins 19R and 20. Although the LCD board includes the LED current limiting resistor, I had found it to be too bright for indoor use, so I added a 150 Ohm resistor in series with the LED+ line before connecting to the 5V line.

A0 is used to select if the data sent goes to configuration "A0=Low" or data "A0=High". CS1 and CS2 are two chip enable signals. We need two because one driver chip alone is not able to drive all the screen points. It is important to note that the datasheet makes no indication that these lines are active LOW.

On pin 7 there is a Clock Input (CL) line were we must feed a 2kHz signal. I its a hassle needing to provide an external clock signal but that's how this LCD works.

The R/W signal determines if the data goes to the LCD (Write) or from the LCD (Read). This signal should be called R/W*, R/W# or something like that to indicate that "0" means Write and "1" means "Read". As with character LCDs, we don't need to use the read feature if we don't want to so we can connect this line to GND. That also prevents the potential destructive problems that we could have if we incorrectly try to write on the LCD when it is configured in read mode.

There are 8 data bits DB0 to DB7 because this is a parallel device where we write a Byte at a time.

Finally there is a RST ti reset the LCD. It is important to know that the use of this signal is very important to the operation of the LCD, something that the datasheet doesn't explain. To obtain the information associated to this signal we need to obtain the SED1520DAA driver chip datasheet.

Signal data on the SED1520DAA datasheet
We can see that the LCD can interface two kinds of MCUs, 68-series or 80-series. The kind of MCU that interfaces is determined bye the RES* signal. If it is a LOW pulse the 68-series communication is selected, if it is a HIGH pulse, a 80-series is selected.
Observe that the R/W only has separates Read from Write in 68 mode. In 80 mode the R/W signal acts as a WR* write enable strobe whereas the E signal acts as a RD* read enable strobe.

In our case we will use the 68-series mode so we must provide a proper reset signal (High level idle state with a low level reset pulse).

To send a Byte to the LCD we must:

  • Set A0 to "0" Command or "1" Data mode
  • Activate CS1 or CS2 at "0" to select te chip that we are adressing
  • Set R/W to "0" to set write mode
  • Send a positive pulse to E to send the data
In order to know the needed timings we can check the LCD datasheet:

We can see that is enough to have the E signal high during 80 ns to write the data to the LCD. As the data set up time is equal to the E pulse width and, as the data is captured when E falls, we could send the data at the same time that E goes high.
All in all we could operate with up to a 5MHz  (200ns) cycle time so, using an Arduino Leonardo and stock digitalWrite functions, it is difficult not to meet the correct timings.

Screen Layout

The screen layout is badly explained in the datasheet. This is bad beacuse in order to write graphical data on the LCD  we need proper information about the correspondence between the framebuffer memory and the screen. After some experiments I can confirm the following layout:

Screen Layout
There are two driver chips on the LCD board U1 and U2. U1, selected with a low CS1 signal, controls the left half of the screen (columns 0 to 60) and U2, selected with a low CS2 signal, controls the right half of the screen (columns 61 to 121).

Each chip features 240 Bytes of memory distributed in 4 pages of 80 Bytes. Each page is associated to 8 display rows. Page 0 goes from row 0 to row 7, page 2 goes from row 8 to row 15 and so on...
As there are only 61 columns associated to each chip, we only use 61 bytes in each page. We could use the  19 extra Bytes on each page as a temporal storage as those bytes are not shown on screen.
The LSB of the Bytes correspond to the lower row associated to the page, so, for instance, bit 0 of page 0 Bytes are associated to the first 0 row. A bit set will light white showing the backlight.

Writes feature an auto-increment, so to fill one page, we can select it and write all bytes from the first to the last column in order.

Test program

I have developed an TestGLCD sketch to test the LCD.

The setup function configures all pins and provides the 2kHz signal to the clock line using the tone function.

The loop function initializes and rewrites the LCD 20 times. In each iteration, the image is changed so we get some sort of diagonal lines animation.After the animation, there is a pause and the process repeats.

There are several commands associated to the possible Bytes we can write with the A0 signal at "0". I have included in the code some defines to give an easier access to those commands.
Any Byte sent while A0 is "1" will go to the current position on the frame buffer. After each write, the frame buffer position autoincrements.

Putting all together

To test the program I have connected an Arduino Leonardo to the LCD. As the interface is parallel there are a lot of wires to connect.

All the LCD connections
During the program loading the LCD shows some random lines but, after that, the program runs as it should.

Program Running

That's all for now. I'm not sure what will I make in the future with this LCD but I will probably write a C library file from the foundations of the test sketch.

Firmware on Github (11/02/2018)

This code is now on Github


  1. Have you by any chance written a C library already,
    im trying to get this screen to work on a stm32f4

  2. Not yet. But all the code is above and not much different from plain C.

  3. This comment has been removed by a blog administrator.

  4. Perfect!!! What I can say in this article is very important to be written as it may help everybody to get awareness. Good job done.
    OET for Nurses in Adelaide | oet in Adelaide