PICAXE Two-Wire LCD Interfacing

IMPORTANT WARNING

The designs on this page are presented "as is" with no warranty or guarantee of operational correctness. The electronic design has not been built, tested nor proven, and there is no guarantee that the designs are sound or that damage will not occur when used with your own equipment. The software has not been tested, debugged and may not include the functionality described in this article. Anyone using the hardware and software designs or information related to them herein does so entirely at their own risk. No liability whatsoever is accepted by the author.

This project is a theoretical exercise and a work in progress and should be considered as an educational resource rather than as a completed or functional project.



The simple Two-Wire LCD Interface offers a low-cost compromise between a parallel LCD interface which ties up processor output lines and the use of an expensive Serial LCD.



Interfacing to an LCD consumes quite a few output lines even when operating the LCD in 4-bit mode. When there aren't enough output lines available to use, a one-wire Serial Interface LCD can be used, but their costs are prohibitive. A reasonable alternative is to use a readily available logic IC and just two output lines.

The code detailed here has been specifically written for the PICAXE and targeted at LCD's which use the Hitachi HD44780 driver chips, which is by far the great majority of LCD's which I have encountered.

Note that the code will not work with 4 x 40 LCD's because they are internally constructed from two 2 x 20 controllers and require an additional control line, although the unused Q1 output of the 74LS164 can be used to control two E lines required by a 4 x 40 LCD. This is a design change that is beyond the scope of this document.

The program code has been highly optimised, requiring just four dedicated byte variables and uses just 85 bytes of program code space. The code is designed for use with all PICAXE variants, although it is best used with the PICAXE-08M, 18A, 28 or 28A and is most suited for use with the PICAXE-18X, 28X and 40X with their larger program memory capacities and extended subroutine capabilities.


Index

The Two-Wire Interface
The Two-Wire Interface Circuit
The Two-Wire Protocol
The Two-Wire Interface Software
The Three-Wire Interface
The Three-Wire Protocol
The Three-Wire Interface Software


The Two-Wire Interface

The design here is inspired by Myke Predko's 2-Wire LCD Interface but that design is improved upon to give proper timing control for data stabilisation before pulsing the LCD "E" signal, and uses a more commonly available component.

This is the minimal for LCD interfacing without going to a serially controlled LCD, and is considerably cheaper than purchasing a dedicated Serial LCD or using a PICAXE or PICmicro to perform that task, but the penalty in a low cost solution is an increase in time taken in updating the LCD, however, this can be offset by moving to a Three-Wire LCD Interface described later. In many cases, the simplicity and low cost of these solutions far outweigh their disadvantages.


The Two-Wire Interface Circuit

Mike's circuit uses a 74LS174 which is no longer easily obtainable ( ie, Maplins Electronics in the UK doesn't stock it ), so this is a re-design using the 74LS164 8-stage serial to parallel converter.

+5V --------------.---------------------.---.------.
                  |                     |   |      |   1N914
          .-------|---------------------|---|------|-----.-----.
         .|.      |                     |   |      |     |     |
         | | 1K0  |       74LS164       |   |      |    _|_    |          LCD
         |_|      |   .-----..------.   |   |      |   _\ /_   |      .---------.
          |       `---| 1 Da  +V 14 |---{   |      |     |     |      |         |
DAT >-----^-----------| 2 Db  Q7 13 |---|---|------|-----'     |    .-^--.      |
                      | 3 Q0  Q6 12 |---|---|------|-----------|--->| 14 | DB7  |
                      | 4 Q1  Q5 11 |---|---|------|-----------|--->| 13 | DB6  |
              .-------| 5 Q2  Q4 10 |---|---|------|-----------|--->| 12 | DB5  |
              |   .---| 6 Q3 /MR  9 |---'   |      |     .-----|--->| 11 | DB4  |
          .---|---|---| 7 0V  CP  8 |---.   |      |     |     |    | 10 | DB3  |
          |   |   |   `-------------'   |   |      |     |     |    |  9 | DB2  |
