Springe zu Hauptinhalt

Springe zu Hauptmenü

Henryk Richter

LPH8731-3C LCD with ATMega

Driver for Siemens A62 display for ATMega

You are here: Startseite » Hardware » LPH8731 ATMega 
Initial breadboard setup


So here I am. After collecting old phones in my family I started identifying the displays in them. One phone, a Siemens A62 contained a display of the type LPH8731-3C. Supposedly, the display was also used in other models such as the M55 but YMMV as Siemens was in the habit of putting different LCDs into phones of the same model. I found some information, hints to the controller type and an AVR compatible driver on a russian forum. It could have ended at that point but I thought that the runtime performance and RAM consumption could be improved. The results of that process can be found in the following sections.

The software package includes the easy-to-use driver with rotation support and elementary pixel/text/graphics subroutines for 8 Bit graphics. The 12 bit mode is implemented but untested, though.

Furthermore, an image converter is provided that takes NetPBM images (pbm,pnm,ppm) as input and writes C header files. The image converter includes optional dithering (Ordered, Floyd-Steinberg, Burkes, Atkinson). I'd suggest to try the Burkes dithering. 

LCD Hardware

LPH8731-3C pinout

I found valuable information on the pinout and controller type of the LCD at http://lobotryasy.net/lph8731-3c.php. The site also offers source code for STM and Atmel MCUs.

The image of my LCD which I included here shows the LCD from the backside. Since the contact pads are comfortably big, I just soldered the 10 connections to the LCD itself. I chose the following connections to the Atmel for my experiments in software SPI mode:

  • 1. /CS (chip select), PD5
  • 2. RS (command=0,data=1) , PD6
  • 3. RES (reset), PD7
  • 4. CLK (serial clock), PB0
  • 5. DAT (serial data), PB1
  • 6. VDD 1.6 - 3.6V
  • 7. GND
  • 8. LED1+ (first LED anode, apply 240 Ohm resistor @ 5V)
  • 9. LED- (common cathode)
  • 9. LED2+ (second LED anode, apply 240 Ohm resistor @ 5V)

The used pins are of course configurable. As the display typically runs at 3V, a level converter might be necessary if the MCU is powered with 5V. I just applied 6.7k/10k resistors as voltage dividers on the pins 1-5.

There is one important point for the library I provided here. In order to use the fast software SPI (4 cycles/Bit), the CLK and DAT pins must be located on the same port. If that is not possible with a given project, a slow variant of the software SPI is also available in the code.


The resolution of the display is 101x80 in landscape orientation. It supports to basic color modes, 8 Bit and 12 Bit. In the former mode, the upper three bits of each pixel form the red channel, the next three bits are the green channel and the lower two bits address the blue channel. In the 12 Bit mode, each channel is addressed by 4 Bits. The drawback of the 12 Bit mode is that two adjacent pixels are to be mixed and written to the display (3 bytes per two pixels). I implemented the 12 bit mode but never really tested it. YMMV. In order to save memory, colors are specified as 8 Bit in 8 Bit mode and 16 Bit in 12 Bit mode as compile-time option (_LCD_8BIT). Color specifications conforming two both modes can be done with the LCD_RGB() macro. The macro takes red, green and blue channel data in 4 bit each and converts it to the correct output color for the active mode.

The display is configured from LPH8731-3C.h. The pin configuration for the Atmel consists of the used port (PORTA,PORTB,...), the respective data direction register and the pin on the port for each signal. In case that CLK and DATA are located on the same port, the directive LCD_PIN_CLKDATA should be defined with the read pin of the port used for these two. This signals that the fast software SPI may be used. If hardware SPI is desired instead, the define _LCD_SOFT_SPI should be disabled.

The runtime initialization call is LCD_init().The init sequence is scripted to reduce code size. The delays in the LCD init are chosen according to the data sheet.

The orientation of the display may be configured at runtime on-the-fly. It is implemtented so that the user doesn't need to worry about coordinate transformation. The display will be adjusted to a new upper left corner, depending on the argument of the LCD_Orientation() call. Every drawing command is conveniently relative to the orientation-dependent upper left corner. The only thing to be taken care of is to swap the maximum width/height constants in the 90 and 270 degree orientations (see LCD_FillScreen() in the C-File). It should be noted that orientation changes affect the pixel write direction registers only. Hence, different parts of the screen may be painted with differently oriented text and graphics.

Apart from usual functions like LCD_FillRect(), LCD_Putc(), LCD_Puts() and of course LCD_SetPixel(), image drawing routines are available. LCD_ShowImage() assumes the image to be located in flash memory. The other bulk drawing option available is LCD_ShowLine() which writes a row of pixels to the display from RAM (or a column with changed drawing orientation).

For the compilation, tree files are needed. These include the driver C implementation and associated header file plus the font (font_ascii_6x8.h in my case).

In terms of data/code size and performance, this driver not only needs way less memory than the other implementation(s) I've found so far -- but is also significantly faster.

Support software

Along with the driver, I've written a simple image converter that takes NetPBM images as input and writes Header-Files to be used with MCU implementations. The converter is a single-file C program without dependencies to external libraries. Consequently, it is not only cross-plattform capable but can easily be compiled without an IDE (e.g. gcc -o pnm2siemens pnm2siemens.c). NetPBM images can be written with a myriad of OpenSource software (gimp, ImageMagicK) as well as heavyweight programs like Adobe's Photoshop.

Calling the program without arguments lists the syntax.

In addition to basic conversion from Grayscale and RGB inputs to the 8 Bit palette of the Siemens display, I also implemented a number of dithering variants (arguments: -dither 0...6).

Example images are shown below (Hint: the #define DBG makes the program write the quantized/dithered image back as test_image.pnm.).

Ordered 2x2
Ordered 4x4



Controller Datasheet originating from Epson/Seiko corp.


ATMega LPH8731-3C Driver plus demo application

Demo Application

Initially, I wanted to write a real old-school intro for the display. Unfortunately, one other project came up where the display was needed for a real purpose. In the end, it fits nicely in a 1U rackmount enclosure.

So what was left of my initial experiments was compiled into a small video (embedded below). The first part of the video shows a redraw test in different orientations, where text and image are re-painted with each increment of the counter.

What follows are two classic effects: tunnel and rotozoom. Both were tested in Matlab, then re-written as MEX-File and when the results were satisfactory, I just dropped them on the Atmel. The effects can be switched via 9600 8N1 UART/RS232 interface, hotkeys: r,t,z.

Compilation: a Makefile for GNU make is included, assuming an available avr-gcc based toolchain. It is probably necessary to adjust the device and clock parameters for compilation (make) and programmer type (make flash).