News:

Let's find out together what makes a PIC Tick!

Main Menu

Large digits on an Alphanumeric 4x20 LCD

Started by top204, Apr 02, 2021, 03:58 PM

Previous topic - Next topic

top204

I created a program to do large digits on an Hitachi 4x20 alphanumeric LCD about 17 years ago, when I was first developing the Proton compiler, so I could test its functionality as I created the LCD commands. I've dug out the program and adapted it to use procedures and the extra features the compilers now have for storing Flash Memory data, even though the original program listing from all those years ago compiled and operated perfectly well, even after all those years. So there is a good level of backward compatability. :-)

The big digit display program is listed below:
'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Display large digits on a 4 line by 20 character alphanumeriic LCD (4x20)
' The program uses the LCD's UDG (User Defined Graphic) characters to create the shapes needed for the large digits
'
' Written by Les Johnson for the Proton8 BASIC compiler.
' https://sites.google.com/view/rosetta-tech/home
'
    Device = 18F25K22                       ' Tell the compiler what device to compile for
    Declare Xtal = 16                       ' Tell the compiler the device is running at 16MHz
'
' Setup the Alphanumeric LCD
'
    Declare LCD_DTPin = PORTB.0             ' The pins used to connect to the LCD's D4 to D5 pins (PORTB.0 to PORTB.3 in this case)
    Declare LCD_RSPin = PORTB.4             ' The pin used to connect to the LCD's RS pin (PORTB.4 in this case)
    Declare LCD_ENPin = PORTB.5             ' The pin used to connect to the LCD's EN pin (PORTB.5 in this case)
    Declare LCD_Interface = 4               ' The LCD will operate with a 4-bit interface
    Declare LCD_Lines = 4                   ' The amount of lines the LCD has
    Declare LCD_Type = Alphanumeric         ' The LCD is an alphanumeric, Hitachi, type
'
' Declare a variable for the demo
'  
    Dim wDispVal As Word                    ' Holds the value to be displayed as big digits

'--------------------------------------------------------------------------------------------
' The main program starts here
' Counts from 0 to 9999, then back to 0 on the LCD in large digits
'
Main:
    DelayMS 200                             ' Wait for the LCD to stabilise after power up
    LCD_SetupUDGs()                         ' Setup the LCD's UDGs
    Cls                                     ' Clear the LCD's display
    Do                                      ' Create a loop
        For wDispVal = 0 To 9999            ' Create a loop to count from 0 to 9999
            LCD_DisplayValue(wDispVal)      ' Display the value on the LCD as big digits
            DelayMS 100                     ' A small delay so we can see the digits move
        Next                                ' Close the counting loop
       
        For wDispVal = 9999 To 0 Step -1    ' Create a loop to count from 9999 to 0
            LCD_DisplayValue(wDispVal)      ' Display the value on the LCD as big digits
            DelayMS 100                     ' A small delay so we can see the digits move
        Next                                ' Close the counting loop
    Loop                                    ' Do it forever  

'--------------------------------------------------------------------------------------------
' Display a value on the LCD using large digits
' Input     : pValue holds the value to display (maximum 9999 on a 4x20 LCD)
' Output    : None
' Notes     : Uses the LCD's UDGs for the shapes of the digits
'
Proc LCD_DisplayValue(pValue As Word)
    Dim bIndex  As Byte                                     ' Holds the index to the flash memory table holding the digit UDG data
    Dim wDecade As Word                                     ' Holds the value for  blanking
    Dim bDigit  As Byte                                     ' Holds the current digit to display
    Dim bLine   As Byte                                     ' Holds the line to display the UDGs on
    Dim wPattern As Word                                    ' Holds the pattern read from the flash memroy UDG data
'
' Each large digit is represented by four lines of four UDGs
'
    Dim DigTable As Flash16 = $0551, $7067, $0551, $0551,_
                              $6776, $6555, $0557, $2556,_
                              $0551, $0551, $6776, $7767,_
                              $7743, $7743, $6776, $2441,_
                              $6041, $7703, $2443, $6776,_
                              $6776, $7767, $0577, $7751,_
                              $2556, $7776, $6776, $7767,_
                              $0551, $2536, $2443, $7464,_
                              $6444, $2443, $7776, $2443,_
                              $2443, $7767, $2443, $7443    
    For bLine = 0 To 3                                      ' Create a loop for the four lines required to display a digit
        wDecade = 1000                                      ' Load the decade counter before entering the loop to display the digits
        Cursor bLine + 1, 0                                 ' Position the cursor on the correct line
        For bDigit = 3 To 0 Step -1                         ' Create a loop for each digit                   
            bIndex = (Dig wDispVal, bDigit) + (bLine * 10)  ' Calculate the index to the data table containing the digit data
            wPattern = CRead16 DigTable[bIndex]             ' Get the data for the digits   
            If bDigit <> 0 And pValue < wDecade Then        ' \
                Print "    "                                ' | Blank out the digits
            Else                                            ' /
                Print (wPattern.HighByte & %11110000) >> 4,_ ' \
                      wPattern.HighByte & %00001111,_        ' | Print the big digit
                      (wPattern.LowByte & %11110000) >> 4,_  ' |
                      wPattern.LowByte & %00001111           ' /
            EndIf          
            If bDigit <> 0 Then
                Print " "
            EndIf
            wDecade = wDecade / 10
        Next
    Next
EndProc

'--------------------------------------------------------------------------------------------
' Set up the UDGs used for the digits in the 4x20 alphanumeric LCD
' Input     : None
' Output    : None
' Notes     : None
'
Proc LCD_SetupUDGs()
    Dim bIndex As Byte
'
' Define bit patterns for the LCD's UDGs
'
    Dim UDG_Data As Flash8 = %00000,_       ' \
                             %00000,_       ' |
                             %00000,_       ' |
                             %00001,_       ' | Left-right up-ramp
                             %00011,_       ' |
                             %00111,_       ' |
                             %01111,_       ' |
                             %11111,_       ' /
                            
                             %00000,_       ' \
                             %00000,_       ' |
                             %00000,_       ' |
                             %10000,_       ' | Right-left
                             %11000,_       ' |
                             %11100,_       ' |
                             %11110,_       ' |
                             %11111,_       ' /
                            
                             %11111,_       ' \
                             %01111,_       ' |
                             %00111,_       ' |
                             %00011,_       ' | Left-right down ramp
                             %00001,_       ' |
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' /
                            
                             %11111,_       ' \
                             %11110,_       ' |
                             %11100,_       ' |
                             %11000,_       ' | Right-left
                             %10000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' /
                            
                             %00000,_       ' \
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' | Lower block
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' /
                            
                             %11111,_       ' \
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' | Upper block
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' /
                            
                             %11111,_       ' \
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' | Full block
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' /
                            
                             %00000,_       ' \
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' | Full blank
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000         ' /    
    Print $FE, $40                          ' Enter CGRAM mode in the LCD
    For bIndex = 0 To 63                    ' Create a loop to read the UDG data
        Print CRead8 UDG_Data[bIndex]       ' Send the bit patterns to the LCD
    Next
EndProc

I've deliberately made the "UDG_Data" flash memory table extended, even though the values would have fitted on a few lines, so you can see the shape of the UDG each data item will make, so you can try altering the digit shapes if you wish.

Below is an Isis simulator screenshot of the above program running. Isis has far too large a gap between the LCD characters, so things never look as they would in "real life" in it.
Large Digits.jpg