CLK >-----|---|---|---------------------'   |      |     |     |    |  8 | DB1  |
          |   |   `-------------------------|------|-----'     |    |  7 | DB0  |
          |   `-----------------------------|------|-----.     `--->|  6 | E    |
          |                                .|.     |     |     .--->|  5 | /WR  |
          |                           10K  | |<-.  |     `-----|--->|  4 | RS   |
          |                           Pot  |_|  `--|-----------|--->|  3 | Vo   |
          |                                 |      `-----------|--->|  2 | Vcc  |
0V -------^---------------------------------^------------------^--->|  1 | Vdd  |
                                                                    `-.--'      |
                          100nF Power Supply                          |         |
                         decoupling not shown                         `---------'

The key to the circuit's simplicity is the 'AND Gate' formed between the DAT signal from the PICAXE and the Q7 output from the 74LS164. It is a clever technique from Electronics Now magazine which saves the need for a single AND gate.

When either DAT or Q7 are low, the E signal to the LCD is kept low. This allows the shift register to be cleared by keeping DAT low during eight clock pulses. When clocking LCD controlling data into the 74LS164, the low Q7 will keep E low regardless of DAT, and the E pulse for the LCD will only occur when Q7 is high and DAT is high. This is achieved by clocking a '1' into the 74LS164 as the first bit after clearing and by pulsing the DAT line after the transfer has been completed.

The 1N914 diode is used to pull E down when Q7 is low ( clamping E when DAT is high to about 0.7V, below the logic high threshold of the LCD input ) and can probably be any high-speed switching diode, although any small-signal diode such as a 1N4148 may work ( but is an untested theory ). The 1K0 resistor is to limit the current to below 5mA ( at 5V ) when the DAT line is high and Q7 is low. It is recommended that the DAT line is kept low whenever possible to minimise current consumption.

It may be possible to replace the 74LS168 with a 74HC168 or 74HCT168, but that is also an untested theory.


The Two-Wire Protocol

                                         .----.----.----.----.----.----.----.      .---.
DAT                                      |    | D7 | D6 | D5 | D4 | RS | ?? |      |   |
      -----------------------------------'    `----^----^----^----^----^----^------'   `---
                                                                                   :   :
          1   2   3   4   5   6   7   8    9   10   11   12   13   14   15   16    :   :
         .-. .-. .-. .-. .-. .-. .-. .-.  .-.  .-.  .-.  .-.  .-.  .-.  .-.  .-.   :   :
CLK      | | | | | | | | | | | | | | | |  | |  | |  | |  | |  | |  | |  | |  | |   :   :
      ---' `-' `-' `-' `-' `-' `-' `-' `--' `--' `--' `--' `--' `--' `--' `--' `-----------
                                     :                                       :     :   :
      ---.---.---.---.---.---.---.---.                                       .-------------
Q7       |   |   |   |   |   |   |   |                                       |     :   :
      ---^---^---^---^---^---^---^---^---------------------------------------'     :   :
                                                                                   .---.
E                                                                                  |   |
      -----------------------------------------------------------------------------'   `---


Q7          -   -   -   -   -   -   -   0    0    0    0    0    0    0    0    1
Q6          -   -   -   -   -   -   0   0    0    0    0    0    0    0    1    D7
Q5          -   -   -   -   -   0   0   0    0    0    0    0    0    1    D7   D6
Q4          -   -   -   -   0   0   0   0    0    0    0    0    1    D7   D6   D5
Q3          -   -   -   0   0   0   0   0    0    0    0    1    D7   D6   D5   D4
Q2          -   -   0   0   0   0   0   0    0    0    1    D7   D6   D5   D4   RS
Q1          -   0   0   0   0   0   0   0    0    1    D7   D6   D5   D4   RS   ??
Q0          0   0   0   0   0   0   0   0    1    D7   D6   D5   D4   RS   ??   0

Clearing the 74LS164 is achieved by setting DAT low (0) and sending eight high going CLK pulses.

DAT is then set high (1) and a further CLK pulse is issued, followed by the data bits for DB7, DB6, DB5, DB4 and RS each with their own CLK pulses.

A further CLK pulse must be issued ( the state of the DAT line does not matter during this CLK pulse ), followed by a final CLK pulse with DAT set low.

