; AXE133 Serial LCD/OLED using PICAXE-18M2
; Emulates basic serial operation of the popular AXE033 module
; CPS, May 2011
; v2 18/01/2012
#picaxe 18M2
; ********************************************
; Note you must uncomment just one of these two options
; depending on whether you have an LCD or OLED module
'#define use_OLED
#define use_LCD
; ********************************************
; Supported Commands
; 0-7, 8-15 CGRAM characters
; 16-252 normal ASCII characters, according to selected character map table
; 253, X display 16 character pre-saved message from EEPROM memory, X can be 0-15
; 254, X LCD command, X can be 0 to 255
; 255, X control outputs C.2, C.1, C.0 (via lower 3 bits of X)
; So, if using a backlit LCD with the active low transistor driver
; on output C.2, then 255,%000 switches backlight on and 255,%100 switches off
#define use_welcome ; display the welcome message upon power up
symbol line_length = 16 ; change to 20 for displays with 20 character lines
symbol baud = N2400_16 ; Serial baud rate 2400,N,8,1. Note main program runs at 16MHz
symbol spare0 = C.0 ; spare output 0
symbol spare1 = C.1 ; spare output 1
symbol spare2 = C.2 ; spare output 2 (or optional backlight)
symbol backlight = C.2 ; optional backlight control for backlit LCDs, active low
symbol RX = C.5 ; serial receive pin
symbol enable = C.6 ; LCD enable
symbol rs = C.7 ; LCD RS
; LCD data pins are on B.0 to B.7
; Store the 16 character user defined messages in EEPROM data memory
; First two messages are optionally used as welcome message
; If using a display with 20 characters you will need to edit
; the start addresses to be multiples of 20 (currently at 16)
; and add 4 characters to each message.
; Please remember 4 line displays always use the strange 1-3-2-4 layout.
#ifdef use_OLED
EEPROM $00, (" Serial OLED ") ; store msg in the EEPROM memory
#else
EEPROM $00, (" Serial LCD ") ; store msg in the EEPROM memory
#endif
EEPROM $10, (" www.picaxe.com ") ; store msg in the EEPROM memory
EEPROM $20, ("This is msg 2 ") ; store msg in the EEPROM memory
EEPROM $30, ("This is msg 3 ") ; store msg in the EEPROM memory
EEPROM $40, ("This is msg 4 ") ; store msg in the EEPROM memory
EEPROM $50, ("This is msg 5 ") ; store msg in the EEPROM memory
EEPROM $60, ("This is msg 6 ") ; store msg in the EEPROM memory
EEPROM $70, ("This is msg 7 ") ; store msg in the EEPROM memory
EEPROM $80, ("This is msg 8 ") ; store msg in the EEPROM memory
EEPROM $90, ("This is msg 9 ") ; store msg in the EEPROM memory
EEPROM $A0, ("This is msg 10 ") ; store msg in the EEPROM memory
EEPROM $B0, ("This is msg 11 ") ; store msg in the EEPROM memory
EEPROM $C0, ("This is msg 12 ") ; store msg in the EEPROM memory
EEPROM $D0, ("This is msg 13 ") ; store msg in the EEPROM memory
EEPROM $E0, ("This is msg 14 ") ; store msg in the EEPROM memory
EEPROM $F0, ("This is msg 15 ") ; store msg in the EEPROM memory
;initialise LCD
init:
gosub LCD_init ; initialise LCD
; display welcome message if desired
#ifdef use_welcome
let b1 = 0 ; message 0 on top line
gosub msg ; do it
low rs ; command mode
let pinsB = 192 ; move to line 2, instruction 192
pulsout enable,1 ; pulse the enable pin to send data.
high rs ; character mode again
let b1 = 1 ; message 1 on bottom line
gosub msg ; do it
#endif
; main program loop, runs at 16MHz
main:
serin RX,baud,b1 ; wait for the next byte
; NB keep character mode test as first item in this list to optimise speed
if b1 < 253 then
let pinsB = b1 ; output the data
pulsout enable,1 ; pulse the enable pin to send data.
goto main ; quickly loop back to top
else if b1 = 254 then
low rs ; change to command mode for next character
serin RX,baud,b1 ; wait for the command byte
let pinsB = b1 ; output the data
pulsout enable,1 ; pulse the enable pin to send data.
high rs ; back to character mode
goto main ; quickly loop back to top
else if b1 = 253 then
serin RX,baud,b1 ; wait for the next byte
gosub msg ; do the 16 character message
goto main ; back to top
else ; must be 255
serin RX,baud,b1 ; wait for the next byte
let pinsC = b1 & %00000111 | %10000000
; output the data on C.0 to C.1, keep RS high
goto main ; back to top
end if
; power on LCD initialisation sub routine
LCD_init:
let dirsC = %11000111 ; PortC 0,1,2,6,7 all outputs
let dirsB = %11111111 ; PortB all outputs
#ifdef use_OLED
; Winstar OLED Module Initialisation
; according to WS0010 datasheet (8 bit mode)
pause 500 ; Power stabilistation = 500ms
; Function set - select only one of these 4 character table modes
;let pinsB = %00111000 ; 8 bit, 2 line, 5x8 , English_Japanese table
'let pinsB = %00111001 ; 8 bit, 2 line, 5x8 , Western_European table1
'let pinsB = %00111010 ; 8 bit, 2 line, 5x8 , English_Russian table
let pinsB = %00111011 ; 8 bit, 2 line, 5x8 , Western_European table2
pulsout enable,1 ;
let pinsB = %00001100 ; Display on, no cursor, no blink
pulsout enable,1
let pinsB = %00000001 ; Display Clear
pulsout enable,1
pause 7 ; Allow 6.2ms to clear display
setfreq m16 ; now change to 16Mhz
let pinsB = %00000010 ; Return Home
pulsout enable,1
let pinsB = %00000110 ; Entry Mode, ID=1, SH=0
pulsout enable, 1
#else
; Standard LCD Module Initialisation
pause 15 ; Wait 15ms for LCD to reset.
let pinsB = %00111000 ; 8 bit, 2 line
pulsout enable,1 ; Send data by pulsing enable
pause 5 ; Wait 5 ms
pulsout enable,1 ; Send data 48 again
pulsout enable,1 ; Send data 48 again
setfreq m16 ; now change to 16Mhz
'let pinsB = %00111000 ; LCD - 8 bit, 2 line, 5x8
'pulsout enable,1
let pinsB = %00000001 ; Clear Display
pulsout enable,1
pause 8 ; 8 = 2ms at 16MHz
let pinsB = %00000010 ; return home
pulsout enable,1
let pinsB = %00000110 ; Entry mode
pulsout enable,1
pause 1
let pinsB = %00001100 ; Display on, no cursor, no blink
pulsout enable,1
#endif
high rs ; Leave in character mode
return
; display message from EEPROM sub routine
; message number 0-15 must be in b1 when called
; uses (alters) b1, b2, b3, b4
msg:
let b2 = b1 & %00001111 * line_length
; EEPROM start address is 0 to 15 multiplied by 16
let b3 = b2 + line_length - 1 ; end address is start address + (line_length - 1)
for b4 = b2 to b3 ; for 16 times
read b4,b1 ; read next character from EEPROM data memory into b1
let pinsB = b1 ; output the data
pulsout enable,1 ; pulse the enable pin to send data.
next b4 ; next loop
return
; Check end user has defined just one type of display
#ifndef use_OLED
#ifndef use_LCD
#error "Oops - no OLED / LCD type defined at top of program!"
#endif
#endif
#ifdef use_OLED
#ifdef use_LCD
#error "Oops - both OLED / LCD types defined at top of program!"
#endif
#endif