3.1 MCC Generated

To generate this project using MPLAB Code Configurator (MCC), 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 (default)
    • HF Internal Clock: 64 MHz (default)
    • 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 Drivers → I2C → I2CSIMPLE, then do the following configuration:
    • I2C_host dependency selector: MSSP1
  5. Go to Project Resources → Drivers → MSSP → MSSP1, then do the following configuration:
    • Interrupt Driven: Checked
    • Serial Protocol: I2C
    • Mode: Host
    • I2C Clock Frequency: 100000
  6. Go to the Pins Grid View, select UQFN40 in the MCU package field, and do the following pin configurations:
    Figure 3-3. Pin Mapping
  7. Go to Project Resources → System → Pin Module and set both pins, RB1 and RB2, to use the:
    • Internal pull-up, by checking the box in the Weak Pullup column
    • Open drain, by checking the box in the open drain column
    Ensure that for MSSP1, SCL is assigned to pin RB1 and SDA is assigned to RB2 in the pin manager grid view.
  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/system/system.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                   0xFF


/*
    Main application
*/

const i2c_host_interface_t *I2C = &i2c1_host_interface;

int main(void)
{
    SYSTEM_Initialize();
    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();

    uint8_t dataWrite[2];
    uint8_t dataRead[1];
    dataWrite[0] = MCP23008_REG_ADDR_IODIR;
    dataWrite[1] = PINS_DIGITAL_OUTPUT;
    if(I2C->Write(I2C_CLIENT_ADDR, dataWrite,2))
    {
        /* Bus is good */
        /* Delay is used as a placeholder for other actions */
        __delay_ms(2);
    }

    if(!I2C->IsBusy())
    {
        if(I2C1_ErrorGet() == I2C_ERROR_NONE)
        {
            /* Transfer is completed successfully */
        }
        else
        {
            /* Error occurred during transfer. */
        }
    }
 
    dataWrite[0] = MCP23008_REG_ADDR_GPIO;
    dataWrite[1] = MCP23008_DATA;
    while(1)
    {
        if(I2C->Write(I2C_CLIENT_ADDR, dataWrite,2))
        {
            /* Bus is good */
            /* Delay is used as a placeholder for other actions */
            __delay_ms(2);

        }
        if(!I2C->IsBusy())
        {
            if(I2C1_ErrorGet() == I2C_ERROR_NONE)
            {
                /* Transfer is completed successfully */
            }
            else
            {
                /* Error occurred during transfer. */
            }
        }

        if (I2C->Read(I2C_CLIENT_ADDR, dataRead,1))
        {
            /* Bus is good */
            /* Delay is used as a placeholder for other actions */
            __delay_ms(2);
        }
        if(!I2C->IsBusy())
        {
            if(I2C1_ErrorGet() == I2C_ERROR_NONE)
            {
                /* Transfer is completed successfully */
            }
            else
            {
                /* Error occurred during transfer. */
            }
        }
        dataWrite[1] = ~dataRead[0];
        __delay_ms(1000);
    }    
}