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.

Interfacing LCD with MSP430 using shift register

Other Parts Discussed in Thread: MSP430FR2311

Hi,

I want to interface an LCD with MSP430fr2311 using a shift register 74HC164 in 4 bit mode. My hardware connections are:

Data pin of 74HC164 - Pin 15 of MSP430 (P1.7)

CLK pin of 74HC164 - Pin 17 of MSP430 (P1.5)

RS pin of LCD - Pin 1 of MSP430 (P1.1)

EN pin of LCD - Pin 2 of MSP430 (P1.0)

Can anyone help me to write the code in which I can display a string on the LCD screen by sending it through shift register 74HC164.

  • Hi Megha!

    This is quite easy. You have to bitbang the bits of your byte into the shift register, set the right RS level and generate the correct edge at the enable pin. Two times for one byte. What have you written yourself so far? What does not work as expected?

    Dennis
  • #include <msp430fr2311.h>
    #define EN BIT0
    #define RS BIT1
    #define CLK BIT5
    #define DATA BIT7
    unsigned int i;
    unsigned int j;
    void delay(unsigned int k)
    {
    for(j=0;j<=k;j++)
    {
    for(i=0;i<100;i++);
    }
    }
    void data_write(void)
    {
    P1OUT |= CLK;
    P1OUT |= EN;
    delay(2);
    P1OUT = ~EN;
    P1OUT = ~CLK;
    }
    void send_command(unsigned char cmd)
    {
    P1OUT = ~RS;
    P1OUT = (P1OUT & 0xF0)|((cmd>>4) & 0x0F); // send higher nibble
    data_write(); // give enable trigger
    P1OUT = (P1OUT & 0xF0)|(cmd & 0x0F); // send lower nibble
    data_write(); // give enable trigger
    }
    void send_data(unsigned char data)
    {
    P1OUT  = RS;
    P1OUT = (P1OUT & 0xF0)|((data>>4) & 0x0F); // send higher nibble
    data_write(); // give enable trigger
    P1OUT = (P1OUT & 0xF0)|(data & 0x0F); // send lower nibble
    data_write(); // give enable trigger
    }
    void send_string(char *s)
    {
    while(*s)
    {
    send_data(*s);
    s++;
    }
    }
    void lcd_init(void)
    {
    P1DIR |= 0xFF;
    P1OUT &= 0x00;
    send_command(0x33);
    send_command(0x32);
    send_command(0x28); // 4 bit mode
    send_command(0x0E); // clear the screen
    send_command(0x01); // display on cursor on
    send_command(0x06); // increment cursor
    send_command(0x80); // row 1 column 1
    }
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;                 // Stop watchdog timer
        __bis_SR_register(SCG0);                 // disable FLL
    
        P1OUT |= BIT0 + BIT1 + BIT5 + BIT7;
        P1DIR |= BIT0 + BIT1 + BIT5 + BIT7;
        P1SEL0 |= BIT0 + BIT1 + BIT5 + BIT7 ;
        P1SEL1  = ~(BIT0 + BIT1 + BIT5 + BIT7);
        UCA0CTLW0 |= UCSWRST;                     // **reset**
        UCA0CTLW0 |= UCMST|UCSYNC|UCCKPL|UCMSB ;   // 3-pin, 8-bit SPI master, Clock polarity high, MSB
    
        UCA0CTLW0 |= UCSSEL__SMCLK;                //SMCLK
        UCA0BR0 = 0x00;                           // /2,fBitClock = fBRCLK/(UCBRx+1).
           UCA0BR1 = 0;
           UCA0MCTLW = 0;                           // No modulation
    
        UCA0CTLW0 &= ~UCSWRST;                    // **Initialize USCI state machine**
    
         lcd_init();
         data_write();
         send_string("0xAA");
         send_command(0xC0);
    
    
        PM5CTL0 &= ~LOCKLPM5;                     // Disable the GPIO power-on default high-impedance mode
                                              // to activate previously configured port settings
    
        while(1)
        {
       
            __bis_SR_register(LPM0_bits | GIE);   // enable global interrupts, enter LPM0
            __no_operation();                     // For debug,Remain in LPM0
    
        }
    }
    
    

  • This is my code i which I have taken reference from - link www.instructables.com/.../ But its not working.
  • But its not working.

    That's not much of an error description (actually, none).

    What have you tried, and what is not working ?

    Use the debugger, single-step though the bit set operations, and measure the according pin, e.g. with a voltmeter.

  • I hv not worked with LCDs earlier. So I dont know very well how to write the function which diaplays any data on the LCD screen. Also I dont know how to send the data to the LCD through 74HC164 shift register. The code I hv written is not working means nothing gets displayed on LCD screen.

  • Is the LCD display actually a 3.3V type ? A 5V variant would not work without additional interface logic. (check datasheets)
    Check the schematics, the connections (wiring, with ohm-meter) and the supply voltages (voltmeter).
    Are the contrast settings on the display correct ? Zero contrast means nothing is displayed. (check datasheet)
    Referencing the (LCD) datasheet, check that the signal sequences in your code are correct. (Single-step debugging, voltmeter)
  • This code looks like it was written to use the LCD's (4-bit) parallel mode, not a shift register.

    You probably need to start from a different code base and/or read up on how shift registers work.
  • Just to get an idea of bitbanging data:

  • Here is my updated code. Still I am unable to see any data on the lcd screen. Can anyone tell me what is wrong in this code?

    #include <msp430fr2311.h>
    #define EN BIT0
    #define RS BIT1
    #define CLK BIT5
    #define DATA BIT7
    void send_command(unsigned char cmd)
    {
    P1OUT = ~RS;
    UCA0TXBUF =cmd;
    }
    void send_data(unsigned char data)
    {
    P1OUT  = RS;
    UCA0TXBUF = data;
    }
    void lcd_init(void)
    {
    P1DIR |= 0xFF;
    P1OUT &= 0x00;
    send_command(0x33);
    send_command(0x32);
    send_command(0x28); // 4 bit mode
    send_command(0x0E); // clear the screen
    send_command(0x01); // display on cursor on
    send_command(0x06); // increment cursor
    send_command(0x80); // row 1 column 1
    }
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;                 // Stop watchdog timer
        __bis_SR_register(SCG0);                 // disable FLL
    
        P1OUT |= BIT0 + BIT1;
        P1OUT |= BIT5 + BIT7;
        P1DIR |= BIT0 + BIT1;
        P1DIR |= BIT5 + BIT7;
        P1SEL0 |= BIT0 + BIT1;
        P1SEL1 &=~(BIT0 + BIT1);
        P1SEL0 |= BIT5 + BIT7;
        P1SEL1 &=~(BIT5 + BIT7);
    
        UCA0CTLW0 |= UCSWRST;                     // **reset**
        UCA0CTLW0 |= UCMST|UCSYNC|UCCKPL|UCMSB ;   // 3-pin, 8-bit SPI master, Clock polarity high, MSB
    
        UCA0CTLW0 |= UCSSEL__SMCLK;                //SMCLK
        UCA0BR0 = 0x00;                           // /2,fBitClock = fBRCLK/(UCBRx+1).
        UCA0BR1 = 0;
        UCA0MCTLW = 0;                           // No modulation
    
        UCA0CTLW0 &= ~UCSWRST;                    // **Initialize USCI state machine**
        PM5CTL0 &= ~LOCKLPM5;                     // Disable the GPIO power-on default high-impedance mode
                                              // to activate previously configured port settings
    
        while(1)
        {
                P1OUT |= CLK;
            	P1OUT &= ~CLK;
            	P1OUT |= EN;
            	P1OUT &= ~EN;
                  lcd_init();
                  __delay_cycles(200);
                 send_data(0xAA);
                  __delay_cycles(200);
                 send_command(0xC0);
                __delay_cycles(200);
    
      }
    }
    
    
    

**Attention** This is a public forum