Forum Discussion

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

2-Line Display & Custom Character Creation and Display

I apologize in advance as I am very new to all of this so my vocabulary will probably be very layman. I will try to provide as much information as possible.

I am currently working with a Nios II processor DE0 board.

A snapshot of the LCD I am working with is

https://www.alteraforum.com/forum/attachment.php?attachmentid=7834 The number after that is ST7066U

I am trying to write in assembly language a program that will allow me to use 2 lines on the display.

I also want to create a custom character to display. After reading the instruction manual, I learned about writing to DDRAM and GCRAM, but I have no idea how.

Any help would be appreciated.

Below is what I have figured out how to write to display:

1 Reply

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

    .global alt_main

    .text

    alt_main:

    movia sp, 0x00800000 //Set up stack address

    movia r10, 0x10000040 //Assigns r10 to address for slider switch

    movi r9, 0b00 //Used as initial contents of slider switch

    movi r11, 0b001 //Assigns value for SW0

    movi r12, 0b010 //Assigns value for SW1

    movi r13, 0b011 //Assigns value for SW2

    movia r17, 0x00800030 //Assigns r17 to address for LCD control port

    movia r16, 0x00800040 //Assigns r18 to address for LCD data port

    call LCDportInit //Sets the port for the LCD to OUTPUT

    call LCDinit //Sets the details that the LCD will follow

    slider_check:

    ldbio r9, 0(r10) //Loads contents of the slider switch

    andi r9, r9, 0b011 //Checks only first 3 bits/switches

    beq r9, r0, slider_check //Loop if 0

    beq r4, r9, slider_check //Loop is same as the check register r4

    mov r4, r9 //Store new check register as equivalent to r9

    beq r9, r11, Hello //If only first slider is on, branch to Hello

    beq r9, r12, HowAreYou //If only second slider is on, branch to HowAreYou

    beq r9, r13, IAmFine //If only third slider is on, branch to IAmFine

    Hello:

    movia r18, Message1 //Assigns r18 as the address of Message1

    call LCDprintString //Run the subroutine to print the message

    br slider_check

    HowAreYou:

    movia r18, Message2 //Assigns r18 as the address of Message2

    call LCDprintString //Run the subroutine to print the message

    br slider_check

    IAmFine:

    movia r18, Message3 //Assigns r18 as the address of Message3

    call LCDprintString //Run the subroutine to print the message

    br slider_check

    LCDcmdWrt:

    subi sp, sp, 8 //Make room on stack

    stw r6, 0(sp) //Save r6

    stw ra, 4(sp) //Save ra incase another

    //subroutine is called

    call delay_20ms //Time needed to perform command

    movi r6, 0 //E=RS=RW=0

    stbio r6, 0(r17) //LCD control port

    stbio r7, 0(r16) //Send command to LCD data port. The command

    //is passed to subroutine in r7

    ori r6, r6, 0b100 //E = 1

    stbio r6, 0(r17) //LCD control port

    call delay_500ns //Keep E high > 450ns

    andi r6, r6, 0b11111011 //E = 0

    stbio r6, 0(r17) //LCD control port

    ldw r6, 0(sp) //restore r6

    ldw ra, 4(sp) //restore ra

    addi sp, sp, 8 //restore sp up to initial address

    ret

    LCDdataWrt:

    subi sp, sp, 8 //Make room on stack

    stw r6, 0(sp) //Save r6

    stw ra, 4(sp) //Save ra incase another subroutine is called

    call delay_20ms //Time needed to perform command

    movi r6, 0b010 //E=0 RS=1 RW=0

    stbio r6, 0(r17) //LCD control port

    stbio r7, 0(r16) //Send command to LCD data port. The command

    //is passed to subroutine in r7

    ori r6, r6, 0b100 //E = 1

    stbio r6, 0(r17) //LCD control port

    call delay_500ns //Keep E high > 450ns

    andi r6, r6, 0b11111011 //E = 0

    stbio r6, 0(r17) //LCD control port

    ldw r6, 0(sp) //restore r6

    ldw ra, 4(sp) //restore ra

    addi sp, sp, 8 //restore sp up to initial address

    ret

    LCDportInit:

    subi sp, sp, 8 //Make room on stack

    stw r6, 0(sp) //Save r6

    stw ra, 4(sp) //Save ra incase another subroutine is called

    movi r6, 0xff //Value used to initiate the LCD as OUTPUT

    stbio r6, 4(r17) //Store to LCD control port

    stbio r6, 4(r16) //Store to LCD data port

    ldw r6, 0(sp) //restore r6

    ldw ra, 4(sp) //restore ra

    addi sp, sp, 8 //restore sp up to initial address

    ret

    LCDinit:

    subi sp, sp, 4 //Make room on stack

    stw ra, 0(sp) //Save ra

    movi r7, 0x38 //Data length 8-bits, 5x7 font

    call LCDcmdWrt

    movi r7, 0x0f //display ON, cursor ON, cursor Blink

    call LCDcmdWrt

    movi r7, 0x01 //clear display

    call LCDcmdWrt

    movi r7, 0x06 //increment cursor position

    call LCDcmdWrt

    movi r7, 0x02 //home cursor

    call LCDcmdWrt

    ldw ra, 0(sp) //restore ra

    addi sp, sp, 4 //restore sp up to initial address

    ret

    LCDprintString:

    subi sp, sp, 8 //Make room on stack

    stw r7, 0(sp) //Save r7

    stw ra, 4(sp) //Save ra

    movi r7, 0x01 //clear display

    call LCDcmdWrt

    movi r7, 0x02 //home cursor

    call LCDcmdWrt

    next_char:

    ldb r7, 0(r18) //Load the current character in the string

    beq r7, r0, end_printString //If LCD has reached the '0' at the end

    //of the string, go to end_printString

    call LCDdataWrt //Run the subroutine LCDdataWrt

    addi r18, r18, 0x01 //Add 1 to the character string value

    br next_char //Loop the current subroutine

    end_printString:

    ldw r7, 0(sp) //Restore r7

    ldw ra, 4(sp) //Restore ra

    addi sp, sp, 8 //Restore sp up to initial address

    ret

    delay_20ms:

    subi sp, sp, 8 //Allocate 8 bytes on stack

    stw r6, 0(sp) //Save r6

    stw ra, 4(sp) //Save return address, allows nesting subroutines

    movia r6, 45455 //This value allows for 20ms to pass

    again_20ms:

    subi r6, r6, 1

    bne r6, r0, again_20ms

    ldw r6, 0(sp) //Restore r6

    ldw ra, 4(sp) //Restore return address

    addi sp, sp, 8 //de-allocate stack locations

    ret

    delay_500ns:

    andi r0, r0, 0b0 //These instructions will provide enough

    andi r0, r0, 0b0 //time to complete the necessary delay time

    ret

    .data

    Message1:

    .asciz "Hello"

    Message2:

    .asciz "How are you?"

    Message3:

    .asciz "I am fine"

    .end