This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

20x2 LCD connection with TIVA C Launchpad (EK-TM4C123GXL)

Other Parts Discussed in Thread: EK-TM4C123GXL

Hello,

I am connecting TIVA C Launchpad with 20x2 LCD. when I turn on the power only I can see is the pixel blinking on the first row . Below is my connection details:

PB0 to PB7 : Data pins

PD0 : RS

PD1: E

R/W :GND

I have referred the below post and made corrections accordingly :

http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/385440

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"

//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif

//LCD code
//PB0 to PB1 Data Lines
//PD0 = RS
//PD1 = E
//R/W = GND


void LCD_command(unsigned char data)
{
	GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0|GPIO_PIN_1,0x00); // PD0=RS=0, PD1=E=0
	GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,data); // DATA Pins
	GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0|GPIO_PIN_1,0x00);  // PD0=RS=0, PD1=E=0
	SysCtlDelay(SysCtlClockGet()/03); // 1 sec delay
    GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0|GPIO_PIN_1,0x02); // enabling LCD by high to low pulse E=1, PD1 high
	SysCtlDelay(SysCtlClockGet()/03);
	GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0|GPIO_PIN_1,0x00); // RS=0, E=0
}

void LCD_data(unsigned char data)
{
	GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0|GPIO_PIN_1,0x00);  // PD0=RS=0, PD=E=0
	GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,data); // DATA Pins
	//GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0|GPIO_PIN_1,0x01); // PD0=RS=1, PD1=E=0
	GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0,1); // PD0=RS=1, PD1=E=0
	SysCtlDelay(SysCtlClockGet()/03);
	GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0|GPIO_PIN_1,0x02); //PD0=RS=0, PD1=E=1
	SysCtlDelay(SysCtlClockGet()/03);
	GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0|GPIO_PIN_1,0x03); //PD0=RS=1, PD1=E=1

}

void LCD_Init()
{
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x038);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x038);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x038);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x038);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x06);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x0c);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x41);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x41);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x43);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x44);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0xC0);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x41);
	SysCtlDelay(SysCtlClockGet()/03);
	LCD_command(0x03);
	SysCtlDelay(SysCtlClockGet()/03);
}

void LCD_String_Display(unsigned char*str)
{
	while(*str);
	{
		LCD_data(*str);
		str++;
	}
}

int main(void)
{
    //SysCtlClockSet (SYSCTL_SYSDIV_16|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                          SYSCTL_XTAL_16MHZ);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
    GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE,GPIO_PIN_0|GPIO_PIN_1);
    LCD_Init();
    LCD_String_Display("A");

}

Please let me know what am I missing..?  I have kept the system clock delay 1 sec, and verified with the scope.

