Nios II-based LCD1602 Driver Example

Nios II-based LCD1602 Driver Example

This article demonstrates how to drive an LCD1602 display using a Nios II soft-core processor on the DE2-115 development board.

Experimental Setup

  • Platform: DE2-115
  • Sofwtare: Quartus II 15.1

The Qsys system configuration is shown below (assembly details omitted for brevity).

SDRAM configuration on the DE2-115 board is illustrated below:

Hardware Code

The hardware design is implemneted in Verilog. The top-level module instantiates a PLL and the Nios II system (my_cpu). The PLL generates a main clock (c0) and the SDRAM clock (sdram_clk). A simple counter (vl_cnt) controls the LCD backlight via lcd1602_vl.

module LCD1602 (
    clk,
    rst_n,
    led,
    lcd1602_RS,
    lcd1602_RW,
    lcd1602_data,
    lcd1602_E,
    sdram_addr,
    sdram_ba,
    sdram_cas_n,
    sdram_cke,
    sdram_cs_n,
    sdram_dq,
    sdram_dqm,
    sdram_ras_n,
    sdram_we_n,
    sdram_clk,
    lcd1602_vl,
    lcd1602_on
);

input           clk;
output          lcd1602_RS;
output          lcd1602_RW;
inout   [7:0]   lcd1602_data;
output          lcd1602_E;
output          lcd1602_vl;
output          lcd1602_on;

input           rst_n;
output [12:0]   sdram_addr;
output [1:0]    sdram_ba;
output          sdram_cas_n;
output          sdram_cke;
output          sdram_cs_n;
inout  [31:0]   sdram_dq;
output [3:0]    sdram_dqm;
output          sdram_ras_n;
output          sdram_we_n;
output          sdram_clk;

output [3:0]    led;

wire c0;
reg [3:0] vl_cnt;

always @(posedge clk or negedge rst_n)
    if (!rst_n)
        vl_cnt <= 4'd0;
    else
        vl_cnt <= vl_cnt + 4'd1;

assign lcd1602_vl = (vl_cnt > 9);
assign lcd1602_on = 1;

PLL PLL_inst (
    .inclk0 ( clk ),
    .c0     ( c0 ),
    .c1     ( sdram_clk )
);

my_cpu u0 (
    .clk_clk       (c0),
    .lcd1602_RS    (lcd1602_RS),
    .lcd1602_RW    (lcd1602_RW),
    .lcd1602_data  (lcd1602_data),
    .lcd1602_E     (lcd1602_E),
    .reset_reset_n (rst_n),
    .sdram_addr    (sdram_addr),
    .sdram_ba      (sdram_ba),
    .sdram_cas_n   (sdram_cas_n),
    .sdram_cke     (sdram_cke),
    .sdram_cs_n    (sdram_cs_n),
    .sdram_dq      (sdram_dq),
    .sdram_dqm     (sdram_dqm),
    .sdram_ras_n   (sdram_ras_n),
    .sdram_we_n    (sdram_we_n),
    .pio_led_export(led)
);

endmodule

Software Code

The software driver is written in C and runs on the Nios II processor. It provides macros for LCD command and data read/write operations, and functions to initialize the LCD, display text, and move the cursor to the second line.

Header File (lcd1602.h)

#ifndef LCD1602_H_
#define LCD1602_H_

#define lcd_write_cmd(base, data)  IOWR(base, 0, data)
#define lcd_read_cmd(base)         IORD(base, 1)
#define lcd_write_data(base, data) IOWR(base, 2, data)
#define lcd_read_data(base)        IORD(base, 3)

void LCD_Init(void);
void LCD_Show_Text(char* Text);
void LCD_Line2(void);

#endif /* LCD1602_H_ */

Source File (lcd1602.c)

#include <stdio.h>
#include <altera_avalon_pio_regs.h>
#include <alt_types.h>
#include <unistd.h>
#include <system.h>
#include <string.h>
#include <io.h>
#include <sys/alt_irq.h>
#include "../inc/lcd1602.h"

void LCD_Init(void)
{
    lcd_write_cmd(LCD1602_BASE, 0x38);  // Initialize LCD
    usleep(2000);

    lcd_write_cmd(LCD1602_BASE, 0x0c);  // Display on, cursor off
    usleep(2000);

    lcd_write_cmd(LCD1602_BASE, 0x01);  // Clear display
    usleep(2000);

    lcd_write_cmd(LCD1602_BASE, 0x06);  // Cursor move direction, no shift
    usleep(2000);

    lcd_write_cmd(LCD1602_BASE, 0x80);  // Set cursor to home position
    usleep(2000);
}

void LCD_Show_Text(char* Text)
{
    int i;
    for (i = 0; i < strlen(Text); i++)
    {
        lcd_write_data(LCD1602_BASE, Text[i]);
        usleep(2000);
    }
}

void LCD_Line2(void)
{
    lcd_write_cmd(LCD1602_BASE, 0xc0);  // Move cursor to start of second line
    usleep(2000);
}

int main(void)
{
    char Text1[16] = " Hello DE2-115 ";
    char Text2[16] = " Legend of NCU ";
    
    LCD_Init();
    LCD_Show_Text(Text1);
    LCD_Line2();
    LCD_Show_Text(Text2);

    return 0;
}

Results

The LCD correctly displays the configured text as shown below:

Notes

  • The PLL generates a 50 MHz clock for the Nios II system and a separate clock for the SDRAM controller.
  • The LCD backlight is controlled by a simple counter; it turns on when vl_cnt exceeds 9.
  • The software includes appropriate delays (usleep) to meet the LCD timing requirements.

Tags: Nios II LCD1602 DE2-115 Embedded Systems FPGA

Posted on Sat, 30 May 2026 17:30:45 +0000 by cbolson