After the transfer is completed, DAT must be set high to active E and then brought low to clear E. The DAT line must then remain low until the 74LS164 has been cleared ( by issuing eight CLK pulses with DAT low ).

Note that by clearing the 74LS164 at Power-On Reset ( eight CLK pulses with DAT low ), and ensuring that DAT is low when the two CLK pulses following the sending of the RS data bit are issued, it is possible to send just six pulses to guarantee that the 74LS164 will be cleared. This will give a slight speed improvement to every transfer of data to the 74LS164.

By tracking what's been clocked into the 74LS164 it is also possible to minimise the number of CLK pulses required to perform a clear and to set the data transfer value, however, the time taken to perform such an optimisation probably outweighs delivering all clock pulses regardless on a PICAXE.


The Two-Wire Interface Software

There are three routines which are used to initialise and control the LCD ...

        GOSUB InitialiseLcd     ; Initialise the LCD

        byte = ...              ; Send byte to LCD Data Register
        GOSUB SendDataByte

        byte = ...              ; Send byte to LCD Command Register
        GOSUB SendCmdByte

The 'InitialiseLcd' routine must be called once, at the start of the program.

The 'SendDataByte' and 'SendCmdByte' routines are used to send data bytes to the LCD data and command registers respectively. This allows data to be displayed on the LCD and the cursor and other attributes of the LCD and its display to be altered. Before calling either of the two routines, the data byte to be sent must be placed in the 'byte' variable. The value put into the 'byte' variable is not changed when the routines are called.

For a more comprehensive review of how to use the routines, please see the article on interfacing LCD's to a PICAXE in the more traditional parallel manner. The user callable routines presented here are compatible with software that uses that design.

  PICAXE LCD Interfacing

The code requires five variables to be defined ...

        SYMBOL  get       = b9
        SYMBOL  byte      = b10
        SYMBOL  dataOut   = b11
        SYMBOL  bitNumber = b12
        SYMBOL  rsbit     = b13

Note that the 'get' variable is only used within the 'InitialiseLcd' routine and therefore 'b9' can be re-used with your own program after the LCD has been initialised.

The 'byte', 'dataOut' and 'bitNumber' variables are only used in the 'InitialiseLcd', 'SendDataByte' and 'SendCommandByte' routines, and therefore 'b10', 'b11', 'b12' and 'w5' can be re-used within your own program, although they will have their values changed when any of these routines are called.

The 'rsbit' variable must be preserved intact during the operation of the program and so 'b13' ( and consequently 'w6' ) must not be used by your own code unless placed somewhere else and restored after use.

The code uses 'SYMBOL DAT_PIN = pinN' to optimise the code ( where N is the number used in the 'SYMBOL DAT = N' definition ), but due to a limitation of the compiler this means that only certain pins can be used for connection to a PICAXE ...

    Variant                         DAT pin allowed

    PICAXE 08 or 08M                1, 2 or 4

    PICAXE 18, 18A and 18X          0, 1, 2, 6 or 7

    PICAXE 28, 28A, 28X and 40X     Any pin

The CLK line can be connected to any PICAXE Digital Output pin. For maximum code size optimisation it is recommended that DAT and CLK are connected to pins 0 and 1, which line connects to which pin is not important ...

    Variant                         DAT pin     CLK pin

    PICAXE 08 or 08M                1           0

    PICAXE 18, 18A and 18X          1 or 0      0 or 1

    PICAXE 28, 28A, 28X and 40X     1 or 0      0 or 1

For ease of using the code on a variety of PICAXE processors, it is recommended that the DAT line is connected to Output Pin 1 and the CLK line is connected to Output Pin 0.

