To get the most of this demonstration adjust your LCD contrast pot to where the characters just turn dark. Enjoy.
Code: Select all
program ODOMETER
'***********************************************************************************
'* Tested on 16F877A @ 8MHz....8 DECADE COUNTER....ODOMETER STYLE *
'* Program by W. Schroeder alias "xor" on Dec. 5, 2005 *
'* *
'* Written and compiled successfully with mikroBASIC 2.2 *
'* mikroBASIC libraries and utilites are implemented to work easily with *
'* the mikroElektronika EasyPIC development board with a 16x2 Character LCD *
'* *
'* This is a demonstration program for the Character LCD that can be adapted for *
'* real-world applications such as a KWh Meter, BTU Meter, Liquid Flow Meter, etc. *
'* The visual effect of an older mechanical odometer is possible by using the LCD *
'* controller's user-RAM area, where the user can place up to 8 custom characters *
'* of 8 bytes each. In this program a table was created, "char5x7", that "byte- *
'* maps" the numbers 0 to 9. Through a series of table offsets you can build new *
'* characters that include part of one and part of the next. This is how the *
'* rolling effect is created and generated. *
'* *
'* The code is built in a modular style to allow a user to find his way to add or *
'* subtract from the 8 Decade Digits that are used for this demonstration. This *
'* counter will count to 99,999,999 before rolling over to zeroes. You can enter a *
'* manual starting point by setting the digit values and the LCD_OUT value to *
'* match these values. The decimal in the display is arbitrary...... Enjoy! *
'***********************************************************************************
const char5x7 as byte[88] = (14, 17, 19, 21, 25, 17, 14, 0, ' "0"
4, 12, 4, 4, 4, 4, 14, 0, ' "1"
14, 17, 1, 2, 4, 8, 31, 0, ' "2"
31, 2, 4, 2, 1, 17, 14, 0, ' "3"
2, 6, 10, 18, 31, 2, 2, 0, ' "4"
31, 16, 30, 1, 1, 17, 14, 0, ' "5"
6, 8, 16, 30, 17, 17, 14, 0, ' "6"
31, 1, 2, 4, 8, 8, 8, 0, ' "7"
14, 17, 17, 14, 17, 17, 14, 0, ' "8"
14, 17, 17, 15, 1, 2, 12, 0, ' "9"
14, 17, 19, 21, 25, 17, 14, 0) ' "0"
const choffset as byte[10] = (0, 8, 16, 24, 32, 40, 48, 56, 64, 72) ' character table offset values
const chpos as byte[8] = (64, 72, 80, 88, 96, 104, 112, 120) ' user-ram character addresses
dim digit0 as byte
dim digit1 as byte
dim digit2 as byte
dim digit3 as byte
dim digit4 as byte
dim digit5 as byte
dim digit6 as byte
dim digit7 as byte
dim dig1flag as byte
dim dig2flag as byte
dim dig3flag as byte
dim dig4flag as byte
dim dig5flag as byte
dim dig6flag as byte
dim dig7flag as byte
dim aa as byte
sub procedure sgl_char(dim dig, offset, pos as byte) ' routine loads characters into CGRAM (user-RAM)
dim counter as byte
dig = choffset[dig] + offset ' digit value and offset
LCD_CMD(chpos[pos]) ' starting CGRAM address for this character
For counter = dig to dig + 7 ' load 8 bytes into CGRAM
LCD_CHR_CP(char5x7[counter])
Next counter
end sub
main:
PORTB = 0 ' initialize ports and variables
TRISB = 0
LCD_INIT(PORTB) ' initialize LCD
LCD_CMD(LCD_CLEAR)
LCD_CMD(LCD_CURSOR_OFF)
LCD_OUT(1, 1, "8 DIGIT ODOMETER") ' print to LCD first
LCD_OUT(2, 4,"0000000.0")
digit0 = 0
digit1 = 0
digit2 = 0
digit3 = 0
digit4 = 0
digit5 = 0
digit6 = 0
digit7 = 0
dig1flag = 0
dig2flag = 0
dig3flag = 0
dig4flag = 0
dig5flag = 0
dig6flag = 0
dig7flag = 0
While true ' start an endless loop
For aa = 0 to 7 ' set up character byte offsets
delay_ms(40) ' delay can be adjusted to speed or slow demo
sgl_char(digit0,aa,0) ' send digit0 to be processed
LCD_CHR(2,12,0) ' print digit0 located at user-ram 0
If dig1flag = 1 Then ' check to see if digit1 is also moving
sgl_char(digit1,aa,1) ' if so then process and display
LCD_CHR(2,10,1) ' print digit1 located at user-ram 1
End If
If dig2flag = 1 Then ' check to see if digit2 is also moving
sgl_char(digit2,aa,2) ' if so then process and display
LCD_CHR(2,9,2) ' print digit1 located at user-ram 2
End If
If dig3flag = 1 Then ' check to see if digit3 is also moving
sgl_char(digit3,aa,3) ' if so then process and display
LCD_CHR(2,8,3) ' print digit3 located at user-ram 3
End If
If dig4flag = 1 Then ' check to see if digit4 is also moving
sgl_char(digit4,aa,4) ' if so then process and display
LCD_CHR(2,7,4) ' print digit4 located at user-ram 4
End If
If dig5flag = 1 Then ' check to see if digit5 is also moving
sgl_char(digit5,aa,5) ' if so then process and display
LCD_CHR(2,6,5) ' print digit5 located at user-ram 5
End If
If dig6flag = 1 Then ' check to see if digit6 is also moving
sgl_char(digit6,aa,6) ' if so then process and display
LCD_CHR(2,5,6) ' print digit6 located at user-ram 6
End If
If dig7flag = 1 Then ' check to see if digit7 is also moving
sgl_char(digit7,aa,7) ' if so then process and display
LCD_CHR(2,4,7) ' print digit7 located at user-ram 7
End If
Next aa ' cycle through all phases of digit movement
If dig1flag = 1 Then ' housekeeping for recently moved digit1
sgl_char(digit1, 8, 1) ' bump digit1 up 1 more byte...snap into place
LCD_CHR(2,10,1) ' print
dig1flag = 0 ' reset flag until next required advance
inc(digit1) ' get next value ready for next move
If digit1 = 10 Then digit1 = 0 End If ' rollover to zero if over 9
End If
If dig2flag = 1 Then ' housekeeping for recently moved digit2
sgl_char(digit2, 8, 2)
LCD_CHR(2,9,2)
dig2flag = 0
inc(digit2)
If digit2 = 10 Then digit2 = 0 End If
End If
If dig3flag = 1 Then ' housekeeping for recently moved digit3
sgl_char(digit3, 8, 3)
LCD_CHR(2,8,3)
dig3flag = 0
inc(digit3)
If digit3 = 10 Then digit3 = 0 End If
End If
If dig4flag = 1 Then ' housekeeping for recently moved digit4
sgl_char(digit4, 8, 4)
LCD_CHR(2,7,4)
dig4flag = 0
inc(digit4)
If digit4 = 10 Then digit4 = 0 End If
End If
If dig5flag = 1 Then ' housekeeping for recently moved digit5
sgl_char(digit5, 8, 5)
LCD_CHR(2,6,5)
dig5flag = 0
inc(digit5)
If digit5 = 10 Then digit5 = 0 End If
End If
If dig6flag = 1 Then ' housekeeping for recently moved digit6
sgl_char(digit6, 8, 6)
LCD_CHR(2,5,6)
dig6flag = 0
inc(digit6)
If digit6 = 10 Then digit6 = 0 End If
End If
If dig7flag = 1 Then ' housekeeping for recently moved digit7
sgl_char(digit7, 8, 7)
LCD_CHR(2,4,7)
dig7flag = 0
inc(digit7)
If digit7 = 10 Then digit7 = 0 End If
End If
inc(digit0) ' housekeeping for recently moved digit0
If digit0 = 10 Then digit0 = 0 End If
If digit0 = 9 Then dig1flag = 1 End If ' Advance the next higher digit?
If digit1 + dig1flag = 10 Then dig2flag = 1 End If ' Advance the next higher digit?
If digit2 + dig2flag = 10 Then dig3flag = 1 End If ' Advance the next higher digit?
If digit3 + dig3flag = 10 Then dig4flag = 1 End If ' Advance the next higher digit?
If digit4 + dig4flag = 10 Then dig5flag = 1 End If ' Advance the next higher digit?
If digit5 + dig5flag = 10 Then dig6flag = 1 End If ' Advance the next higher digit?
If digit6 + dig6flag = 10 Then dig7flag = 1 End If ' Advance the next higher digit?
Wend ' do it all again
end.