I'm still evaluating options to display info for a revamp of my old Vivarium Controller project, and whilst the tests with an I2C module that piggybacked on the back of a KS0108 GLCD have proved difficult, the other option is to use traditional wiring to the 20 pin header, and with a bit of juggling around I might just be able to free up the extra pins required.
Anyway, I have a MicroElektronica EasyPIC5 board and their 128 x 64 mono (Blue/white) GLCD. Using a 16F877A, 20mhz crystal and their own example HEX program the file loaded and ran through the demo just fine, so I know the hardware works. Now I only have the demo version of Mikro Basic and I can't re-compile the example code for my target PIC and desired OSC speed as it exceeds the limit, so I went hunting for some examples for PBP and came across this - courtesy of Ranjit Diol - (I've changed the LCD pins to match the pinouts of the LCD I have as the original use different ports)
It compiles fine for the 18F4580 I'm using, but I don't get anything on the display... I did notice that some links included a controller board (http://www.piclist.com/techref/io/lcd/ks0108.htm) but then this really is a PIC with MAX232 and EEPROM all on one board so shouldn't really make any difference for the code not to display something ?Code:ASM __CONFIG _CONFIG1H, _OSC_HSPLL_1H __CONFIG _CONFIG2L, _PWRT_ON_2L __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H __CONFIG _CONFIG3H, _PBADEN_OFF_3H __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L ENDASM DEFINE OSC 20 ADCON1 = $0F clear '************************************************************************ ' IMPORTANT, PLEASE NOTE THE FOLLOWING 'This application assumes you have a 64KBit external eeprom connected 'via I2C. Without that you will only be able to send images directly 'to the LCD display and not be able to store them -- See the readme.txt 'for the Windows GLiPIC interface. ' 'Adjust the PIN assignments as neccessary for your prototype 'This was tested using a 20MHz xtal if you use a different OSC speed 'you may have to make some adjustement in the 'strobe' subroutine. '************************************************************************ 'routine's e_pause constant for other speeds ADCON1 = 7 'Make all pins digital, you may adjust as needed lcd_dat VAR PORTD 'LCD bus Pins 7-14 LSB-MSB scl VAR PORTC.3 'I2C SCL for ext eeprom sda VAR PORTC.4 'I2C SDA for ext eeprom in_pin VAR PORTC.7 'Serial input pin out_pin VAR PORTC.6 'Serial output pin lcd_e VAR PORTB.4 'Enable pin on LCD lcd_cd VAR PORTB.2 'Data/Command R/S on LCD lcd_rw VAR PORTB.3 'Read/Write on LCD lcd_cs1 VAR PORTB.0 'ChipSelect1 on LCD lcd_cs2 VAR PORTB.1 'ChipSelect2 on LCD lcd_rst VAR PORTB.5 'Reset Pin on LCD 'Set pins for output TRISB.0 = 0 TRISB.1 = 0 TRISB.2 = 0 TRISD = 0 TRISb.0 = 0 TRISb.1 = 0 TRISb.2 = 0 TRISC.3 = 0 TRISC.4 = 0 TRISb.5 = 0 'Constants used ser_baud CON 84 '9600 baud serout/serin ctl CON $A0 'EEprom control code row CON $b8 'LCD page 0 last_row CON $bf 'LCD page 7 col CON $40 'Line byte position 0 last_col CON 63 'Last column (1-64) first_col CON 0 'First column max_col CON 128 'Last column (1-127) max_line CON 8 'Line 8 (based on 1-8) max_pos CON 64 'Column 64 positon per side (1-64) cr CON 13 'CR for serout lf CON 10 'LF for serout disp_on CON $3f 'LCD Display ON disp_off CON $3e 'LCD Display OFF disp_ram CON $c0 'Ram Display 0 (Page 0 at top of display) blank CON $00 'Blank character e_pause CON 6 'Pauseus 6 for Strobe routine 'Word variables used eepaddr VAR WORD addr VAR WORD 'Arrays used in_array VAR byte[32] in_ctl VAR byte[8] 'Byte Variables used buff_count VAR BYTE 'buffer count hex_nibble VAR BYTE 'hex nibble from serin in_ascii VAR BYTE 'ASCII char from serin buf_cnt VAR BYTE 'buffer counter byte_pos VAR BYTE 'To keep track of a byte's position in_byte VAR BYTE 'The incoming byte tmp VAR BYTE 'Temporary var index VAR BYTE 'Index for arrays j VAR BYTE 'General counter k VAR BYTE 'General counter line VAR BYTE 'An LCD row delay VAR BYTE 'Execution delay, used with 'pause' 'Initialize variables hex_nibble = 0 byte_pos = 0 delay = 10 in_byte = 0 tmp = 0 index = 0 'Reset LCD lcd_dat = 0 ' Clear PORTD lcd_cd = 0 lcd_rw = 0 lcd_e = 0 lcd_cs1 = 1 lcd_cs2 = 0 lcd_rst = 1 pause 100 'Let things stabilize lcd_rst = 0 pause 10 ' Reset LCD lcd_rst = 1 pause 500 'Jump over subroutines to main program goto main ' **** (GO)SUB ROUTINES **** strobe: lcd_e = 1 pauseus e_pause lcd_e = 0 return clearall: lcd_cd = 0 ' Command mode lcd_dat = disp_off ' Display Off gosub strobe lcd_cs1=1 lcd_cs2=0 for index = 1 to 2 for j = row to last_row lcd_cd = 0 'Command mode gosub strobe ' Write the data lcd_dat = col ' Column address = 0 gosub strobe lcd_dat = j gosub strobe lcd_cd = 1 ' Write mode for k = first_col to last_col lcd_dat = blank gosub strobe next next swap lcd_cs1,lcd_cs2 next lcd_cs1=0 lcd_cs2=1 lcd_cd=0 lcd_dat=row gosub strobe lcd_dat = disp_ram ' Ram Line 0 gosub strobe lcd_dat=col gosub strobe lcd_cs1=1 lcd_cs2=0 lcd_dat=row gosub strobe lcd_dat = disp_ram ' Ram Line 0 gosub strobe lcd_dat=col gosub strobe lcd_dat = disp_on 'display on gosub strobe lcd_cd = 1 ' Set Data command lcd_cs1 = 1 ' Left side active lcd_cs2 = 0 return init: 'Initialization lcd_cd = 0 ' Set command mode lcd_cs1 = 1 ' Left Side on lcd_cs2 = 0 ' Right Side off for index = 1 to 2 lcd_dat = disp_off ' Display Off lcd_dat = disp_ram ' Ram Line 0 gosub strobe ' Write the data lcd_dat = col ' Y address = 0 gosub strobe lcd_dat = row ' Page = 0 gosub strobe lcd_dat = disp_on ' Display On gosub strobe swap lcd_cs1,lcd_cs2 next lcd_cs1=1 lcd_cs2=0 return '****Place char on LCD Routine ***** 'Place byte of data on lcd assumes in_byte, byte_pos and line (line) 'Char position on LCD byte_pos = 0-127 (Horiz), ROW 0-7 (vert) putbyte: lcd_dat = in_byte 'Display the byte gosub strobe byte_pos=byte_pos+1 'Increment position 'Now do some LCD house cleaning and adjust counters if byte_pos=max_pos then lcd_cs1=0 lcd_cs2=1 lcd_cd = 0 lcd_dat = col gosub strobe lcd_dat = disp_ram gosub strobe lcd_dat = row + line gosub strobe lcd_cd = 1 endif if byte_pos = max_col then 'Check if line = line + 1 'New Line if line = max_line then line = 0 endif byte_pos = 0 'Reset byte_pos lcd_cs1=1 lcd_cs2=0 lcd_cd = 0 lcd_dat=col gosub strobe lcd_dat = row + line gosub strobe lcd_dat = disp_ram gosub strobe lcd_cd =1 endif return '***** Convert incoming ascii to hex byte Routine ***** find: Lookdown in_array[index],["0123456789abcdef"],hex_nibble return '=============================== ' **** BEGIN MAIN PROGRAM ****** '=============================== main: gosub init ' Initialize LCD gosub clearall ' Clear all pages goto term logo: gosub init ' Initialize LCD gosub clearall ' Clear all pages '**** DISPLAY IMAGES IN EXTERNAL 64KBit EEPROM VIA I2C ***** ' Load opening screen from eeprom assuming a 64KBit eeprom byte_pos=0 line =0 for addr = 0 to 8192 'Eight 1kbyte pages of eeprom I2CREAD sda,scl,ctl,addr,[in_byte] gosub putbyte if (addr=1024) OR (addr=2048) OR (addr= 3072) OR (addr=4096) OR (addr=5120) OR (addr=6144) OR (addr=7168) OR (addr=8192) then pause 4000 gosub init gosub clearall endif if addr=8192 then addr = 0 endif next goto logo 'Continue looping inifitum! '******************************************** 'Terminal Subroutine term: 'Assumes Home Position 'Setup variables j=0 index=0 k=0 line=0 addr=0 in_ascii = 0 buff_count = 32 delay = 10 addr = 0 byte_pos = 0 'Get the initial parameters get_param: serin2 in_pin,ser_baud,[wait ("*"),STR in_ctl\9] for index = 0 to 8 Lookdown in_ctl[index],["0123456789abcdef"],hex_nibble in_ctl[index]=hex_nibble next delay = (in_ctl[7]<<4) | in_ctl[8] buff_count = (in_ctl[1]<<4) | in_ctl[2] addr.byte1 = (in_ctl[3] <<4) | in_ctl[4] addr.byte0 = (in_ctl[5] <<4) | in_ctl[6] buf_cnt = (buff_count - 1) eepaddr = addr j=in_ctl[0] if j = 0 then lcd_loop 'Display directly on LCD if j = 1 then eep_loop 'Load ext eeprom if j = 2 then logo 'Display images loop goto get_param eep_loop: serin2 in_pin,ser_baud,[wait ("]"),STR in_array\buff_count] 'Wait for ] and the load in_array for index = 0 to buf_cnt 'Get char and place in array Lookdown in_array[index],["0123456789abcdef"],hex_nibble in_array[index]=hex_nibble next for index = 0 to buf_cnt step 2 in_byte = (in_array[index]<<4) | (in_array[index+1]) 'Form a hex number MSB-LSB I2CWRITE sda,scl,ctl,eepaddr,[in_byte] pause 10 eepaddr=eepaddr+1 next goto eep_loop lcd_loop: serin2 in_pin,ser_baud,[wait ("]"),STR in_array\buff_count] 'Wait for ] and the load in_array for index = 0 to (buff_count - 1) gosub find 'Get char and place in array in_array[index]=hex_nibble next for index = 0 to (buff_count - 1) step 2 in_byte = (in_array[index]<<4) | (in_array[index+1]) 'Form a hex number MSB-LSB gosub putbyte next goto lcd_loop
All I'm really after is for the GLCD to behave as if it were an 8 line x 21 character display - nothing fancy, but on an 18F4580 running at 40 Mhz off a 20 Mhz xtal.... if someone could suggest a simple equivalent of the "hello world"LCD code, or correct me if there are any reasons why this seems such a steep hill to climb with PBP I would be most obliged
Malcolm
Bookmarks