Let me know if there is something wrong.

 

 

  • I want to insert LCD datasheet here. Can you please tell from where I can insert that PDF doc. 

  • Hello Anup,

    Did you remove the 0Ohm resistance on the PD0,PD1 to PB6,PB7 pair. Please refer to the user guide schematic for EK-TM4C123GXL

    Regards
    Amit
  • This is surely wrong (under Lcd Data)

    GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0|GPIO_PIN_1,0x02); //PD0=RS=0, PD1=E=1

    This sets E high - yet drives RS low.  Terrible!   Both must be high - and should NOT toggle together!

    GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0|GPIO_PIN_1,0x03); //PD0=RS=1, PD1=E=1

    Code above leaves both RS & E high - you want to drive E low at the completion of your display data write.

    As Amit (and perhaps few others) have LONG noted - dreaded 0Ω resistors continue their long torment.   (God forbid they be properly "bagged" or tombstoned...)

  • Hello,

    Thank you for your reply. sorry for the terrible mistake. I just noticed that after posting the query and changed pins from PD0, PD1 to PA6, PA7.

     

     

  • Hello Anup,

    So did it work after correcting?

    Regards
    Amit
  • Left to their own devices (i.e. unguided) a 2-3 post issue extends to 10+... (wonderful - insures 100K points - but time/effort (value) is diluted and such inefficiency {even long & well identified} calls into question (other, perhaps more serious) misuse of time & resources...)

    As I listed in the original (correcting) post - RS/RW & E must NOT toggle together.   This poster's code does that.   While wrong - this may work (until) the code changes from command to data write - and then the "together toggle" will disrupt the Lcd controller.

  • Hello,

    Thank you for your suggestions. I have changed the code accordingly. Still the same issue continues, LCD continuously blinks .


    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/fpu.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"


    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif

    //LCD code
    //PB0 to PB1 Data Lines
    //PA6 = RS
    //PA7 = E
    //R/W = GND


    void LCD_command(unsigned char data)
    {
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7,0x00); //PA6=PA7=0x00
    GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,data); // DATA Pins
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7,0x00); //PA6=PA7=0x00
    SysCtlDelay(SysCtlClockGet()/3); // 1 sec delay
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7,0x80); //PA6=0, PA7=1
    SysCtlDelay(SysCtlClockGet()/3);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7,0x00); //PA6=PA7=0x00
    }

    void LCD_data(unsigned char data)
    {
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7,0x00); // PA6=PA7=0x00
    GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,data); // DATA Pins
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7,0x40); // PA6=1,PA7=0
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6,GPIO_PIN_6);// PA6=1, PA7=0
    SysCtlDelay(SysCtlClockGet()/5);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7,GPIO_PIN_7);// PA6=1,PA7=1
    SysCtlDelay(SysCtlClockGet()/3);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7,0x00); //PA7=0x00
    SysCtlDelay(SysCtlClockGet()/3);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7,0x00); //PA6=PA7=0x00
    }

    void LCD_Init()
    {
    SysCtlDelay(SysCtlClockGet()/3);
    LCD_command(0x38); // function set
    SysCtlDelay(SysCtlClockGet()/3);
    LCD_command(0x38); // function set
    SysCtlDelay(SysCtlClockGet()/3);
    LCD_command(0x38); // function set
    SysCtlDelay(SysCtlClockGet()/3);
    LCD_command(0x38); // function set
    SysCtlDelay(SysCtlClockGet()/3);
    LCD_command(0x01); // clear display
    SysCtlDelay(SysCtlClockGet()/3);
    LCD_command(0x06); // Entry mode set
    SysCtlDelay(SysCtlClockGet()/3);
    LCD_command(0x0C); // Display ON/OFF
    SysCtlDelay(SysCtlClockGet()/3);
    }

    void LCD_String_Display(unsigned char*str)
    {
    SysCtlDelay(SysCtlClockGet()/3);
    LCD_data(0x41); // display A
    SysCtlDelay(SysCtlClockGet()/3);
    LCD_data(0x43); // Display C
    SysCtlDelay(SysCtlClockGet()/3);
    LCD_data(0x44); // Display D
    SysCtlDelay(SysCtlClockGet()/3);
    while(*str);
    {
    LCD_data(*str);
    str++;
    }
    }


    int main(void)
    {
    SysCtlClockSet (SYSCTL_SYSDIV_16|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    //ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    // SYSCTL_XTAL_16MHZ);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
    GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_6|GPIO_PIN_7);
    LCD_Init();
    LCD_String_Display("WELCOME");
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7,0x00);

    }

    // Please let me know if I am missing something. In LCD_data function I did the correction and now E goes high after RS signal.  I have a doubt the the *str loop does not get called. 

    // Please help.

  • Our firm has just moved - we're over-loaded w/boxes - I'm not here "officially."

    Your code has improved - but is ripe w/redundancies.   (i.e. you must spend more time in thought)

    Lcd_Data still over-challenges:

    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7,0x40); // PA6=1,PA7=0
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6,GPIO_PIN_6);// PA6=1, PA7=0

    Do not those 2 lines do the same?   (you should be the proof-reader)

    and

    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7,0x00); //PA7=0x00
    SysCtlDelay(SysCtlClockGet()/3);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7,0x00); //PA6=PA7=0x00

    That 1st write clears "E" - that's fine.   Then the 2nd - clears both "E" & "RS" - when both were (already) clear.   Pointless...

    Suggest that you employ KISS.   Forget your string command for now.  Employ a single character data write "0x41 for "A" - see if it works.

    Depending upon your compiler settings - your delay loops may not be executing.  Failed delays & bad contrast settings are "usual suspects" for no display...

  • Hello,

    Thank you for your suggestions. I will modify this accordingly. Should I need to keep RS continuously high or make it zero after data write ? ..
    I have connected R/W pin directly to GND of TIVA C, and made the GND common with +5V Power supply. Should I need to consider R/W in code also and define it zero.

    Please suggest.
  • All signals must comply w/HD44780 (and/or clones) data spec. RS & RW are not to toggle together w/E - your earlier code did that.

    When doing a data write RS may remain high - toggling it will likely cause trouble - and it's pointless.

    When doing a command write - or series of such writes - RS may remain low. Again toggling RS may cause trouble.

    We "set" RS just prior to any display write - and "clear" RS just prior to any command write. This (golden) rule has aided hundreds of our display clients.

    For a huge percentage of Lcd character applications grounding RW (as you've done) is perfectly acceptable. Only when throughput is "de rigueur" - or when you want to use the lcd as an 80 byte storage ram - is it necessary to "control" RW. If you've grounded RW - there is no need to define it but do check that your code makes no other reference to RW.

    Again - check your delays - your IDE may be eliminating them - you must set "optimizations" to very low or off...   Toggling an Led - with your expected delays inserted between on & off - will confirm that your delays are working...