Forum Discussion

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

printing to 16x2 LCD module

i got this code from here (http://forum.niosforum.com/forum/index.php?showtopic=229). this code initialize the lcd module.

#include <unistd.h># include <stdlib.h># include <stdio.h>
/* Commands which can be written to the COMMAND register */
enum /* Write to character RAM */
{
    LCD_CMD_WRITE_DATA = 0x80
    /* Bits 6:0 hold character RAM address */
};
enum /* Write to character generator RAM */
{
    LCD_CMD_WRITE_CGR = 0x40
    /* Bits 5:0 hold character generator RAM address */
};
enum /* Function Set command */
{
    LCD_CMD_FUNCTION_SET = 0x20,
    LCD_CMD_8BIT = 0x10,
    LCD_CMD_TWO_LINE = 0x08,
    LCD_CMD_BIGFONT = 0x04
};
enum /* Shift command */
{
    LCD_CMD_SHIFT = 0x10,
    LCD_CMD_SHIFT_DISPLAY = 0x08,
    LCD_CMD_SHIFT_RIGHT = 0x04
};
enum /* On/Off command */
{
    LCD_CMD_ONOFF = 0x08,
    LCD_CMD_ENABLE_DISP = 0x04,
    LCD_CMD_ENABLE_CURSOR = 0x02,
    LCD_CMD_ENABLE_BLINK = 0x01
};
enum /* Entry Mode command */
{
    LCD_CMD_MODES = 0x04,
    LCD_CMD_MODE_INC = 0x02,
    LCD_CMD_MODE_SHIFT = 0x01
};
enum /* Home command */
{
    LCD_CMD_HOME = 0x02
};
enum /* Clear command */
{
    LCD_CMD_CLEAR = 0x01
};
# define na_lcd_pio_command ((volatile int *) 0x80920850)# define na_lcd_pio_status ((volatile int *) 0x80920851)# define na_lcd_pio_wr_data ((volatile int *) 0x80920852)# define na_lcd_pio_rd_data ((volatile int *) 0x80920853)
# define PIO_LCD_IO_COMMAND (*na_lcd_pio_command)# define PIO_LCD_IO_STATUS (*na_lcd_pio_status)# define PIO_LCD_IO_WR_DATA (*na_lcd_pio_wr_data)# define PIO_LCD_IO_RD_DATA (*na_lcd_pio_rd_data)
void delay(int para)//delay for 0.2*para ms
{
    int i=0,j=0;
    for(i=0;i<para;i++)
  for(j=0;j<10000;j++);
}
int main()
{
    delay(75);
    PIO_LCD_IO_COMMAND=LCD_CMD_FUNCTION_SET | LCD_CMD_8BIT;
    delay(21);
    PIO_LCD_IO_COMMAND=LCD_CMD_FUNCTION_SET | LCD_CMD_8BIT;
    delay(10);
    PIO_LCD_IO_COMMAND=LCD_CMD_FUNCTION_SET | LCD_CMD_8BIT;
    delay(10);
    PIO_LCD_IO_COMMAND=LCD_CMD_FUNCTION_SET | LCD_CMD_8BIT | LCD_CMD_TWO_LINE;
    delay(10);
    PIO_LCD_IO_COMMAND=LCD_CMD_ONOFF;
    delay(10);
    PIO_LCD_IO_COMMAND=LCD_CMD_CLEAR;
    delay(10);
    PIO_LCD_IO_COMMAND=LCD_CMD_MODES | LCD_CMD_MODE_INC;
    delay(10);
    PIO_LCD_IO_COMMAND=LCD_CMD_ONOFF | LCD_CMD_ENABLE_DISP;
    delay(1000);
    return 0;
}

my question is: How to i print characters to the screen? i suppose i shud look for the address of the pins RS, R/W, and E. but i&#39;ve yet to locate them.

At the mean time, i&#39;m going thru pio_lcd16207.c and pio_lcd16207.h. i think i understand wat these codes r trying to do but i&#39;ve yet to come out with a prog tat works.

Pls advice. Thx in advance.

4 Replies

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

    i also tried to modified from pio_lcd16207.h. i merely add in the main function, change nr_delay to usleep. this time, nth happen to the lcd module.

    #include <unistd.h># include "pio_lcd16207.h"# include "nios2_system.h"    /* Descriptions of standard peripherals */
    static void delayShort(void);
    // Device constants
    // Internal LCD signals
    enum{
        LCD_E  = 0x400,
        LCD_RS = 0x200,
        LCD_RW = 0x100,
        LCD_DATA = 0x0FF
    };
    // LCD Device Commands
    enum{
        LCD_CMD_CLEAR = 0x01,
        LCD_CMD_HOME  =    0x02,
        LCD_CMD_MODES = 0x04,
        LCD_CMD_ONOFF = 0x08,
        LCD_CMD_SHIFT = 0x10,
        LCD_CMD_FUNC  = 0x20,
        LCD_CMD_RAMCGR= 0x40,
        LCD_CMD_RAMDDR= 0x80,
        LCD_CMD_FILLER= 0x00
    };
    // Device Parameters
    enum{
        LCD_INTERFACE = 0x10,  // interface width;1 (8 BITS)/0 (4BITS)
        LCD_NUMROWS =    0x08,  //#  of display rows; 1 (2 ROWS)/0 (1ROW) 
        LCD_PIXEL    =    0x04,  // character pixel;    1(5x10 dots)/0 (5x7 dots)
        LCD_MOVE    =    0x02,  // character move direction; 1(increment)/0(decrement)
        LCD_SHIFT    =    0x01,  // move character with display shift; 1(shift)/0(no shift)
        LCD_DISP_SHIFT=    0x08  // action after character; 1(display shift)/0(character shift)
    };
    enum{
        LCD_COM_RESET = 0x30
    };
    // Some LCD parameters# define LCD_BUS_WIDTH 8# define LCD_PIXEL_WIDTH 5# define LCD_PIXEL_HEIGHT 8
    // The hardcoded definition of where the LCD lives at 
    // PIO port address
    np_pio *lcd = 0;
    void nr_pio_lcdcursorvisible(int bVisible)
    {
        if(bVisible)
      nr_pio_lcdwritecommand(0x0E);
        else 
      nr_pio_lcdwritecommand(0x0C);
    }
    void nr_pio_lcdon(int bOn)
    {
        if(bOn)
      nr_pio_lcdwritecommand(0x0C);
        else 
      nr_pio_lcdwritecommand(0x08);
    }
    void nr_pio_lcdclearscreen(void)
    {
        nr_pio_lcdwritecommand(LCD_CMD_CLEAR);
    }
    void nr_pio_lcdsetcursor(int row, int col)
    {
        unsigned char address;
        if(row > LCD_NUM_ROW)
      row = LCD_NUM_ROW;
        if(col > LCD_NUM_COL)
      col = LCD_NUM_COL;
        if(row == 0)
      address = 0;
        else if (row == 1)
      address = 0x40;
        else if (row == 2)
      address = 0x20;
        else
      address=0x60;
        address += col;
        nr_pio_lcdwritecommand(LCD_CMD_RAMDDR | address);
    }
    void nr_pio_lcdprintstringslowly(char *string, int time)
    {
        char tempBuffer;
        int i;
        i=0;
        sprintf(tempBuffer, string);
        // Show as much of the string as we can...
        while(tempBuffer)
        {
      nr_pio_lcdwritecharacter(tempBuffer);
      usleep(time);
      i++;
        }
    }
    /*
     * nr_pio_lcdwritescreen(char *string);
     *
     * This is probably the most useful routine. It
     * takes a string, and prints it to the LCD starting
     * from the first character. If the string is less
     * than 32 characters, fill the rest of the display
     * with blanks. If the string exceeds 32 characters,
     * truncate it. So sorry!
     */
    void nr_pio_lcdwritescreen(char *string)
    {
        int row;
        int col;
        int done;
        int count;
        count=0;
        for(row=0; row < LCD_NUM_ROW; row++)
        {
      for(col=0; col < LCD_NUM_COL; col++)
      {
          nr_pio_lcdsetcursor(row,col);
          if(string == 0x00)    // hit the end and stick there.
        nr_pio_lcdwritecharacter(0xA0);
          else
        nr_pio_lcdwritecharacter(string);
      }
        }
    }
    void nr_pio_lcdinit(np_pio *lcdPio)
    {
        static int beenInitialized;    // uninitialized static variables get cleared each run!
        if(beenInitialized)
      return;
        
        if(!lcdPio)
      lcdPio = (np_pio *)na_lcd_16207_0;    // pio in reference design...
        lcd = lcdPio;
        // Send first Reset
        usleep(15);    
        nr_pio_lcdwritecommand(LCD_COM_RESET);
        // Send second Reset
        usleep(5);    
        nr_pio_lcdwritecommand(LCD_COM_RESET);
        // Send third Reset
        usleep(1);
        nr_pio_lcdwritecommand(LCD_COM_RESET);
        // Setup interface parameters: 8 bit bus, 2 rows, 5x7 font
        usleep(1);
        nr_pio_lcdwritecommand(LCD_CMD_FUNC | LCD_INTERFACE | LCD_NUMROWS);
        
        // Turn Display Off
        usleep(1);
        nr_pio_lcdwritecommand(LCD_CMD_ONOFF);
        // Clear Display
        usleep(1);
        nr_pio_lcdwritecommand(LCD_CMD_CLEAR);
        
        // Setup Default Mode
        usleep(1);
        nr_pio_lcdwritecommand(LCD_CMD_MODES | LCD_MOVE);
        //ON
        usleep(1);
        nr_pio_lcdon(1);
        
        beenInitialized = 1;
    }
    void nr_pio_lcdwritecommand(unsigned char command)
    {
        // preserve the data on the lines, but clear the RS and RW line
        lcd->np_piodata=(lcd->np_piodata & ~(LCD_RS | LCD_RW | LCD_E));
        
        // output the RS and RW lines.. but nothing else
        lcd->np_piodirection=(lcd->np_piodirection | (LCD_RS | LCD_RW | LCD_E));
        delayShort();
        // toggle the E line HIGH to latch the command
        lcd->np_piodata=(lcd->np_piodata | LCD_E);
        delayShort();
        
        // output command word whilst E line is high
        lcd->np_piodata=(lcd->np_piodata & ~LCD_DATA);
        lcd->np_piodata=(lcd->np_piodata | command);
        lcd->np_piodirection=(lcd->np_piodirection | LCD_DATA);
        // toggle the E line LOW to latch the data
        lcd->np_piodata=(lcd->np_piodata & ~LCD_E);
        delayShort();
    }
    void nr_pio_lcdwritecharacter(unsigned char character)
    {
        // preserve the data on the lines, but clear the RW and E line, set RS
        lcd->np_piodata=(lcd->np_piodata & ~(LCD_RW | LCD_E));
        lcd->np_piodata=(lcd->np_piodata | LCD_RS);
        
        // output the RS and RW lines.. but nothing else
        lcd->np_piodirection=(lcd->np_piodirection | (LCD_RW | LCD_E | LCD_RS));
        delayShort();
        // toggle the E line HIGH to latch the command
        lcd->np_piodata=(lcd->np_piodata | LCD_E);
        delayShort();
        
        // output command word whilst E line is high
        lcd->np_piodata=(lcd->np_piodata & ~LCD_DATA);
        lcd->np_piodata=(lcd->np_piodata | character);
        lcd->np_piodirection=(lcd->np_piodirection | LCD_DATA);
        // toggle the E line LOW to latch the data
        lcd->np_piodata=(lcd->np_piodata & ~LCD_E);
    }
    void delayShort(void)
    {
        int i;
        int v = 0;
        for(i=0;i<50;i++)
      v++;
    }  
    int main(void)
    {
        lcd = (np_pio *)na_lcd_16207_0;
        // Send first Reset
        usleep(15);
        nr_pio_lcdwritecommand(LCD_COM_RESET);
        // Send second Reset
        usleep(5);    
        nr_pio_lcdwritecommand(LCD_COM_RESET);
        // Send third Reset
        usleep(1);
        nr_pio_lcdwritecommand(LCD_COM_RESET);
        // Setup interface parameters: 8 bit bus, 2 rows, 5x7 font
        usleep(1);
        nr_pio_lcdwritecommand(LCD_CMD_FUNC | LCD_INTERFACE | LCD_NUMROWS);
        // Turn Display Off
        usleep(1);
        nr_pio_lcdwritecommand(LCD_CMD_ONOFF);
        // Clear Display
        usleep(1);
        nr_pio_lcdwritecommand(LCD_CMD_CLEAR);
        // Setup Default Mode
        usleep(1);
        nr_pio_lcdwritecommand(LCD_CMD_MODES | LCD_MOVE);
        //ON
        usleep(1);
        nr_pio_lcdon(1);
        printf("LCD initialized.\n");
        usleep(1000);
        nr_pio_lcdwritecharacter(&#39;A&#39;);
        printf("LCD written.\n");
        usleep(5000);
        return 0;
    }

    Pls help! Thx!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by jwlam@Aug 28 2006, 04:04 AM

    i got this code from here (http://forum.niosforum.com/forum/index.php?showtopic=229). this code initialize the lcd module.

    #include <unistd.h># include <stdlib.h># include <stdio.h>
    /* commands which can be written to the command register */
    enum /* write to character ram */
    {
        lcd_cmd_write_data = 0x80
        /* bits 6:0 hold character ram address */
    };
    enum /* write to character generator ram */
    {
        lcd_cmd_write_cgr = 0x40
        /* bits 5:0 hold character generator ram address */
    };
    enum /* function set command */
    {
        lcd_cmd_function_set = 0x20,
        lcd_cmd_8bit = 0x10,
        lcd_cmd_two_line = 0x08,
        lcd_cmd_bigfont = 0x04
    };
    enum /* shift command */
    {
        lcd_cmd_shift = 0x10,
        lcd_cmd_shift_display = 0x08,
        lcd_cmd_shift_right = 0x04
    };
    enum /* on/off command */
    {
        lcd_cmd_onoff = 0x08,
        lcd_cmd_enable_disp = 0x04,
        lcd_cmd_enable_cursor = 0x02,
        lcd_cmd_enable_blink = 0x01
    };
    enum /* entry mode command */
    {
        lcd_cmd_modes = 0x04,
        lcd_cmd_mode_inc = 0x02,
        lcd_cmd_mode_shift = 0x01
    };
    enum /* home command */
    {
        lcd_cmd_home = 0x02
    };
    enum /* clear command */
    {
        lcd_cmd_clear = 0x01
    };
    # define na_lcd_pio_command ((volatile int *) 0x80920850)# define na_lcd_pio_status ((volatile int *) 0x80920851)# define na_lcd_pio_wr_data ((volatile int *) 0x80920852)# define na_lcd_pio_rd_data ((volatile int *) 0x80920853)
    # define pio_lcd_io_command (*na_lcd_pio_command)# define pio_lcd_io_status (*na_lcd_pio_status)# define pio_lcd_io_wr_data (*na_lcd_pio_wr_data)# define pio_lcd_io_rd_data (*na_lcd_pio_rd_data)
    void delay(int para)//delay for 0.2*para ms
    {
        int i=0,j=0;
        for(i=0;i<para;i++)
      for(j=0;j<10000;j++);
    }
    int main()
    {
        delay(75);
        pio_lcd_io_command=lcd_cmd_function_set | lcd_cmd_8bit;
        delay(21);
        pio_lcd_io_command=lcd_cmd_function_set | lcd_cmd_8bit;
        delay(10);
        pio_lcd_io_command=lcd_cmd_function_set | lcd_cmd_8bit;
        delay(10);
        pio_lcd_io_command=lcd_cmd_function_set | lcd_cmd_8bit | lcd_cmd_two_line;
        delay(10);
        pio_lcd_io_command=lcd_cmd_onoff;
        delay(10);
        pio_lcd_io_command=lcd_cmd_clear;
        delay(10);
        pio_lcd_io_command=lcd_cmd_modes | lcd_cmd_mode_inc;
        delay(10);
        pio_lcd_io_command=lcd_cmd_onoff | lcd_cmd_enable_disp;
        delay(1000);
        return 0;
    }

    my question is: how to i print characters to the screen? i suppose i shud look for the address of the pins rs, r/w, and e. but i&#39;ve yet to locate them.

    at the mean time, i&#39;m going thru pio_lcd16207.c and pio_lcd16207.h. i think i understand wat these codes r trying to do but i&#39;ve yet to come out with a prog tat works.

    pls advice. thx in advance.

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=17891)</div>

    --- Quote End ---

    this is regester map address,pls see linux driver book,could anyone post the lcd driver?thanks
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    jwlam,

    have you got it working ? I am interested in this. Pls help me through.

    cheers