LAUNCHXL-F280049C: LCD I2C Interfacing

Part Number: LAUNCHXL-F280049C
Other Parts Discussed in Thread: PCF8574, C2000WARE

Tool/software:

I am trying to interface an I2C LCD with the TI launch pad. Several attempts were made using examples but nothing seems to be working. Please see my code and guide me. I am a beginner in this domain.  I couldn't even do LCD back light  off and on.

#include "driverlib.h"
#include "device.h"
#include "i2c.h"
#include "i2cLib_FIFO_polling.h"

// LCD and I2C definitions
#define SLAVE_ADDR 0x27 // Common address for PCF8574 I2C LCD backpack
#define LCD_BACKLIGHT 0x08 // Backlight control bit
#define ENABLE 0x04 // Enable bit
#define RS_DATA 0x01 // Register select bit for data
#define RS_COMMAND 0x00 // Register select bit for command

// Global variables
uint16_t AvailableI2C_slaves[20];
uint16_t status;

// Function prototypes
void I2C_GPIO_init(void);
void I2Cinit(void);
void I2C_sendByte(uint16_t data);
void lcd_backlightOn(void);
void lcd_backlightOff(void);
void delay_us(uint32_t us);

void main(void)
{
// Initialize device clock and peripherals
Device_init();

// Disable pin locks and enable internal pullups
Device_initGPIO();

// Initialize I2C pins
I2C_GPIO_init();

// Initialize PIE and clear PIE registers. Disable CPU interrupts
Interrupt_initModule();

// Initialize the PIE vector table
Interrupt_initVectorTable();

// Initialize I2C peripheral
I2Cinit();

// Optional: Scan I2C bus
uint16_t *pAvailableI2C_slaves = AvailableI2C_slaves;
status = I2CBusScan(I2CA_BASE, pAvailableI2C_slaves);

// Main loop: blink backlight ON and OFF every 1 second
while (1)
{
lcd_backlightOn();
DEVICE_DELAY_US(1000000); // 1 second delay

lcd_backlightOff();
DEVICE_DELAY_US(1000000); // 1 second delay
}
}

void I2C_GPIO_init(void)
{
GPIO_setDirectionMode(35U, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(35U, GPIO_PIN_TYPE_PULLUP);
GPIO_setQualificationMode(35U, GPIO_QUAL_ASYNC);

GPIO_setDirectionMode(37U, GPIO_DIR_MODE_IN);
GPIO_setPadConfig(37U, GPIO_PIN_TYPE_PULLUP);
GPIO_setQualificationMode(37U, GPIO_QUAL_ASYNC);

GPIO_setPinConfig(GPIO_35_I2CA_SDA);
GPIO_setPinConfig(GPIO_37_I2CA_SCL);
}

void I2Cinit(void)
{
I2C_disableModule(I2CA_BASE);
I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 100000, I2C_DUTYCYCLE_50);
I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDR);
I2C_setOwnSlaveAddress(I2CA_BASE, 96);
I2C_disableLoopback(I2CA_BASE);
I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);
I2C_setDataCount(I2CA_BASE, 1);
I2C_setAddressMode(I2CA_BASE, I2C_ADDR_MODE_7BITS);
I2C_enableFIFO(I2CA_BASE);
I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
I2C_setFIFOInterruptLevel(I2CA_BASE, I2C_FIFO_TXEMPTY, I2C_FIFO_RX2);
I2C_enableInterrupt(I2CA_BASE, I2C_INT_ADDR_SLAVE | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);
I2C_enableModule(I2CA_BASE);
}

void I2C_sendByte(uint16_t data)
{
while (I2C_isBusBusy(I2CA_BASE)); // Wait for bus to be free

I2C_setDataCount(I2CA_BASE, 1); // Send one byte
I2C_putData(I2CA_BASE, data); // Put data in TX FIFO
I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
I2C_sendStartCondition(I2CA_BASE); // START

while (I2C_getStatus(I2CA_BASE) & I2C_STS_BUS_BUSY); // Wait for transmission

if (I2C_getStatus(I2CA_BASE) & (I2C_STS_NO_ACK | I2C_STS_ARB_LOST))
{
I2C_clearStatus(I2CA_BASE, I2C_STS_NO_ACK | I2C_STS_ARB_LOST);
}

I2C_sendStopCondition(I2CA_BASE); // STOP
while (I2C_isBusBusy(I2CA_BASE)); // Wait for bus to clear

delay_us(50); // Small delay
}

void lcd_backlightOn(void)
{
// Send dummy data with backlight ON
I2C_sendByte(0x00 | LCD_BACKLIGHT | ENABLE);
delay_us(1);
I2C_sendByte(0x00 | LCD_BACKLIGHT); // EN low
}

void lcd_backlightOff(void)
{
// Send dummy data with backlight OFF
I2C_sendByte(0x00 | ENABLE); // EN high
delay_us(1);
I2C_sendByte(0x00); // EN low, backlight off
}
void delay_us(uint32_t us)
{
DEVICE_DELAY_US(us);
}

