3.2 Foundation Services

To generate this project using Foundation Services (FS), follow the next steps:

  1. Create a new MPLAB X IDE project for PIC18F47Q10.
  2. Open MCC from the toolbar (more information on how to install the MCC plug-in can be found in the reference list).
  3. Go to Project Resources → System → System Module and do the following configuration:
    • Oscillator Select: HFINTOSC
    • HF Internal Clock: 64 MHz
    • Clock Divider: 1
    • In the Watchdog Timer Enable field in the WWDT tab, WDT Disabled has to be selected
    • In the Programming tab, Low-Voltage Programming Enable has to be checked
  4. From the Device Resources window, add I2CSIMPLE, then do the following configuration:
    • Select I2C Host: MSSP1
  5. Go to Device Resources → Peripherals → MSSP1, then check the Interrupt Driven box.
  6. Open the Pin Manager → Grid View window, select UQFN40 in the MCU package field and do the following pin configurations:
    Figure 3-4. Pin Mapping
  7. Go to Project Resources → Pin Module, and set both pins, RB1 and RB2, to use the internal pull-up by checking the box in the WPU column.
  8. In the Project Resources window, click the Generate button so that MCC will generate all the specified drivers and configurations.
  9. Edit the main.c file, as following:
#include "mcc_generated_files/mcc.h"

#define I2C_CLIENT_ADDR              0x20
#define MCP23008_REG_ADDR_IODIR     0x00
#define MCP23008_REG_ADDR_GPIO      0x09
#define PINS_DIGITAL_OUTPUT         0x00
#define MCP23008_DATA               0x0F

/*
                         Main application
 */
void main(void)
{
    // Initialize the device
    SYSTEM_Initialize();

    // Enable the Global Interrupts
    INTERRUPT_GlobalInterruptEnable();

    // Enable the Peripheral Interrupts
    INTERRUPT_PeripheralInterruptEnable();

    /* Set data to use in the I2C operations */
    uint8_t data = MCP23008_DATA;
    /* Set the extended pins as digital output */
    i2c_write1ByteRegister(I2C_CLIENT_ADDR, MCP23008_REG_ADDR_IODIR, PINS_DIGITAL_OUTPUT);
    
    while (1)
    {
        /* Write data to the GPIO port */
        i2c_write1ByteRegister(I2C_CLIENT_ADDR, MCP23008_REG_ADDR_GPIO, data);
        /* Read data from the GPIO port */
        data = i2c_read1ByteRegister(I2C_CLIENT_ADDR, MCP23008_REG_ADDR_GPIO);
        /* Overwrite data with the inverted data read */
        data = ~data;
        
        __delay_ms(500);
	}
}