' *** LCD16x2-CustCharDriver14M2.bas ******************* 2011.10.01 ***
' This program runs on a Picaxe-14M2 @ 8MHz. It receives serial data
' from a master processor & diplays it on an HD 44780-type 16x2 LCD.
' *** Constants *******
symbol cmnd = 0 ' RSbit = 0 (low) for command bytes
symbol text = 1 ' RSbit = 1 (high) for text bytes
symbol enPin = B.1 ' LCD enable pin on B.1
symbol rxPin = C.4 ' serial data received on C.4
Symbol BaudRate = N4800_32
' *** Variables *******
symbol char = b0 ' character to be sent to LCD
symbol index = b1 ' used in for/next loop
symbol nibHi = b2 ' the high nibble of char
symbol nibLo = b3 ' the low nibble of char
symbol RSbit = b4 ' used to set up for cmnd/text byte
symbol temp = b5 ' used to manipulate character data
symbol RSpin = pinB.0 ' here, we're using RSpin as a variable
' (to access the state of the input),
' so the form "pinB.0" is required
symbol Started=b27
' *** Directives ******
#picaxe 14M2 ' set compiler mode
#terminal off
#Define StandAlone
'#Define BuiltIn
' *** Data ************
; A
; W
data (%00100) ' *
data (%01010) ' * *
data (%01110) ' ***
data (%01010) ' * *
data (%00000) '
data (%10101) '* * *
data (%11111) '* * *
data (%01010) ' * *
; <
; >
data (%00100) ' *
data (%01010) ' * *
data (%10001) '* *
data (%00100) ' *
data (%00100) ' *
data (%10001) '* *
data (%01010) ' * *
data (%00100) ' *
; .
data (%00000) '
data (%00000) '
data (%00000) '
data (%00000) '
data (%00000) '
data (%01110) ' ***
data (%01110) ' ***
data (%00000) '
; Batt Full
data (%01110) ' ***
data (%11111) '*****
data (%11111) '*****
data (%11111) '*****
data (%11111) '*****
data (%11111) '*****
data (%11111) '*****
data (%11111) '*****
; Batt Half
data (%01110) ' ***
data (%10001) '* *
data (%10001) '* *
data (%10001) '* *
data (%11111) '*****
data (%11111) '*****
data (%11111) '*****
data (%11111) '*****
; Batt Empty
data (%01110) ' ***
data (%10001) '* *
data (%10001) '* *
data (%10001) '* *
data (%10001) '* *
data (%10001) '* *
data (%10001) '* *
data (%11111) '*****
' Display on LCD
data 48,("Serial LCD V1.4")
data 64,("Ready.Baud N4800")
' *** Begin Main Program **********************************************
setfreq m32
Symbol LCD_power=C.0
high LCD_Power
dirsB = %11111111 ' all PortB pins are outputs to the LCD
dirsC = %11000111 ' C.3, C.4, and C.5 are fixed as inputs.
' *** Initialize the LCD ***
outpinsB = 0 ' clear all output lines
pause 1600 ' pause 200 mS for LCD initialization
outpinsB = 12 ' (48/4=12) set to 4-bit operation
pulsout enPin,8 ' send data
pause 80 ' pause 10 mS
pulsout enPin,8 ' send again
pulsout enPin,8 ' send again (necessary in 4-bit mode)
outpinsB = 8 ' (32/4=8) set to 4-bit operation
pulsout enPin,8 ' send data.
pulsout enPin,8 ' send again (necessary in 4-bit mode)
outpinsB = 32 ' (128/4=32) set to 2 line operation
pulsout enPin,8 ' send data
char = 12 ' display on, cursor off
gosub OutToLCD
' *** Load custom chars into CGRAM ***
char = 64 ' define custom characters
RSbit = cmnd
gosub OutToLCD2
RSbit = text
for index = 0 to 47 ' install 8 custom characters
read index, char
gosub OutToLCD2
next index
char = 1 ' instruction: clear display
gosub OutToLCD ' send instruction to LCD
pause 16 ' minimum 2mS delay for clear display
#IfDef StandAlone Then
char = 128 ' instruction: go to start of 1st row
gosub OutToLCD ' send instruction to LCD
for index = 48 to 63 ' output data to 1st row of LCD
read index, char ' read character from EEPROM
gosub OutToLCD ' send character to LCD
next index
Pause 16
char = 192 ' instruction: go to start of 2nd row
gosub OutToLCD ' send instruction to LCD
for index = 64 to 79 ' output data to 2nd row of LCD
read index, char ' read character from EEPROM
gosub OutToLCD ' send character to LCD
next index
#EndIf
Let Started=0
' *** Main loop: Receive data and display it. ***
do
bptr = 28
serin rxPin,BaudRate,@bptrinc
serin [800], RxPin, BaudRate, @bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
#IfDef StandAlone Then
If Started=0 Then
Let char = 1
gosub OutToLCD
pause 16
Let Started=1
EndIf
#EndIf
@bptr = 0
bptr = 28 ' Reset the byte pointer to the first location.
do until @bptr = 0
char = @bptrinc
gosub OutToLCD
loop ' do loop
loop ' main loop
OutToLCD:
select case char
case 0 to 31
RSbit = cmnd
case 128 to 207
RSbit = cmnd
case 123
char = 0 ; W/H icon
RSbit = text
case 124
char = 1 ; <> icon
RSbit = text
case 125
char = 2 ; 'dp' icon
RSbit = text
case 208
char = 3 ; Battery icon
RSbit = text
case 209
char = 4 ; Battery Half icon
RSbit = text
case 210
char = 5 ; Battery Empty icon
RSbit = texte
case 255 ; Reset LCD Display
Low LCD_Power
pause 1000
Reset
else
RSbit = text
endselect
OutToLCD2:
nibHi = char & %11110000 ' isolate high nibble of char
nibHi = nibHi / 4 ' move to pins 5,4 ,3 & 2
outpinsB = nibHi ' place high nibble of char onto pins
RSpin = RSbit ' RSpin = 0 for cmnd or 1 for text
pulsout enPin,2 ' send data
nibLo = char & %00001111 ' isolate low nibble of char
nibLo = nibLo * 4 ' move to pins 5,4 ,3 & 2
outpinsB = nibLo ' place low nibble of char onto pins
RSpin = RSbit ' RSpin = 0 for cmnd or 1 for text
pulsout enPin,2 ' send data
return
#IfDef StandAlone Then
#IfDef BuiltIn Then
#Error "Stand alone and Built in both defined."
#EndIf
#Else
#IfDef BuiltIn Then
Let Char=0
#Else
#Error "Stand alone or Built in must be defined."
#EndIf
#EndIf
#picaxe 08M2
#Define StandAlone
Setfreq M32
Symbol stb = C.4
Symbol sck = C.1
Symbol sda = C.2
Symbol sda_pin = pinC.2
Symbol rxpin = C.3 ' serial data received on C.3
'Symbol BaudRate = N4800_32
Symbol baudrate = T9600_32
Symbol timing = 1
Symbol char1=17
Symbol raw=b0
Symbol chrs=b1
Symbol cmd=b2
Symbol dataposition=b3
Symbol displayposition=b4
Symbol index=b5
Symbol Started=b6
Symbol var1=b7 'Hexadecimal conversion
Symbol var2=b8
Symbol var3=b9
Output sda
Gosub Clear_Disp
Gosub Disp_On
Let chrs=char1
Let displayposition=0
'Display on VFD
Data 0, ("Serial Data Monitor")
Data 20,("T9600.8 Qualifier=7E")
'Data 41,("Test Mode Selected")
Pause 100
For index = 0 To 19 ' output data to 1st row of VFD
Read index, chrs ' read character from EEPROM
Gosub Check_Chrs ' send character to VFD
Next index
Let cmd=168 ;Line 2, position 1
Gosub Send_Function
For index = 20 To 40 ' output data to 2nd row of VFD
Read index, chrs ' read character from EEPROM
Gosub Check_Chrs ' send character to VFD
Next index
Main:
Do
bptr = 28 'Set up to begin storing data at location 29,
'(just above the 28 general purpose variables)
Serin RxPin, baudrate, @bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc
@bptr = 0 'We're using 0 as an end of transmission marker.
If Started=0 Then
Let Started=1
Gosub Clear_Disp
EndIf
Let cmd=128 ;Line 1, position 1
Gosub Send_Function
bptr = 28 'Reset the byte pointer to the first location.
'Send two spaces to centralise the display
Let chrs=32
Gosub Send_Char
Let chrs=32
Gosub Send_Char
Do Until @bptr = 0 'loop until we reach the EOT character
chrs = @bptrinc 'get each byte
Let var1=chrs
Gosub HexToAscii
Let chrs=var1
Gosub Send_Char
Let chrs=var2
Gosub Send_Char
'Let chrs=32
'Gosub Send_Char
Loop 'do loop
'Send two spaces to centralise the display
Let chrs=32
Gosub Send_Char
Let chrs=32
Gosub Send_Char
Loop
Goto Main 'main loop
Send_Data:
High sck
High stb
Pause timing
Low stb
Let raw=250 ;Data Send
Gosub Send_Raw_Reverse
Return
Send_Ins:
High sck
High stb
Pause timing
Low stb
Let raw=248 ;Instruction Send
Gosub Send_Raw_Reverse
Return
Clear_Disp:
Gosub Send_Ins
Let raw=1 ;Display Clear
Gosub Send_Raw_Reverse
Pause 10
Return
Disp_On:
Gosub Send_Ins
Let raw=12 ;Display on
Gosub Send_Raw_Reverse
Return
Send_Char:
Gosub Send_Data
Let raw=chrs ;Character value
Gosub Send_Raw_Reverse
Return
Send_Function:
Gosub Send_Ins
Let raw=32 ;Function Set
Gosub Send_Raw_Reverse
Gosub Send_Ins
Let raw=cmd ;Command to send
Gosub Send_Raw_Reverse
Return
Send_Raw_Reverse:
Pause timing
Low sck
Let sda_pin=bit7 'Character stored in Raw
Pause timing
High sck
Pause timing
Low sck
Let sda_pin=bit6
Pause timing
High sck
Pause timing
Low sck
Let sda_pin=bit5
Pause timing
High sck
Pause timing
Low sck
Let sda_pin=bit4
Pause timing
High sck
Pause timing
Low sck
Let sda_pin=bit3
Pause timing
High sck
Pause timing
Low sck
Let sda_pin=bit2
Pause timing
High sck
Pause timing
Low sck
Let sda_pin=bit1
Pause timing
High sck
Pause timing
Low sck
Let sda_pin=bit0
High sck
Pause timing
Low sck
Return
Check_Chrs:
Select Case chrs
Case 1
Let cmd=128 ;Line 1, position 1
Gosub Send_Function
Case 2
Let cmd=168 ;Line 2, position 1
Gosub Send_Function
Case 3
Gosub Clear_Disp
Else ' all other text
Gosub Send_Char
EndSelect
Return
HexToAscii:
'converts var1 byte variable to 2 ASCII hex characters, ascii characters returned in var1 and var2
var2 = var1 And $0F 'isolate bottom nibble
If var2 < 10 Then
var2 = $30 + var2
Else
var2 = var2 + 55
endif
var3 = var1 And $F0 'isolate top nibble
var3 = var3 / 16 'moves top 4 bits into bottom 4 bits
If var3 < 10 Then
var3 = $30 + var3
Else
var3 = var3 + 55
endif
var1 = var3
Return