Please help

  • Hi T,

    While I cannot review the code, I can help answer any specific questions you may have. As a starting point, please use the C2000WARE I2C examples to verify your SW I2C and GPIO configurations and application code. I am not familiar with this specific LCD, but please make sure the physical connections match the datasheet of both devices.

    Best Regards,

    Aishwarya

  • I have tried to see the SCL line with LCD data and without LCD data...when using loop back it is able to generate the CLK which can be seen on DSO and when LCD data is transmitted it is not getting reflected. I need some help or link to I2C LCD interfacing with F280049C

  • T,

    We do not have any examples to specifically interface with LCD but we have I2C EEPROM examples that can be modified for your use. Quick Google search shows me resources of how to use C2000 with LCD. Here are a few resources (I2C is similar across Gen 3 MCUs):

    CCS/TMS320F28379D: I2c communicate with a LCD display (PCF8574)

    Best Regards,

    Aishwarya

  • Thanks a lot. The shared thread is very useful and finally I could send data to LCD display. Please find the complete working code here.

    //#############################################################################

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "lcd_i2c.h"
    #include "i2cLib_FIFO_polling.h"

    //
    // Globals
    //
    #define I2C_SLAVE_ADDR 0x27
    #define I2C_NUMBYTES 1

    uint16_t delay;
    uint16_t connt = 35;
    uint16_t ten, unit;

    // Converts digit to ASCII
    uint16_t convert(uint16_t a) {
    return a + '0';
    }

    // Splits number into tens and units
    void dec_unid_convert(uint16_t a) {
    ten = a / 10;
    unit = a % 10;
    }

    // Microsecond delay
    void usDelay(uint32_t count) {
    DEVICE_DELAY_US(count);
    }

    // Sends one byte of data to LCD via I2C
    void I2C_out(uint16_t data) {
    I2C_setSlaveAddress(I2CA_BASE, I2C_SLAVE_ADDR);
    I2C_putData(I2CA_BASE, data);
    I2C_sendStartCondition(I2CA_BASE);
    while(!I2C_isBusBusy(I2CA_BASE));
    I2C_sendStopCondition(I2CA_BASE);
    usDelay(2000);
    }

    void LCD_command(uint16_t cmd) {
    uint16_t upper = (cmd & 0xF0);
    uint16_t lower = ((cmd << 4) & 0xF0);

    I2C_out(upper | 0x0C);
    I2C_out(upper | 0x08);
    I2C_out(lower | 0x0C);
    I2C_out(lower | 0x08);
    }

    void LCD_write(uint16_t val) {
    uint16_t upper = (val & 0xF0);
    uint16_t lower = ((val << 4) & 0xF0);

    I2C_out(upper | 0x0D);
    I2C_out(upper | 0x09);
    I2C_out(lower | 0x0D);
    I2C_out(lower | 0x09);
    }

    void LCD_setCursor(uint16_t row, uint16_t col) {
    uint16_t addr = (row == 0) ? (0x80 + col) : (0xC0 + col);
    LCD_command(addr);
    }

    void init_LCD() {
    usDelay(50000);
    LCD_command(0x33);
    LCD_command(0x32);
    LCD_command(0x28);
    LCD_command(0x0C);
    LCD_command(0x06);
    LCD_command(0x01);
    usDelay(2000);
    }

    void intro() {
    LCD_setCursor(0, 0);
    LCD_write('W'); LCD_write('E'); LCD_write('L'); LCD_write('C'); LCD_write('O'); LCD_write('M'); LCD_write('E');
    LCD_setCursor(1, 0);
    LCD_write('F'); LCD_write('2'); LCD_write('8'); LCD_write('0'); LCD_write('0'); LCD_write('4'); LCD_write('9');
    LCD_setCursor(0,13);
    LCD_write('Y'); LCD_write('E'); LCD_write('S');
    LCD_setCursor(1,13);
    LCD_write('N'); LCD_write('O'); LCD_write('O');
    }

    void main(void)
    {
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    GPIO_setPinConfig(GPIO_35_I2CA_SDA);
    GPIO_setPadConfig(35, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(35, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(GPIO_37_I2CA_SCL);
    GPIO_setPadConfig(37, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(37, GPIO_QUAL_ASYNC);

    I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 100000, I2C_DUTYCYCLE_33);
    I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
    I2C_enableModule(I2CA_BASE);

    init_LCD();
    intro();

    while(1) {
    delay++;
    if (delay > 20000) {
    dec_unid_convert(connt);
    LCD_setCursor(0, 10);
    LCD_write(convert(ten));
    LCD_write(convert(unit));

    LCD_setCursor(1, 10);
    LCD_write(convert(unit));
    LCD_write(convert(ten));

    delay = 0;
    connt--;
    if (connt == 0) connt = 35;
    }
    }
    }