The complete program for controlling a HD4470 based LCD through a 74LS168, exclusing the User Program code, is given below, The code uses the recommended connection pins for the DAT and CLK lines, and the SYMBOL definitions for DAT, CLK and DAT_PIN will need to be changed if you choose to use alternative pins.

        SYMBOL DAT              = 1         ; Pin number of DAT line
        SYMBOL CLK              = 0         ; Pin number of CLK line

        SYMBOL DAT_PIN          = pin1      ; Pin number of DAT line

        SYMBOL CLK_PULSE_LENGTH = 1         ; 10uS
        SYMBOL E_PULSE_LENGTH   = 1         ; 10uS

        SYMBOL RSCMDmask        = %00000000 ; Select Command register
        SYMBOL RSDATmask        = %00001000 ; Select Data register

        SYMBOL  get             = b9
        SYMBOL  byte            = b10
        SYMBOL  dataOut         = b11
        SYMBOL  bitNumber       = b12
        SYMBOL  rsbit           = b13

    PowerOnReset:

        GOSUB InitialiseLcd

        ; User Program Here

        END

    InitialiseLcd:

        FOR get = 0 TO 5
          READ get,byte
          GOSUB SendInitCmdByte
        NEXT

        ' Nibble commands - To initialise 4-bit mode

        EEPROM 0,( $33 )    ; %001?---- %001L----   Display Format
        EEPROM 1,( $32 )

        ' Byte commands - To configure the LCD

        EEPROM 2,( $28 )    ; %00101000 %001LNF00   Display Format
        EEPROM 3,( $0C )    ; %00001100 %00001DCB   Display On
        EEPROM 4,( $06 )    ; %00000110 %000001IS   Cursor Move

                            ; L : 0 = 4-bit Mode    1 = 8-bit Mode
                            ; N : 0 = 1 Line        1 = 2 Lines
                            ; F : 0 = 5x7 Pixels    1 = N/A
                            ; D : 0 = Display Off   1 = Display On
                            ; C : 0 = Cursor Off    1 = Cursor On
                            ; B : 0 = Cursor Steady 1 = Cursor Flash
                            ; I : 0 = Dec Cursor    1 = Inc Cursor
                            ; S : 0 = Cursor Move   1 = Display Shift

        EEPROM 5,( $01 )    ; Clear Screen

        RETURN

    SendInitCmdByte:

        PAUSE 15                        ; Delay 15mS

    SendCmdByte:

        rsbit = RSCMDmask               ; Send to Command register

    SendDataByte:

        dataOut = byte & %11110000 | rsbit
        GOSUB TransferTo74LS164
        dataOut = byte * %00010000 | rsbit
        GOSUB TransferTo74LS164

        rsbit = RSDATmask               ; Send to Data register next

        RETURN

    TransferTo74LS164:

        LOW DAT                         ; Clear 74LS164
        FOR bitNumber = 0 TO 7
          PULSOUT CLK,CLK_PULSE_LENGTH
        NEXT

        HIGH DAT                        ; Transfer data
        PULSOUT CLK,CLK_PULSE_LENGTH
        FOR bitNumber = 0 TO 6
          DAT_PIN = dataOut / $80
          PULSOUT CLK,CLK_PULSE_LENGTH
          dataOut = dataOut * 2
        NEXT

        PULSOUT DAT,E_PULSE_LENGTH      ; Pulse E

        RETURN                          ; Completed transfer

If you need the absolutely minimum code size and are prepared to have any data held in the 'w0' variable altered when the LCD routines are called, and accept that the execution time will increase, then the 'TransferTo74LS164' routine can be replaced with the code below, which saves 6 bytes of code space ...

    TransferTo74LS164:

        w0 = dataOut / 2 | $80          ; Format data

        FOR bitNumber = 0 TO 15         ; Clear and transfer data
          DAT_PIN = bit15
          PULSOUT CLK,CLK_PULSE_LENGTH
          w0 = w0 * 2
        NEXT

        PULSOUT DAT,E_PULSE_LENGTH      ; Pulse E

        RETURN                          ; Completed transfer


The Three-Wire Interface

The three-wire interface circuit is the same as the Two-Wire Interface Circuit except that the Memory Reset pin of the 74LS164 ( /MR ) is not connected to +5V, but is driven from a PICAXE Digital Output, CLR. This speeds up LCD updating because it is no longer necessary to use eight clock pulses to clear the 74LS164 before every LCD control byte is sent.

If you are planning to build either a two-wire or three-wire LCD interface on a breadboard, veroboard ( stripboard ) or as a PCB, it would probably make sense to use a three pin molex connector and a link so /MR can either connect to an external CLR line for three-wire use, or to +5V for two-wire use.


The Three-Wire Protocol

      ---. .---------------------------------------------------
