Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

Problem with character LCD on Cyclone III FPGA Development Kit

Hello,

I am writing because I have a problem with the character LCD on Cyclone III FPGA Development Kit. I cannot write anything on it, I always have the first line completely black, and the second line completely empty.

I read carefully the documentation and previous posts on the forum about similar problem, and I know that there is an error on the Altera documentation about the enable pin (AC24 instead of AB24). So, I do not understand why that does not work.

Attaching, I put the schematic file of quartus, the system build with sopc builder, and the properties of the nios project.

I first try with the following simple program :

# include <stdio.h>                                                              // Needed for printf# include "system.h"# include "altera_avalon_pio_regs.h"
int main (void)
{
    IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0x35);                            // Display a known value on leds
    printf("Hello\n");
    IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0xA2);                            // Display a known value on leds
    while(1);
}
My leds display well 0xA2 at the end, but nothing on LCD.

After I try using fprintf, with the following program :

# include <stdio.h>                                                              // Needed for printf# include <unistd.h>                                                             // Needed for usleep# include "system.h"# include "altera_avalon_pio_regs.h"
int main (void)
{
    int nbChar;
    FILE * lcd;
    lcd = fopen(LCD_NAME, "w");                                                 // Open the LCD device
    if (lcd == NULL)                                                            // Test the success of the file opening by displaying value on leds
        IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0x86); 
    else
        IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0x3C);
    usleep(5000000);                                                            // Pause 5s to read the value on leds
    nbChar = fprintf(lcd, "Hello\n");                                           // Printf something on LCD and get the number of characters written
    
    IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0xFF & (nbChar >> 24));           // Display on leds the value returned by fprintf (1st 8 bits)
    usleep(5000000);                                                            // Pause 5s to read the value on leds
    IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0xFF & (nbChar >> 16));           // Display on leds the value returned by fprintf (2nd 8 bits)
    usleep(5000000);                                                            // Pause 5s to read the value on leds
    IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0xFF & (nbChar >>  8));           // Display on leds the value returned by fprintf (3rd 8 bits)
    usleep(5000000);                                                            // Pause 5s to read the value on leds
    IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0xFF & (nbChar >>  0));           // Display on leds the value returned by fprintf (4th 8 bits)
    usleep(5000000);                                                            // Pause 5s to read the value on leds
    while(1);
}
The opening of the file succeed since I see 0x3C on the leds, and the value returned by the fprintf function is well 6. But I still have nothing on LCD.

If someone have an idea of the cause of this problem, because I really don't see what it can be.

Thanks in advance

Jérôme

9 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Your code should work. If not, I will check two things:

    1. Did you connect the LCD external pins (not in SOPC, but in top VHDL file)?

    LCD_ON, -- Power ON/OFF

    LCD_BLON, -- Back Light ON/OFF

    if not, your LCD software may be working, but you will not see anything in the real LCD.

    2. Maybe you need a initialization sequence for the LCD.

    ///// LCD control: //////////////////////////////////////////////////////

    // From: http://www.altera.com/support/examples/nios2/exm-micro_mutex.html

    // ESC sequences:

    // From: http://www.isthe.com/chongo/tech/comp/ansi_escapes.html

    // ESC[#;#H Moves the cursor to line# , column#

    // ESC[2J Clear screen and home cursor

    // ESC[K Clear to end of line # define ESC_TOP_LEFT "[1;0H" # define ESC_BOTTOM_LEFT "[2;0H" # define LCD_CLR "[2J" # define LCD_CLR_LINE "[K"

    static unsigned char ESC = 0x1b; // Integer ASCII value of the ESC character

    void LCD_hello(void)

    {

    FILE* LCD;

    LCD = fopen ("/dev/lcd", "w");

    if (LCD == NULL) {

    printf("LCD open failed\n");

    } else {

    printf("LCD open succeeded\n");

    fprintf(LCD, "%c%s", ESC, LCD_CLR); // Clears LCD

    fprintf(LCD, "LCD demo using\n");

    fprintf(LCD, "Altera HAL in C");

    }

    fclose (LCD);

    }
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hello,

    There are no other external pins to connect to the LCD. The power is always given because it is directly connected to vcc (cf picture taken from board schematic).

    I try with the initialization sequence but it doesn't change anything.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Sorry, I was thinking on DE2 boards, where enable signals should be connected outside SOPC to allow LCD operation. I don't know if it the same for Cyclone III kits.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hello,

    The problem is resolved. It was due to the hardware, because I put the data pins in output, whereas they have to be bidirectionnal.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This thread was a good find for me. I have been trying to get the character LCD panel working on a Cyclone III dev. kit and it would show no response. I knew about the enable pin documentation problem and was sure I had it wired properly. I came across this thread and then changed the data lines to bi-directional and now the character LCD works! Thanks for posting your find.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    please can you tell me where to change the data lines to bidirectional.

    Please help, i need this to work.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    It's the data pins that you connect to the LCD that have to be bidirectionnal, you do this in Quartus II. In the first picture attached, its LCD_DATA[7_0] (FPGA pins AB3, V6, V5, ..., AA4).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    thank you for your reply. Im new in NIOS II. The LCD is now working. Now i need to write some charater on the LCD if i press a button and a different one when a relaese the button. FOr example:

    if button = 1 "HELLO"

    else "HI".

    i've write the follwing xode but is doesn't work. Can you hel me o n this.

    thank you.

    int main (void)

    {

    // int nbChar;

    int botao;

    FILE * lcd;

    lcd = fopen(LCD_DISPLAY_NAME, "w"); // Open the LCD device

    botao = IORD_ALTERA_AVALON_PIO_EDGE_CAP(USER_PB_BASE);

    if (botao == 1)

    fprintf(lcd, "LASSE 2011\n");

    else

    fprintf(lcd, "Second line 2011\n");

    return(0);

    }

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Few ideas :

    1. Your program executes once and then exits. You have to put your test in a loop such as while(1).

    2. When configuring the PIO Core, have you well enabled the edge capture ? On both edges ?

    3. To detect both edges (button pushed and button released) you must change the if else operation you did, because the if tells you if you have a transition (it can be a rising or a falling edge), the else will thus be executed always if you don't touch the button. So inside, the if, you should have a second test to check the current value on the port to determine if it is was rising (1) or falling (0) transition.