#include errorlevel -203, -205 ,-207 ;************************************************************************************** ;** THIS DEFINITIONS CAN BE CHANGED BY USER ;** ;** REMEMBER THAT KS0108_data and its associated TRIS register SHOULD BE A COMPLETE 8 BIT ;** PORT ;** REGISTER ASSOCIATED WHITH E, RW, RS SHALL HAVE THEIR TRIS DEFINITION ;** ;** ;** ;** ;************************************************************************************** #define KS0108_data PORTD ; LCD data bits (port wired to D0-D7) - in this case port D #define KS0108_tris TRISD ; LCD data direction - Thisi is TRISS register associated to KS0108_data port #define KS0108_E PORTC, 6 ; LCD E clock (pin wired to E line) #define KS0108_RW PORTC, 5 ; LCD read/write line (pin wired to RW line) #define KS0108_RS PORTC, 4 ; LCD register select line (pin wired to RS line) #define KS0108_E_DIR TRISC, 6 ; E line associated TRIS bit #define KS0108_RW_DIR TRISC, 5 ; RW line associated TRIS bit #define KS0108_RS_DIR TRISC, 4 ; RS line associated TRIS bit #define KS0108_CS1 PORTB,0 ; CS1 line (pin wired to CS1 line) #define KS0108_CS2 PORTB,1 ; CS2 line (pin wired to CS2 line) #define KS0108_CS1_DIR TRISB,0 ; CS1 line associated TRIS bit #define KS0108_CS2_DIR TRISB,1 ; CS2 line associated TRIS bit #define MCUCLK Nop4 ; delay time for data settiling: select Nop4 for CPUCLK > = 20 MHZ else select Nop0 udata KS0108_out res 1 ;var to put in data to be displayed KS0108_X res 1 ; X pos to turn on pixel KS0108_Y res 1 ; Y POS TO TURN ON PIXEL KS0108_COL res 1 ; RAW KS0108_RAW res 1 ; COL KS0108_busyflag res 1 ; status flags (local) KS0108_IN res 1 ; data input from KS0108 temp res 1 temp1 res 1 x res 1 y res 1 timer res 1 ;******************** global vars to create library global KS0108_out ;data to send to KS0108 global KS0108_X ;X pixel pos (0 o 127) global KS0108_Y ;Y pixel pos (0 to 63) global KS0108_COL ; Coloumn (o to 7) global KS0108_RAW ;raw (0 to 127) - chip select done by program global KS0108_IN ; data read from KS0108 ;****************** reset vector org 0x0000 goto main org 0x0004 code retfie ; **************** program example main call KS0108init ; inits display ;***** fills display whith byte pattern from 255 to 1 movlw 0xff movwf KS0108_out ; puts value 0xff in KS0108_out (var used to put data on main1 call KS0108fill decfsz KS0108_out,F goto main1 ;traces a line from (127,63) to (1,0) movlw .127 movwf KS0108_X traceline movf KS0108_X,W rrf KS0108_X,W bcf STATUS,C movwf KS0108_Y call KS0108_pixon decfsz KS0108_X,F goto traceline main2 goto main2 ; infinite loop ;**************************** end program example ;****************** DRIVER SUBROUTINES ;****************** init ports and values KS0108init banksel KS0108_tris ; sets ports TRIS registers bcf KS0108_E_DIR bcf KS0108_RW_DIR bcf KS0108_RS_DIR bcf KS0108_CS1_DIR bcf KS0108_CS2_DIR clrf KS0108_tris banksel KS0108_data ; reset to 0 all ports values bcf KS0108_E bcf KS0108_RW bcf KS0108_RS bcf KS0108_CS1 bcf KS0108_CS2 clrf KS0108_data ;********************* selects and initailizes chip 1 bsf KS0108_CS1 bcf KS0108_CS2 movlw 0x3f ; 0xef is init command call KS0108commandW ; KS0108commandw is a part of KS0108command instruction and doesn't need data to be ;stored in KS0108_out, but uses data in W register ; it's used by internal driver routines movlw 0xc0 ;0xc0 sets start display line to 0 call KS0108commandW ;******************** selects and initailizes chip2 (as for chip 1) bcf KS0108_CS1 bsf KS0108_CS2 movlw 0x3f call KS0108commandW movlw 0xc0 call KS0108commandW bcf KS0108_CS1 bcf KS0108_CS2 ;******************** clears GLCD (fill whith 0x00) movlw 0x00 movwf KS0108_out ; KS0108_out is var used to output data bytes to glcd, now it's set to 0 call KS0108fill ; executes "fill" instruction return ; KS0108fill routine ***************** fill GLCD whith data stored in KS0108_out KS0108fill BSF KS0108_CS1 BCF KS0108_CS2 fill_1 ;here starts loop 1 that will be repeated one time per chip MOVLW 0x08 ; init raw loop from 8 to 1 note thata x and y are internal and not global vars MOVWF y fill_2 decf y,W ;as i'm countig from 8 to 1, but I need selecr raws from 7 to 0, I decrement y and ;put it in w ADDLW 0xB8 ; to select a raw, command is 0xb8 + raw number CALL KS0108commandW ; sends command to select raw MOVLW 0x40 ;command to selects a coloumn is 0x40 + coloumn number, I start from 0 CALL KS0108commandW ; send command to select coloumn MOVWF x fill_3 movf KS0108_out ,W CALL KS0108writeW ;displays on selected raw, coloumn data stored in KS0108_out ;decrements and goes on displaying data ( I don't need to select coloumns every time ;as KS0108 auto increments coloumn number every write operation) DECFSZ x,F ; repeats fill_3 64 times ( from 0 to 63) GOTO fill_3 DECFSZ y,F ; repeats fill_2 8 tines (for coloumns from 7 to 0) GOTO fill_2 BTFSS KS0108_CS1 ;if chip 2 is selected (chip 1 cleared) ends GOTO fillend MOVLW 0xC0 ;0xC0 is "home command" CALL KS0108commandW BCF KS0108_CS1 ;else selects chip 2 BSF KS0108_CS2 GOTO fill_1 ;repeats loop fillend MOVLW 0xC0 CALL KS0108commandW BCF KS0108_CS1 BCF KS0108_CS1 RETURN global KS0108fill ;****************** Write command to KS0108 KS0108command movf KS0108_out,W KS0108commandW ; procedure using data in WREG bcf KS0108_RS ;clears RS line bcf KS0108_RW ;clears RW line bsf KS0108_E ;Enable high to lock command lines status movwf KS0108_data ;data on D0-D7 call MCUCLK ; wait KS0108 data settiling time bcf KS0108_E ; Enable low nop ; 1 cycle settiling time call KS0108_ready ; check busy flag ( if clock is less than 12 MHz it shall be omitted) return global KS0108command ;***************** write data to KS0108 (for comments wiew KS0108command ) KS0108write movf KS0108_out,W KS0108writeW bsf KS0108_RS bcf KS0108_RW bsf KS0108_E movwf KS0108_data call MCUCLK bcf KS0108_E bcf KS0108_RS call KS0108_ready return global KS0108write ;****************** read data from KS0108 and put it in KS0108_IN KS0108_read ; read from display routine bsf KS0108_RS ; RS and RW lines must be ""HIGH" bsf KS0108_RW bsf KS0108_E ; Enable high to lock command lines call MCUCLK ; waits ..... bcf KS0108_E ;Enable line low call KS0108_ready ; waits display to be ready bsf KS0108_RW ;Read command shall be repeated 2 times as 1st time KS0108 puts data on latch and ;2nd time puts them on D0-D7 (1st time read is a "dummy" read) bsf KS0108_RS bsf KS0108_E banksel KS0108_tris ; make D0-D7 port an input movlw 0xff movwf KS0108_tris banksel KS0108_data movf KS0108_data,W ; reads data movwf KS0108_IN ; puts data on KS0108_IN banksel KS0108_tris clrf KS0108_tris banksel KS0108_data bcf KS0108_E bcf KS0108_RW bcf KS0108_RW call KS0108_ready ; check busy flag ( if clock is less than 12 MHz it could be omitted) return global KS0108_read ;************ check KS0108 busy flag ( checks if GLCD is ready) ; note that KS0108 will ALWAYS answer to this command, also if it's doing something else ;***************************** MORE COMMENTS NEXT TIME..... KS0108_ready movwf temp1 clrf KS0108_data readyflag1 bcf KS0108_RS bsf KS0108_RW bsf KS0108_E bsf STATUS,RP0 movlw 0xff movwf KS0108_tris bcf STATUS,RP0 movf KS0108_data movwf KS0108_busyflag bsf STATUS,RP0 clrf KS0108_data bcf STATUS,RP0 call Nop4 bcf KS0108_E btfss KS0108_busyflag,7 goto readyflag1 bcf KS0108_RW movf temp1 return ; wait cycle (quite stupid way, but timigs are perfect) Nop20 nop nop nop nop nop nop nop nop nop nop nop nop nop Nop8 nop nop nop nop Nop4 nop nop nop nop Nop0 return ;************** turn on a pixel x = KS0108_X y= KS0108_Y KS0108_pixon call KS0108_pos ; selects raw, coloumn call KS0108_read ;reads data already displayed movf KS0108_Y,W andlw 0x07 call pixtable iorwf KS0108_IN call KS0108_posX movf KS0108_IN,W call KS0108writeW return global KS0108_pixon ;************** turn off a pixel x = KS0108_X y= KS0108_Y KS0108_pixoff call KS0108_pos call KS0108_read movf KS0108_Y,W andlw 0x07 call pixtable movwf temp negf temp,W andwf KS0108_IN,W call KS0108_posX movf KS0108_IN,W call KS0108writeW return global KS0108_pixoff ; ********** reads KS0108_X and KS0108_Y and selects right chip, raw, coloumn KS0108_pos btfss KS0108_X,6 goto KS0108_pos1 bcf KS0108_CS1 bsf KS0108_CS2 goto KS0108_pos2 KS0108_pos1 bsf KS0108_CS1 bcf KS0108_CS2 KS0108_pos2 movf KS0108_Y,W movwf temp rrf temp,F bcf STATUS,C rrf temp,F bcf STATUS,C rrf temp,W iorlw 0xb8 call KS0108commandW KS0108_posX movf KS0108_X,W iorlw 0x40 call KS0108commandW return ; ********** reads KS0108_RAW and KS0108_COL and selects chip, raw, coloumn KS0108_pos btfss KS0108_COL,6 goto KS0108_pos1 bcf KS0108_CS1 bsf KS0108_CS2 goto KS0108_pos2 KS0108_pos1 bsf KS0108_CS1 bcf KS0108_CS2 KS0108_pos2 movf KS0108_RAW,W iorlw 0xb8 call KS0108commandW movf KS0108_COL,W iorlw 0x40 call KS0108commandW return ;******************** part of pixon... selects pixel on byte pixtable addwf PCL,F ;add offset to pc to retlw 0x01 retlw 0x02 retlw 0x04 retlw 0x08 retlw 0x10 retlw 0x20 retlw 0x40 retlw 0x80 end