This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LCD 20x4 ( 4 bits ) lib

hello everyone I am trying to use a LCD 20x4 ( 4 bits ) with a lm3s328 , but have not found a proper lib , can someone give me a hand .
Thank you .

Parents Reply Children
  • Do you can help-me in this implementations?
    Tanks!

  • What "help" do you need?

    What have you tried?

    Where are you stuck?

    Remember that the LCD neither knows nor cares what chip you use - you just have to follow the correct protocol and the correct timing.

    The only things that will be specific to the particular chip are the control of the port pins, and getting the timing right...

  • OK. My question is in setting the ports . For I am using an LPC1343 and examples are for LPC series 2000. I'm trying mater the maximum of origial code , so the " #define 's"

    //THE PORTLCD.C
    #include <../cmsis/device/lpc134x.h>
    #include "portlcd.h"
    
    #define USE_FIO 3
    
    #if USE_FIO == 1
    #define IO1DIR    FIO1DIR
    #define IO1SET    FIO1SET
    #define IO1CLR    FIO1CLR
    #define IO1PIN    FIO1PIN
    #elif USE_FIO == 2
    #define IO1DIR    IODIR1
    #define IO1SET    IOSET1
    #define IO1CLR    IOCLR1
    #define IO1PIN    IOPIN1
    #elif USE_FIO == 3
    #define IO1DIR    GPIO_GPIO2DIR
    #define IO1SET    GPIO_GPIO2DATA
    #define IO1CLR    GPIO_GPIO2DATA
    #define IO1PIN    GPIO_PIN0
    #endif
    
    /* Please note, on old MCB2300 board, the LCD_E bit is p1.30, on the new board
     it's p1.31, please check the schematic carefully, and change LCD_CTRL and LCD_E
     accordingly if you have a different board. */
    /* LCD IO definitions */
    #define LCD_E     GPIO_PIN0 // 0x80000000            /* Enable control pin                */
    #define LCD_RW    GPIO_PIN1 // 0x20000000            /* Read/Write control pin            */
    #define LCD_RS    GPIO_PIN2 // 0x10000000            /* Data/Instruction control          */
    #define LCD_CTRL  GPIO_PIN3 // 0xB0000000            /* Control lines mask                */
    #define LCD_DATA  GPIO_PIN4 | GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7// 0x0F000000              /* Data lines mask
    
    void LCD_init(void) {
            /* Initialize the ST7066 LCD controller to 4-bit mode. */
            //PINSEL3 = 0x00000000;
    #if USE_FIO == 1
            SCS |= 0x00000001; /* set GPIOx to use Fast I/O */
    #endif
            IO1DIR |= LCD_CTRL | LCD_DATA;
            IO1CLR = !LCD_RW | !LCD_RS | !LCD_DATA;
    
            lcd_write_4bit(0x3); /* Select 4-bit interface            */
            LCD_delay(100000);
            lcd_write_4bit(0x3);
            LCD_delay(10000);
            lcd_write_4bit(0x3);
            lcd_write_4bit(0x2);
    
            lcd_write_cmd(0x28); /*0x28 2 lines, 5x8 character matrix     */
            lcd_write_cmd(0x0e); /* Display ctrl:Disp/Curs/Blnk=ON    */
            lcd_write_cmd(0x06); /* Entry mode: Move right, no shift  */
    
            LCD_load((BYTE *) &UserFont, sizeof(UserFont));
            LCD_cls();
            return;
    }
    ///THE MAIN.C
    #include "../cmsis/device/lpc134x.h"
    #include "../drivers/displays/lcd20x4/portlcd.h"
    
    int main(void) {
            gpioInit();
            LCD_init();
            LCD_cls();
            LCD_gotoxy(1,1);
            LCD_putc("Test");
            for (;;) {
            }
    }
    

  • Never write code that lies to the reader.

    A person who reads IO1DIR assumes that he knows the meaning of IO1DIR. It clearly indicates something happening to port 1 - while you try to remap to port 2. Bad, bad, bad, bad!

    Consider something like:

    #define LCD_RS    (1u << 28)
    #define LCD_RW    (1u << 29)
    ...
    
    #define LCD_SET_OUTPUT(bits)    (GPIO_GPIO2DIR |= (bits))
    #define LCD_SET(bits)           (GPIO_GPIO2DATA |= (bits))
    #define LCD_CLR(bits)           (GPIO_GPIO2DATA &= ~(bits))
    ...
    

    and then:

    LCD_SET_OUTPUT(LCD_RS|LCD_RW|...);
    LCD_SET(LCD_RS);
    LCD_CLR(LCD_RW);
    ...
    

  • I know that simply means IO1DIR
    IO = Input / Output
    1 = Port Identifier
    DIR = port the operating direction ( input, output ) .
    Sorry if I'm learning to confuse a month and your help was important. I'm sure the question pin R / W lcd . I realized that he is on a pin , but he is in the right GND ? I've done some lcd connections in Proteus and it was so.

  • Yes, but isn't it confusing if you have source code that makes use of a constant named "IO1DIR" which seems to imply port 1. But you have a #define that translates IO1DIR into GPIO_GPIO2DIR which seems to be port 2? Wouldn't you be extremely confused if an assign to port 1 actually changes the state of port 2?

    Wouldn't you be confused if you indicate blinkers left on your car and the indication inside the car indicates left but the lamps on the outside instead indicates right?

    The time/cost of maintainance of source code very much depends on how easy it is to read and understand. So the code should "speak" to the developer. And it most definitely shouldn't lie, because it will come back and haunt you.

  • I'm sure the question pin R / W LCD . I Realized que he is on a pin , but he is in the right GND ? I've done some lcd connections in Proteus and it was so .
    Got it , thanks for the tip .

  • Jonatan souza.
    it seems that your code is changed and is different from what was on my mind.use these codes.

    
    #ifndef __PORTLCD_H
    #define __PORTLCD_H
    
    #define USE_FIO         1
    
    #if USE_FIO
    #define IODIR_LCD    FIO0DIR
    #define IOSET_LCD    FIO0SET
    #define IOCLR_LCD    FIO0CLR
    #define IOPIN_LCD    FIO0PIN
    #else
    #define IODIR_LCD    IODIR0
    #define IOSET_LCD    IOSET0
    #define IOCLR_LCD    IOCLR0
    #define IOPIN_LCD    IOPIN0
    #endif
    
    /* LCD IO definitions */
    #define LCD_E                   ( 1 << 26 )                       /* Enable control pin                */
    #define LCD_RW                  ( 1 << 25 )                       /* Read/Write control pin            */
    #define LCD_RS                  ( 1 << 24 )                       /* Data/Instruction control          */
    #define LCD_CTRL                ( LCD_E | LCD_RW | LCD_RS )       /* Control lines mask                */
    #define LCD_DATA                ( 0x0f << 27 )
    #define LCD_DATA_START  27                    /* Data lines mask                   */
    
    extern void LCD_init(void);
    extern void delay (DWORD cnt) ;
    extern void LCD_load(BYTE *fp, DWORD cnt);
    extern void LCD_gotoxy(DWORD x, DWORD y);
    extern void LCD_cls(void);
    extern void LCD_cur_off(void);
    extern void LCD_on(void);
    extern void LCD_putc(BYTE c);
    extern void LCD_puts(BYTE *sp);
    extern void LCD_bargraph(DWORD val, DWORD size);
    extern void LCD_cur_blink( void );
    
    #endif /* end __PORTLCD_H */
    
    
    


    you should just change the Port number and pins according to your project.
    and Source code for 20 character length LCDs.

    
    
    /******************************************************************************
    void LCD_init( void )
    {
       /* Initialize the ST7066 LCD controller to 4-bit mode. */
    #if USE_FIO
            SCS |= 0x00000001;      /* set GPIOx to use Fast I/O */
    #endif
       IODIR_LCD |= LCD_CTRL | LCD_DATA;
       IOCLR_LCD  = LCD_RW   | LCD_RS   | LCD_DATA;
    
       lcd_write_4bit(0x3);                /* Select 4-bit interface            */
       delay (10);
       lcd_write_4bit(0x3);
       delay (10);
       lcd_write_4bit(0x3);
       lcd_write_4bit(0x2);
    
       lcd_write_cmd(0x28);                /* 2 lines, 5x8 character matrix     */
       lcd_write_cmd(0x0e);                /* Display ctrl:Disp/Curs/Blnk=ON    */
       lcd_write_cmd(0x06);                /* Entry mode: Move right, no shift  */
    
       LCD_load( (BYTE *)&UserFont, sizeof (UserFont) );
       LCD_cls();
       return;
    }
    
    /******************************************************************************
    void LCD_gotoxy( DWORD x, DWORD y )
    {
       /* Set cursor position on LCD display. Left corner: 1,1, right: 16,2 */
       DWORD c;
    
       c = x;
       if (y)
       {
          c |= 0x40;
       }
       lcd_write_cmd (c | 0x80);
       lcd_ptr = y*20 + x;
       return;
    }
    
    /******************************************************************************
    void LCD_putc( BYTE c )
    {
       /* Print a character to LCD at current cursor position. */
       if (lcd_ptr == 20)
       {
          lcd_write_cmd (0xc0);
       }
       lcd_write_data(c);
       lcd_ptr++;
       return;
    }
    
    
    /*****************************************************************************
    **                            End Of File
    ******************************************************************************/
    
    
    

  • I'm using the same code , but I'm getting messages such as: "Controller received command whilst busy" and then another " Attempted to read controller date whilst busy" . What is it?

  • proteus is not a reliable simulator.test your code on a real hardware. I used this module in some of my projects and is working well. try more.

  • 6-Jan-2015 18:59 GMT: "I am trying to use a LCD 20x4 ( 4 bits ) with a lm3s328"

    9-Jan-2015 09:29 GMT: "I am using an LPC1343"

    So what chip are you really using??

    Again, leave the LCD part alone until you mastered driving the point pins with specific timing.

    Learn to walk before trying to run.

  • Sorry personal now that I realized . But I am using LPC1343 . Sorry, sorry . It was bad.

  • Right. So get down to learning how to set & clear its pins with defined timing...

  • I believe that this is the problem. On and off the pins have learned and fix what was wrong . But I have questions about this delay . If I leave without "return" it is locked as in an infinite loop and does not pursue the code. I also noticed that the variable msticks does not increase . How come?

    ///LCD.c
    void lcd_delay(int msec) {
            volatile uint32_t done = msTicks + msec;
            while (msTicks != done)
                    ;
    }
    
    ///VTABLE.c
    void SysTick_Handler(void) {
            msTicks++;
    }
    
    

  • Have you forgotten to make msTicks volatile? Making done volatile is not necessary because it doesn't get changed elsewhere.