CLR      | |
         `-'
         :    .----.----.----.----.----.----.----.     .---.
DAT      :    |    | D7 | D6 | D5 | D4 | RS | ?? |     |   |
      --------'    `----^----^----^----^----^----^-----'   `---
         :                                             :   :
         :      1    2    3    4    5    6    7    8   :   :
         :     .-.  .-.  .-.  .-.  .-.  .-.  .-.  .-.  :   :
CLK      :     | |  | |  | |  | |  | |  | |  | |  | |  :   :
      ---------' `--' `--' `--' `--' `--' `--' `--' `----------
         :                                        :    :   :
      ---.                                        .------------
Q7       |                                        |    :   :
         `----------------------------------------'    :   :
                                                       .---.
E                                                      |   |
      -------------------------------------------------'   `---

Q7        0       0    0    0    0    0    0    0    1
Q6        0       0    0    0    0    0    0    1    D7
Q5        0       0    0    0    0    0    1    D7   D6
Q4        0       0    0    0    0    1    D7   D6   D5
Q3        0       0    0    0    1    D7   D6   D5   D4
Q2        0       0    0    1    D7   D6   D5   D4   RS
Q1        0       0    1    D7   D6   D5   D4   RS   ??
Q0        0       1    D7   D6   D5   D4   RS   ??   0

Clearing the 74LS164 is achieved by sending a low going CLR pulse. The state of the DAT line does not matter at this time.

DAT is then set high (1) and a further CLK pulse is issued, followed by the data bits for DB7, DB6, DB5, DB4 and RS each with their own CLK pulses.

A further CLK pulse must be issued ( the state of the DAT line does not matter during this CLK pulse ), followed by a final CLK pulse with DAT set low.

After the transfer is completed, DAT must be set high to active E and then brought low to clear E. The DAT line must then remain low until the 74LS164 has been cleared.

Providing the CLR line is kept high by the PICAXE ( or wired to +V ), the code used to control the two-wire interface can be used with the three-wire interface without change, but the code will run slower than that designed for the three-wire interface.


The Three-Wire Interface Software

The software used for the three-wire interface is the same as the Two-Wire Interface Software with two changes.

The following constant definitions must be added at the start of the source code ...

        SYMBOL CLR              = ?     ; Pin number of CLR line
        SYMBOL CLR_PULSE_LENGTH = 1     ; 10uS

The CLR line can be connected to any PICAXE Digital Output pin.

The 'TransferTo74LS164' routine needs to be replaced with the following code ...

    TransferTo74LS164:

        PULSOUT CLR,CLR_PULSE_LENGTH    ; Clear 74LS164

        HIGH DAT                        ; Transfer data
        PULSOUT CLK,CLK_PULSE_LENGTH
        FOR bitNumber = 0 TO 6
          DAT_PIN = dataOut / $80
          PULSOUT CLK,CLK_PULSE_LENGTH
          dataOut = dataOut * 2
        NEXT

        PULSOUT DAT,E_PULSE_LENGTH      ; Pulse E

        RETURN                          ; Completed transfer


PICAXE is a trademark of Revolution Education Ltd. PICmicro is a registered trademark of Microchip Inc.





Associated Articles

  The PICAXE Processors
  PICAXE News
  PICAXE Questions & Answers
  PICAXE Comparisons
  PICAXE Pinouts
  PICAXE Serial Interfacing
  PICAXE Infra-Red Interfacing
  PICAXE Wireless Interfacing
  PICAXE LCD Interfacing
  A Real-Time Clock for the PICAXE-18X
  PICAXE Optimisations
  The PICAXE Birthday Box Project
  PICAXE Telephone Exchange Simulator
  The Brainf**ked PICAXE
  The PICAXE Extended Programming Interpreter
  Build Your Own Basic Stamp
  Tech Toys



Sites to Visit

  PICAXE Home Page
  Revolution Education Ltd

  Tech-Supplies Ltd



Site Navigation

  Home Page
  What's New
  Search
  Add Bookmark
  Have Your Say
  Guestbook




First published on Friday the 6th of August, 2004 at 04:37:18
Last upload was on Wednesday the 3rd of November, 2004 at 12:59:13