Optrex DMC16207 LCD Driver
(Including Source Code)



Jessamyn Smith
CDMA Group
Dec 6, 2000


An LCD seems like a simple way to add visual appeal to a project. And it is, once you have the working source code in front of you. The early stages of development, however, involved a great deal of trial and error. Hopefully this application note can save others what I went through. This code has been designed specifically for the Optrex DMC16207 LCD, using the EPF10K20RC240-4 chip on the Altera UP1 board.

The LCD controller contains some control signals for the LCD and provides a slower clock (since the LCD has a relatively slow response time). This module is for demonstration purposes; when integrating an LCD into a project one would most likely interface directly with the driver. The controller is provided so that the LCD Driver may be tested independently. It instantiates the LCD driver and a clock divider as explained below.



Contents



Timing

The LCD is extremely sensitive to timing, particularly during initialization. The enable signal must be pulsed, since it acts as a clock to the LCD. Luckily, setting the enable signal to an inverted clock signal worked beautifully. This LCD driver assumes that a 2.5 kHz clock is being supplied. A simple clock divider, instantiated in the control module, was used to provide this from the Altera UP1 board, which has a 25MHz clock. While it is theoretically possible to read the busy flag (high data bit) of the LCD in order to determine when the next instruction may be executed, this design simply counts clock cycles to ensure enough time has passed since the last instruction. This avoided the special wiring necessary to work around the fact that the UP1 board (or at least Max+PlusII) does not allow tri-state pins. In our implementation we actually did have the high data bit wired so we could both set and read that bit. The bit is not used in this sample code, but does appear in the entity declaration. That line may be commented out if the high bit is only wired as an input. Using the busy flag would be a nice improvement to this code, since it would likely speed up the LCD module.



Initialization

The manufacturers specification sheets state that the LCD will automatically initialize if certain requirements are met when powering up the unit. I have yet to see that work, so this driver initializes manually. The sequence of instructions in the data sheet did not work either, so initialization was achieved by trial and error. The working sequence is as follows:

RSR/WData Time HeldPurpose
00000000007 cycles (2.8ms) Allow LCD time to warm up
000011000015 cycles (6ms) Set display to 1 line, 8 bit data interface
00000010001 cycle (0.4ms) Turn display off
00000000014 cycles (1.6ms) Clear display
00000001101 cycle (0.4ms) Set display to increment on write, no shift
00000011114 cycles (1.6ms) Move cursor to home position



Writing to a Specific Location

There is a shift command, which should let the user shift the entire display in order to write to a specific location on the screen. This proved rather difficult to implement, so this driver simply does a write cycle during which every location on the screen is rewritten. The static parts of the display are constants, while the input data is assigned directly to the desired location. A counter is started at zero and incremented each time through the write state. The location of the cursor is automatically updated after each write, and the data is determined from the current count. This is not a particularly elegant solution, but it does work dependably.



Updating the Screen on Change of Mode or Data

I had assumed that the LCD would overwrite whatever was on the screen during each write cycle, but this was not the case. In order to see updated data, it is necessary to clear the screen. The LCD is normally in idle mode, waiting for the data_valid line to be asserted. Once data_valid is set high, the write flag is set and the state is changed to clear. After clearing the display, the write flag is checked and the LCD begins writing (if high) or waiting (if low, from reset for example). This prevents the LCD from writing until there is data valid on the line. The mode line is monitored from the idle state; when a change is detected, the screen is cleared and rewritten. It is assumed that the data_valid line will be set high each time new valid data is available. It is expected that the data lines will be held steady from the time data_valid is asserted until the LCD sets done high.



VHDL Source Code

LCD driver The main LCD module. If the specifications on the control lines are followed and a 2.5 kHz clock is provided, this can easily be integrated into a project.
clock divider Provides an output clock with a period 10000 times the input clock.
 
LCD controller A sample controller. This is provided mainly for demonstration purposes. Compiling these three files and assigning appropriate pins should produce a working demo.



LCD Pin Assignments

PinFunction
1Ground
2Power supply (Vcc)
3Contrast power supply (hook to Vcc through a potentiometer so contrast can be adjusted)
4register select (1=data, 0=instruction)
5read(1)/write(0)
6enable (must be pulsed)
7-14data (LSB - MSB)