Forum Discussion

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

How to Initialize Char LCD using PIO (De0-Nano)

Hello to the whole forum, this is my very first thread so please be kind with me(=

I'm trying to drive a char LCD using my de0 nano but no results yet..

My lcd is a 5v unit but since I need just to write to it I guess it wont be a problem, except for a bit weak logic 1 but according to data sheet it should work.

I tried the altera university core for 16 x 2 char LCD but since I must keep the reduced drivers enabled this seems not the right option to save memory, anyway this core was able to properly initialize the LCD so I must have made some coding/timing error.

In my new implemntation I drive it with 2 separate PIO, one for RS, R/W, En + one for Data.

The PIO_LCD_COMMAND drives the 3bit output bus (msb is RS, RW, lsb is En), then the PIO_LCD_DATA drives the lcd bidirectional data bus.

Here's the LCD data sheet if it may help: http://www.farnell.com/datasheets/2051086.pdf?_ga=1.268795697.1932054068.1473273391

Here below I've attached my initialization code, I hope someone might help! Much thanks guys :D

IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LCD_DATA_BASE, ALTERA_AVALON_PIO_DIRECTION_OUTPUT);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x00);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b000);

usleep(16000);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b001);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x30);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b000);

usleep(4500);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b001);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x30);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b000);

usleep(200);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b001);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x30);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b000);

usleep(200);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b001);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x38);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b000);

usleep(200);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b001);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x08);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b000);

usleep(200);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b001);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x01);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b000);

usleep(200);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b001);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x06);

usleep(100);

IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE,0b000);

usleep(200);

2 Replies

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

    Hi I've been able to initialize it correctly.

    I didn't set the biport output direction for all data pins.

    No I fixed it:

    IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LCD_DATA_BASE , 0b11111111);

    Anyway I try to print some char after the initialization but no result, here's the code I used to print a char:

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x80);

    usleep(1);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b001);

    usleep(2);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b000);

    usleep(200);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x41);

    usleep(1);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b101);

    usleep(2);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b100);

    usleep(200);

    I take some wide timing since I wanted to be sure the unit has time to do its internal operation.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Everything solved, now I can print char and do stuff.

    The second issue was caused by wrong timing.

    The Clear Display command is quite slow and it take 1.52ms to be done, so I Changed usleep(2000).

    As I said I've taken super wide delays since I wanted to avoid timing issue.

    This is my working/corrected code, I hope it may help someone:

    IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LCD_DATA_BASE, 0b11111111);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x00);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b000);

    usleep(16000);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x38);

    usleep(1);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b001);

    usleep(2);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b000);

    usleep(4500);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x38);

    usleep(1);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b001);

    usleep(2);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b000);

    usleep(200);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x38);

    usleep(1);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b001);

    usleep(2);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b000);

    usleep(200);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x38);

    usleep(1);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b001);

    usleep(2);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b000);

    usleep(200);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x0E);

    usleep(1);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b001);

    usleep(2);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b000);

    usleep(200);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x01);

    usleep(1);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b001);

    usleep(2);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b000);

    usleep(2000);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x06);

    usleep(1);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b001);

    usleep(2);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b000);

    usleep(200);

    //data to test lcd

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_DATA_BASE, 0x41); // A

    usleep(1);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b101);

    usleep(2);

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_COMMAND_BASE, 0b100);

    usleep(2);