'************************************************************************ 'GLTERM.BAS Terminal application for use with a KS0108 (or compatible) 'graphic LCD controller connected to a Microchip(TM) PIC 16F877 'Written in MELabs PicBasicPro(TM) Ver 3.32 '================== NOT FOR COMMERICIAL USE ============================= ' ' Author: Ranjit Diol - COMPSys LLC, March 2000 ' (c) Copyright Ranjit Diol, 2001 ' ' DISCLAIMER: This file is being released as non-commericial ' freeware. It is being provided "AS IS", neither the author, ' nor COMPSys LLC shall be held liable for any damages caused ' by its use.This application may be used in its entirety or ' in parts within some other application as long as the author ' is given credit for those parts used. ' ' Contact: rsdiol@mich.com for more information ' '************************************************************************ ' IMPORTANT, PLEASE NOTE THE FOLLOWING '************************************************************************ 'This application relies on an ASCII character loaded in the internal '256 byte PIC eeprom. Use the attached file EEPLOAD.BAS to populate the 'internal eeprom with an abbreviated (all upper case) ASCII character set ' 'You may use the utlity BINHEX.EXE to create and easily insert your own 'character set,BINHEX.EXE is available at http://www.compsys1.com/workbench 'You will also find more information on the KS0108 controller at the site. '************************************************************************ ' PIC PINS USED: 'PORTD 8 pins for data (LCD pins 7-14 DB0-DB7) ' 'PORTC Pins 0,1,2,5 by the controller (LCD pins 6,4,5,17 E,CD,RW,RST) ' Pins 3 & 4 are reserved for an I2C ext eeprom, ' Pins 6 & 7 are for the ISP and terminal. ' 'PORTB Pins 1 & 2 are used by the controller (LCD pins 15-16 CS1,CS2) ' Pins 0,3 & 4 available for output ' Pins 5,6 & 7 avaible for input ' 'All remaing pins are available ' 'The OSC speed is 20Mhz, you may change this. However, the STROBE 'subroutine line 'pauseus 6' may need to be tweaked for your OSC speed ' ' 'You may change pin assignments to suit your own needs. ' DEFINE ONINT_USED 1 'Required if ISP is used ADCON1 = 7 'Set pins to digital DEFINE OSC 20 'OSC freq NOTE: For any other 'you may have to change the pauseus 'in the 'Strobe' subroutine dat var PORTD 'LCD data lines 0-7 'LCD Constants (See KS0108 data sheet for more info) 'These Must be set for EACH side '******************************* line_0 con $b8 'LCD Lines 0-7 line_1 con $b9 Line_2 con $ba Line_3 con $bb line_4 con $bc Line_5 con $bd Line_6 con $be Line_7 con $bf disp_off con $3e 'Display off disp_on con $3f 'Display on col con $40 'Column 0-63 disp con $c0 'Display Line at top (disp+1 etc.) ee_offset con $28 'Offset for characters in the eeprom max_col con 128 'Maximum chars per LCD display max_per_side con 64 'Maximum chars per side clr_byte con $00 'Clear byte char_width con $05 'Char width (char = 5x7) char_offset con $04 'LCD control pins e var PORTC.0 'Enable clock cd var PORTC.1 'Command Low / Data High rw var PORTC.2 'Read High / Write Low rst var PORTC.5 'Reset LCD cs1 var PORTB.1 'Left Chip Select High = active cs2 var PORTB.2 'Right Chip Select High = active 'Serial Setup out_pin var PORTC.6 in_pin var PORTC.7 ser_baud con 84 '9600 Baud 'Ouput Pins bport0 var PORTB.0 'Pins available for I/O bport3 var PORTB.3 bport4 var PORTB.4 'Input Pins bport5 var PORTB.5 bport6 var PORTB.6 bport7 var PORTB.7 'Set pins for input TRISB.5 = 1 TRISB.6 = 1 TRISB.7 = 1 'Set Pins for Output TRISB.0 = 0 TRISB.1 = 0 TRISB.2 = 0 TRISB.3 = 0 TRISB.4 = 0 TRISD = 0 TRISC.0 = 0 TRISC.1 = 0 TRISC.2 = 0 TRISC.3 = 0 TRISC.4 = 0 TRISC.5 = 0 cmd var BYTE[2] 'Array for command bytes cmdvar var BYTE 'command variable cpin var BYTE 'command pin inbyte var BYTE 'char from terminal chr var BYTE 'chr to display i var BYTE 'general counter j var BYTE 'general counter k var BYTE 'general counter tmp1 var BYTE 'temp var tmp2 var BYTE 'temp var tmp3 var BYTE 'temp var col_pos var BYTE 'Vertical column position (0-128) line_pos var BYTE 'Line postion (0-7) term_flag var BYTE 'Terminal flag for line 7 tcount var BYTE 'Terminal line character counter col_loc var BYTE 'Column location pin_on var BYTE 'Pin state variable pin_on = 0 chr = 0 dat = 0 i = 0 j = 0 k = 0 col_pos = 0 line_pos = 0 dat = 0 ' Clear PORTD cd = 0 rw = 0 e = 0 cs1 = 1 cs2 = 0 tcount = 0 col_loc = 0 rst = 1 pause 100 'Let things scolilize rst = 0 pause 10 ' Reset LCD rst = 1 pause 600 goto main 'Skip over subroutines '********** (GO)SUBROUTINES ************ 'Toggle E strobe: e = 1 pauseus 6 'Works for a 20MHz osc e = 0 return 'Initialize init: 'Initialization cd = 0 ' Set command mode cs1 = 1 ' Left Side on cs2 = 0 ' Right Side off for i = 1 to 2 dat = disp_off ' Display Off dat = disp ' Ram Line 0 gosub strobe ' Write the data dat = col ' col address = 0 gosub strobe dat = line_0 ' Page = 0 gosub strobe dat = disp_on ' Display On gosub strobe swap cs1,cs2 'switch sides next cs1=1 cs2=0 return 'Initialize Clear all bytes in display ram clearall: cd = 0 ' Command mode dat = disp_off ' Display Off gosub strobe cs1=1 cs2=0 for i = 1 to 2 for j = line_0 to line_7 cd = 0 'Command mode gosub strobe ' Write the data dat = col ' col address = 0 gosub strobe dat = j gosub strobe cd = 1 ' Write mode for k = 1 to max_per_side dat =clr_byte ' Clear the displayed byte gosub strobe next next swap cs1,cs2 'Switch sides next cs1=0 cs2=1 cd=0 dat=line_0 gosub strobe dat = disp ' Ram Line 0 gosub strobe dat=col gosub strobe cs1=1 cs2=0 dat=line_0 gosub strobe dat = disp ' Ram Line 0 gosub strobe dat=col gosub strobe dat = disp_on 'display on gosub strobe cd = 1 ' Set Data command cs1 = 1 ' Left side active cs2 = 0 return 'Display character putchr: cd =1 chr = ((chr - ee_offset)*char_width) k = chr + char_offset for j = chr to k gosub inc_pos read j,dat gosub strobe col_pos=col_pos+1 'Increment position next gosub addspc 'Add a space return 'Add a space addspc: gosub inc_pos dat = clr_byte 'Blank char gosub strobe 'Toggle E col_pos=col_pos+1 'Increment position return 'Set position on display inc_pos: if col_pos = max_per_side then 'Mid screen cs1 = 0 'Switch sides cs2 = 1 cd = 0 'command mode dat = col gosub strobe 'Toggle E cd = 1 endif if col_pos = max_col then 'End of line cs1 = 1 cs2 = 0 line_pos = line_pos +1 col_pos = 0 'Reset col position cd = 0 'command mode dat = col 'Column 0 gosub strobe 'Toggle E cd = 1 'Data mode endif if line_pos = 8 then 'Line can only be 0-7 line_pos = 0 if term_flag = 1 then 'If terminal mode line_pos = 7 'keep at line 7 endif endif cd = 0 'command mode dat = line_0 + line_pos 'Set new line gosub strobe 'Toggle E cd = 1 'Data mode return 'Locates postion on LCD given col_pos and line_pos locate: if col_pos < (max_per_side - 1) then 'Switch to correct side cs1=1 cs2=0 col_loc = col_pos else cs1 =0 cs2 =1 col_loc = col_pos - max_per_side endif cd = 0 'Command mode dat=line_0 + line_pos gosub strobe 'Toggle E dat=col + col_loc gosub strobe 'Toggle E cd = 1 return 'Prints title on first line title: col_pos = 8 line_pos = 0 gosub locate for i= 0 to 19 lookup i,["GRAPHIC LCD TERMINAL"],chr if chr=" " then for j = 1 to 3 gosub addspc next else gosub putchr endif next i 'Draw 2 graphic lines (lines 1 & 4) for j = 1 to 4 step 3 col_pos=0 line_pos =j gosub locate for i = 0 to (max_per_side - 1) dat = $14 gosub strobe next i col_pos=64 gosub locate for i = 0 to (max_col - 1) dat = $14 gosub strobe next i next j col_pos = 0 line_pos = 5 gosub locate for i= 0 to 21 lookup i,["SEND CMDS VIA TERMINAL"],chr if chr=" " then for j = 1 to 3 gosub addspc next else gosub putchr endif next i 'Draw 1 graphic bar at line 6 col_pos=0 line_pos =6 gosub locate for i = 0 to (max_per_side - 1) dat = $3c gosub strobe next i col_pos=64 gosub locate for i = 0 to (max_col - 1) dat = $3c gosub strobe next i col_pos = 0 line_pos = 2 gosub locate for i= 0 to 9 lookup i,["PORTB PINS"],chr if chr=" " then for j = 1 to 3 gosub addspc next else gosub putchr endif next col_pos = 64 line_pos = 2 gosub locate for i= 0 to 10 lookup i,["PORTC STATE"],chr if chr=" " then for j = 1 to 3 gosub addspc next else gosub putchr endif next return 'Clear line 7 routine clearline7: cs1 = 0 cs2 = 1 for i = 1 to 2 cd = 0 dat = line_7 gosub strobe 'Toggle E dat = col gosub strobe 'Toggle E cd = 1 for j = 0 to max_per_side dat = clr_byte gosub strobe 'Toggle E next j swap cs1,cs2 next i cs1 = 1 cs2 = 0 col_pos = 0 line_pos = 7 return 'Terminal command subroutine do_cmds: if cmd[0]= "B" then cpin=cmd[1] - $30 'Convert ASCII to number if cpin = 0 then toggle bport0 tmp1 = line_pos tmp2 = col_pos line_pos = 3 col_pos = 0 gosub locate if PORTB.0=1 then chr = "1" else chr = "0" endif gosub putchr line_pos = tmp1 col_pos = tmp2 gosub locate endif if cpin = 3 then toggle bport3 toggle bport0 tmp1 = line_pos tmp2 = col_pos line_pos = 3 col_pos = 8 gosub locate if PORTB.3=1 then chr = "1" else chr = "0" endif gosub putchr line_pos = tmp1 col_pos = tmp2 gosub locate endif if cpin = 4 then toggle bport4 toggle bport0 tmp1 = line_pos tmp2 = col_pos line_pos = 3 col_pos = 18 gosub locate if PORTB.4=1 then chr = "1" else chr = "0" endif gosub putchr line_pos = tmp1 col_pos = tmp2 gosub locate endif if cpin = 5 then toggle bport5 toggle bport0 tmp1 = line_pos tmp2 = col_pos line_pos = 3 col_pos = 28 gosub locate if PORTB.5=1 then chr = "1" else chr = "0" endif gosub putchr line_pos = tmp1 col_pos = tmp2 gosub locate endif if cpin = 6 then toggle bport6 toggle bport0 tmp1 = line_pos tmp2 = col_pos line_pos = 3 col_pos = 38 gosub locate if PORTB.6=1 then chr = "1" else chr = "0" endif gosub putchr line_pos = tmp1 col_pos = tmp2 gosub locate endif if cpin = 7 then toggle bport7 toggle bport0 tmp1 = line_pos tmp2 = col_pos line_pos = 3 col_pos = 48 gosub locate if PORTB.7=1 then chr = "1" else chr = "0" endif gosub putchr line_pos = tmp1 col_pos = tmp2 gosub locate endif endif chr="B" return 'Checks PORTB Pins 0,3,4,5,6 & 7 (pins 1 & 2 are used by the controller) chk_portb: tmp1 = line_pos 'Save postion tmp2 = col_pos tmp3 = chr line_pos = 3 col_pos = 0 gosub locate if PORTB.0=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 8 gosub locate if PORTB.3=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 18 gosub locate if PORTB.4=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 28 gosub locate if PORTB.5=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 38 gosub locate if PORTB.6=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 48 gosub locate if PORTB.7=1 then chr = "1" else chr = "0" endif gosub putchr line_pos = tmp1 'Restore old values col_pos = tmp2 chr = tmp3 gosub locate return 'Checks PORTC Pin activity 0-7 chk_portc: tmp1 = line_pos 'Save postion tmp2 = col_pos tmp3 = chr line_pos = 3 col_pos = 64 gosub locate if PORTC.0=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 72 gosub locate if PORTC.1=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 80 gosub locate if PORTC.2=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 88 gosub locate if PORTC.3=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 96 gosub locate if PORTC.4=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 104 gosub locate if PORTC.5=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 112 gosub locate if PORTC.6=1 then chr = "1" else chr = "0" endif gosub putchr col_pos = 120 gosub locate if PORTC.7=1 then chr = "1" else chr = "0" endif gosub putchr line_pos = tmp1 'Restore old values col_pos = tmp2 chr = tmp3 gosub locate return '************ 'MAIN PROGRAM '************ main: gosub init gosub clearall 'Initialize and clear display gosub title gosub chk_portb 'Terminal Section col_pos = 0 line_pos = 7 'Setup terminal gosub locate 'for using line 7 cs1=1 cs2=0 cd = 0 dat = col gosub strobe dat = line_7 gosub strobe cd = 1 term_flag = 1 ' Flag to use line 7 only serout2 out_pin,ser_baud,["READY:",10,13] '******************** MAIN TERMINAL LOOP ************************ term: 'Other subroutines can be inserted in this 500ms loop gosub chk_portb 'Check PORTB status gosub chk_portc 'Check PORTC status '**************************************************************** serin2 in_pin, ser_baud,500,term,[chr] ' 500 ms timeout,adjust as needed if chr="]" then 'Check if command key ], if so serout2 out_pin,ser_baud,["CMD:"] serin2 in_pin, ser_baud,[wait ("@"),STR cmd\2] 'get 2 command characters serout2 out_pin,ser_baud,["CMD:", STR cmd\2,10,13] gosub do_cmds 'and branch to the command endif 'sub-routines if chr = $20 then 'If space ($20) then gosub addspc 'add a space endif if (chr<$28) OR (chr> $5a) then term 'Char not in our eeprom ' gosub putchr 'Display the character tcount = tcount + 6 if tcount > 127 then gosub clearline7 tcount = 0 endif goto term 'Do it forever! end '*************** 'END OF PROGRAM '***************