I2C Communication (PIC) with an 8-bit I/O Expander

Objectives

In this assignment, you will learn how to use I$^{\text{2}}$C serial communication on the PIC18F47Q10 Curiosity Nano and MCC. This will be critical for your semester project as every team has at least two serial peripherals (e.g., wifi module, serial sensor). To prepare you for the next homework assignment and your semester project, you will create an array of LEDs that will increment by one each time a button is pressed. You will use an 8-bit I/O expander IC that is used in situations when you run out of I/O pins on a microcontroller and cannot swap the microcontroller for one with more I/O pins.

With your partner, you must demonstrate proficiency in:

  1. Configuring MCC for an external I$^{\text{2}}$C device.

  2. Controlling an external I/O expander using I$^{\text{2}}$C.

Figure 1: Block Diagram

Bill of Materials

Item Quantity Value(s)
Breadboard 1
Jumper wires Many
Resistors 10 (7) 220Ω, (3) 10kΩ
LEDs 7
Push Button 1 SPST
Micro USB cable 1
Curiosity Nano 1 PIC18F47Q10 Curiosity Nano (datasheet)
MCP23008 (provided in class) 1 MCP23008 (datasheet)
Benchtop oscilloscope 1

Resources

Prior to Demonstration of Proficiency

  1. Read and search the Curiosity Nano datasheet and find the following:

    1. The recommended pins for I$^{\text{2}}$C communication.

    2. The 5V output pin on the Curiosity Nano.

  2. Wire your breadboard to match the schematic below:

    Figure 2: MCP23008 Serial I/O expander circuit schematic
    Figure 2: MCP23008 Serial I/O expander circuit schematic

  3. Next, you will configure a new project in MPLAB® X and add an I$^{\text{2}}$C serial component in MCC. Open MPLAB® X and create a new project

    1. Click Next >

      Figure
      Figure

    2. Select the PIC18F47Q10 as the Device, the Curiosity Nano as the Tool, and click Next >.

      (If this doesn’t show up, make sure that the Nano is plugged in.)

      Figure
      Figure

    3. Select the XC8 Compiler and click Next >

      Figure
      Figure

    4. Name the project and click Finish.

      Figure
      Figure

    5. Open MCC

      Please use MCC Classic. We can support it better, it has more advanced configuration options, but is also still relatively easy to use.

    6. Under Device Resources add “MSSP1”

    7. Select I2C in the Serial Protocol dropdown

      Figure
      Figure

  4. Open i2c1_master_example.h

    1. Find and note the two functions to read and write single bytes.
  5. Open the datasheet for the MCP23008

    1. Note that the slave address for this circuit will be 0x20 because pins A2, A1, and A0 are grounded (see Section 1.4 in the datasheet for more info)

    2. Find Table 1-2 in the datasheet and note the register addresses for IODIR and GPIO.

  6. In main.c:

    1. #include the i2c1_master_example.h

    2. In main(), use the I$^{\text{2}}$C write command you noted earlier to set bit IO7 in the IODIR register as a digital input (see page 9 of the MCP23008 datasheet).

    3. Create a variable named counter and initialize it to 1.

  7. In the while() loop:

    1. Use the I$^{\text{2}}$C read command you noted earlier to read the GPIO register in the I/O expander, and store the value read in a register.

    2. Next, bitmask this variable value to return the most significant bit (GP7) which is attached to the button. Store this value in a new variable.

      buttonValue = value & 0b10000000;
      
    3. Since the button is wired to output a logic 0 every time it is pressed, write an if() statement to check when the button is pressed. (Hint: When the button is pressed, the digital value will be equal to 0.)

      1. Within the if() statement, increment the counter variable.

      2. Within the if() statement, use the I$^{\text{2}}$C write command you noted earlier to write the lowest 7 bits of the counter variable to the GPIO register in the I/O expander.

Next, you will probe the serial lines with an oscilloscope and decode the serial signal. Note that while all of our oscilloscopes can be used to see serial signals, only the newer MSO-X oscilloscopes (with the dark front bezel) have serial decoding functionality.

  1. Connect two probes from the Agilent MSO-X oscilloscope to the SDA and SCL wires, respectively.

  2. Run the program on your PIC so that it continually polls the button to see if it has been pressed. This will generate a constant stream of I$^{\text{2}}$C traffic on SDA and SCL. Then, follow the example in this video to show the raw I$^{\text{2}}$C data on the oscilloscope screen, and also to use the Serial mode to decode the data into a hex byte.

  3. Finally, confirm that when you press the button that the binary pattern on the LEDs increments by 1. If it does not, use the serial data decoded in the previous step to debug your code.

Devices

Digital Multimeter Oscilloscope Power Supply
(Not Used Today) (Used Today) (Not Used Today)
Function Generator Waveform Generator Soldering Iron
(Not Used Today) (Not Used Today) (Not Used Today)

Probes

Oscilloscope Digital Multimeter Soldering Iron
(Used Today) (Not Used Today) (Not Used Today)