• PicŪ Basic

  • MCP23017 Port expander for LCD and Numeric Keypad

    A current project for a PIC18F2480 repeater controller required an LCD display and a numeric keypad to enter values while on site.

    Although I had a PCF8574 8 bit LCD display working nicely thanks to examples by numerous contributors on this site, especially Towlerg and Barak, this still left insufficient ports to add a keypad.

    The MCP23017 is an I2C 16 bit port expander which seemed ideal, it's cheap and readily available. Port A for the LCD and Port B for the keypad. The 16 bit chip is, however, much more complex to use than the PCF8574 as a number of registers need setting to get things just right. It is essential that you become familiar with the MCP23017 datasheet. The register addresses on page 5 and page 9 are helpful as are the descriptions of the registers later in the document.

    So beginning with George's latest tried and proven PCF8574 program (see Post 146 here) I added the necessary initialisation of registers for the MCP23017. I also inserted the correct register address in each of the HBusout statements.

    I won't go into the dozens of experiments (I'm a slow learner) to get things right. Initially I used IOCON.BANK1 but had conflicting results. In the end BANK0 was the way to go and things fell into place with register addresses working as they should.

    The essential difference between the 8 bit device and the 16 bit device is that the latter device has registers that need to be set correctly. Though it does mean that the 16 bit chip is quite flexible. In the case of the keypad it was necessary to set up 4 bits as outputs and 4 bits as inputs. Weak pullups on the inputs enabled 4 resistors to be omitted, although a small software change was necessary to re-arrange the input data when interpreting the button pushes. I'm sure my key routine could be made more efficient but that's not the real purpose of this article.

    Writes are made to the LAT registers (OLATA and OLATB) while reads are made directly from the B port (GPIOB). As long as the direction register (GPPUB) is properly set there are no conflicts between read and write actions. Look at the two include files to get an idea of how it works. A "PrintInit" sub routine is called from the main program to get things going, although it could be called in the I2CPrintHardCommand.inc file at the end of the file just after the label "I2CPrintCommand_End:". I need to control this in my larger program hence it's in the main file.

    You have probably noticed that I used the decimal equivalent in the register addresses (e.g. 19 instead of $13). No real reason for this, just habit.

    Pin connections for the standard 1602 LCD are:
    Port A         LCD
    21             R/S    
    22             NC
    23             Enable
    24             NC
    25             Data 4
    26             Data 5
    27             Data 6
    28             Data 7
    The LCD needs power, contrast control and R/W taken to ground although pin 24 of the expander does have a low that could be used for this.

    For the Keypad the connections are:
    Port B           Keypad
    1    inputs        8    row 4   (1k resistor between the two pins)
    2                  7    row 3   (1k resistor between the two pins)
    3                  6    row 2   (1k resistor between the two pins)
    4                  5    row 1   (1k resistor between the two pins)
    5    outputs       4    column 1 no resistors on the output side
    6                  3    column 2
    7                  2    column 3
    8                  1    column 4
    That's pretty well it. Thanks to the many people who offered suggestions in the forum. One of the important tricks was to add a CLEAR to the I2C routines. It doesn't work without that. I imagine almost any device with I2C hardware would run this project providing the configs were appropriately set.

    I've attached a zip with three files, the BAS and two INC. For further information check out Towlerg's article on a bit banged approach.

    MCP23017 menu and print.zip

    Projects grow in 3 dimensions in my ham shack