CPLD IO Detailed description.

LCD IO Interface description V1.0

 

The LCD interface is designed to control up to 3 LCD controllers at a time.

It has been tested with HD44780 based LCD controllers and HD62380 based

Graphics LCDs. In theory any other controller which takes up to 2 memory

addresses and uses Motorola R/W and E bus signals can be used.

 

The LCD controller bus has 8 bidirectional D7..D0 signals. There is a RS

signal which is used to select the register you want to read to write to.

There is a combined R/#W signal which controls where we want to read from or

write to the LCD controller. There is also the E (or strobe) signal. When

the strobe signal is low. The LCD controller does not interpret any of the

commands on the bus. When the signal goes high the command is executed.

 

The LCD Interface is implemented as several memory mapped registers.

      Register                              Address

      LCD_DATA_REG            0x600000 xxxx0000

      LCD_CTRL_REG             0x600001 xxxx0001

      LCD_STROBE1_REG      0x600006 xxxx0110

      LCD_STROBE2_REG      0x60000A xxxx1010

      LCD_STROBE3_REG      0x60000E xxxx1110

 

The LCD_DATA_REG register is used to read or write to the D7..D0 signals.

When you write to that register the CPLD will latch the data into an

internal register. The data will appear on the D7..D0 bus only if the R/#W

signal is in low state and one of the strobe signals is active otherwise the

CPLD will keep the D7..D0 in high impedance state. Note that the CPLD latches

the data in internal registers as part of the write operation. The data will

stay until overridden. You can output the same data multiple times, just by

flipping the E signal a few times.

 

When you read from the LCD_DATA_REG register the CPLD will output the data

from the LCD controller to the data bus of the MCU only when R/#W signal is

in high state and one of the strobes is active, otherwise the CPLD will keep

the MCU data bus in high impedance state, and you will read noise.

 

 

 

The LCD_CTRL_REG register controls the state of the RS and R/#W signals. The

RS signal is controlled by bit 0 of that register and the R/#W signal is

controlled by bit 1. All other bits are ignored.

 

When you write into the LCD_CTRL_REG the data is latched into internal

registers and the state of the RS and R/#W signals are changed accordingly.

When you read from the LCD_CTRL_REG register bit 0 and 1 will read the state

of the RS and R/#W signals respectively. Note that those signals are output

only, so the data read will be the same as whatever last you have written in

those bits.

 

 

 

The LCD_STROBEx_REG registers control the strobe signals for LCD1, LCD2 and

LCD3. To set the strobe signal to high, we must write 1 to the bits one and

two of the corresponding strobe register. To set the strobe signal to low, we

have to write 0 to the corresponding strobe register.

 

Note: Strobe signals are mutually exclusive, that is setting strobe for one

controller to high will automatically set the other two to low.

 

At reset, the state of the signals is as follows:

      RS    - low

      R/#W - low

      Ex    - low

      D7..D0      - high impedance

 

HD44780 communication examples:

 

example 1 - write 0x28 to the command register (RS=0) of LCD1

begin example 1

      write LCD_DATA_REG, 0x28 // the CPLD latches the data to

                         // internal register

      write LCD_CTRL_REG, 0    // R/W# = 0, RS = 0 (Write, Command Reg)

      write LCD_STROBE1_REG, 3 // enable strobe for LCD1

                         // at this point the latched data appears on

                         // D7..D0

      delay ~500 nS           // LCD controllers are notoriously slow

      write LCD_STROBE1_REG, 0 // clear the strobe, so we can process

                         // with the next command

end example1

 

example 2 - write 'A' to the data register (RS=1) of LCD2

begin example2

      write LCD_DATA_REG, 'A'  // CPLD latches the data

      write LCD_CTRL_REG, 1    // R/#W = 0, RS = 1 (Write, Data Reg)

      write LCD_STROBE2_REG, 3 // Set strobe for LCD2 to high

      delay ~500 nS

      write LCD_STROBE2_REG, 0 // Clear strobe

end example2

 

example 3 - read busy flag from LCD3 (read Command reg)

begin eample3

      write LCD_CTRL_REG, 2    // R/#W = 1, RS = 0 (Read, Command Reg)

      write LCD_STROBE3_REG, 3 // Set strobe to high

      delay ~500 nS           // wait for the LCD controller

      read  result, LCD_DATA_REG // read from LCD_DATA_REG will latch data

                           // from D7..D0

      write LCD_STROBE3_REG, 0 // clear strobe

      return (result & 0x80)   // Busy Flag is bit 7

end example3

 

example 4 - write ' ' 5 times to the Data register of LCD1, if your LCD is

set in auto increment mode, this will write 5 spaces from the current cursor

position

begin example4

        write LCD_DATA_REG, ' '

      write LCD_CTRL_REG, 1   // R/#W = 0, RS = 1 (Data reg)

      for(i=0; i < 5; i++)

      {

          write LCD_STROBE1_REG, 3  // We only flip the strobe

          delay ~500 nS       // since the data is already

          write LCD_STROBE1_REG, 0  // latched inside the CPLD

          delay ~450 nS

      }

end example4

 

Go Back