'I2C LCD SPEED TEST.BAS 'BY NoRoHS 'BASIC INTERFACING WITH AN ARDUINO I2C LCD GY-LCD-V1 20x4 LCD MODULE 'TARGET PIC 12F629 'PRINTS THE NUMBERS (0 THROUGH 65535) ON THE LCD AS FAST AS IT CAN 'RESULT IS ABOUT 800CPS COM SPEED AND DISPLAY VALUE UPDATE IS 120 TIMES A SECOND 'SET PROGRAMMER FOR POWER-UP TIMER ENABLE AND HS CLOCKING (20MHZ) AND NO WDT '352 WORDS USED 'TESTED AND CONFIRMED ON LAST SAVE/COMPILE 11/11/12 ' ' ' |<============ NO NEED FOR 4.7k PULLUP RESISTORS - ' | |<======== 10K'S ARE ON ARDUINO I2C LCD MODULE'S BACKBOARD ' | | ' GND SDA SCL N/C ' __|___|___|___|__ ' | 8 7 6 5 | ' > PIC12F629 | ' |__1___2___3___4__| ' | | | | ' +5V X-TAL N/C ' ' METHOD OF OPERATION: ' USES BYTE VARIABLE (NUM_GEN) TO STEP THROUGH ALL 65536 VALUES AND PRINT ' THIS NUMBER ON THE FIRST LINE. EACH NUMBER IS CONVERTED TO A ' DIGIT VALUE AND PADDED BY ADDING 48 THE RESULTS TO CONVERT IT TO ASCII. ' SINCE THIS IS AN I2C COM, THE LCD IS IN THE 4-BIT MODE AND DATA IS MOVED ' USING THE 4-BIT FORMAT, REQUIRING THE SHIFTING AND MASKING OF DATA FOR ' EACH COMMAND/VALUE SENT. ' ' THIS IS A 'CHOPPED' PROGRAM FROM ANOTHER ONE AND MOST OF THE UN-NEEDED ' PROGRAM INFORMATION HAS BEEN REMOVED, BUT SOME MAY STILL REMAIN. ' ' THE FOLLOWING HELPS EXPLAIN THE 12C TO 4-BIT MODE DATA CONVERSION PROCESS: ' ' ' vvvvvvv (FROM FIRST DEMO PROGRAM - RELEVENT - FOR REFERENCE ONLY) vvvvvvvv ' *************************************************************************** ' * * ' * WRITING TO LCD MODULE WITH I2C FORMAT: (I2CWRITE D,C,ADDR,[LCD_DAT]) * ' * * ' *************************************************************************** ' * * ' * *REMEMBER, EVEN THOUGH THE LCD IS SET FOR 4-BIT MODE, IN I2C WE ARE * ' * ALWAYS SENDING 8 BITS OF DATA WITH EVERY I2CWRITE COMMAND * ' * * ' * *HIGH NIBBLE MEANS THE HIGHEST 4 BITS OF A BYTE * ' * *LOW NIBBLE MEANS THE LOWEST 4 BITS OF A BYTE * ' * * ' * *LCD_DAT Variable IS A BYTE - VALUE MAYBE CODED IN HEX ($xy) * ' * FOR EASY READING * ' * * ' * *HIGH NIBBLE OR THE x IN $xy IS THE LCD MODULE FUNCTION PINS (4 BITS) * ' * *LOW NIBBLE OR THE y IN $xy IS THE LCD DATA PINS (4 BITS) * ' * * ' * *HIGH NIBBLE (FUNCTION NIBBLE)(x IN $xy) EX:($4y OR %0100yyyy) CONTAINS* ' * LCD_DAT.Bit7 = BACKLIGHT LED ON/OFF (1 = OFF, 0 = ON)(NOT A MISPRINT)* ' * LCD_DAT.Bit6 = RS (1 = DATA, 0 = INSTRUCTION) * ' * LCD_DAT.Bit5 = R/W (1 = READ, 0 = WRITE) * ' * LCD_DAT.Bit4 = E (1 = ENABLE, 0 = INHIBIT) * ' * * ' * **NOTE THAT EVERY TRANSMISSION OF DATA WILL INCLUE INFORMATION ABOUT * ' * THESE FUNCTIONS. IN THIS EXAMPLE, SETTING THESE PINS (IF NEEDED) * ' * MUST BE DONE AFTER CONSTRUCTING THE DATA TO BE SENT. MASKING AND * ' * SHIFTING NEEDED TO CONSTRUCT THE LOWER NIBBLE MEANS THESE BITS ARE * ' * ALWAYS SET TO "0" AFTER THE DATA IS CONSTRUCTED. * ' * * ' * *LOW NIBBLE (DATA NIBBLE) (THE y IN $xy) EX:($x8 OR %xxxx1000) CONTAINS* ' * LCD_DAT.Bit3 = DATA BIT 3 (MSB) * ' * LCD_DAT.Bit2 = DATA BIT 2 * ' * LCD_DAT.Bit1 = DATA BIT 1 * ' * LCD_DAT.Bit0 = DATA BIT 0 (LSB) * ' * * ' * *LCD_DAT IS SENT OUT IN TWO WRITES USING I2CWRITE(**) * ' * SEND OUT THE HIGH NIBBLE OF THE DATA FIRST: * ' * LCD_DAT = FUNCTION + DATA(HIGH NIBBLE) > I2CWRITE * ' * LATCH DATA TO LCD MODULE (ENABLE BIT SET/RELEASE) > RETURN * ' * SEND OUT THE LOW NIBBLE OF THE DATA SECOND: * ' * LCD_DAT = FUNCTION + DATA (LOW NIBBLE) > I2CWRITE * ' * LATCH DATA TO LCD MODULE (ENABLE BIT SET/RELEASED) > RETURN * ' * * ' * **NOTE: * ' * THE FIRST TIME THE MODULE IS ADDRESSED IT IS IN THE 8-BIT MODE. * ' * THESE COMMANDS MUST BE THE FIRST SENT TO THE LCD MODULE TO PUT * ' * IT IN THE 4-BIT MODE: * ' * * ' * LCD_DAT = $02 * ' * GOSUB LCDWRITE * ' * GOSUB LCDWRITE * ' * LCD_DAT = $08 * ' * GOSUB LCDWRITE * ' * * ' * *EXAMPLE: (SENDING THE CHARACTER "H") * ' * * THE CHARACTER "H" IN HEX IS $48 * ' * * SEND THE HEX '4' FIRST, THEN THE HEX '8' SECOND * ' * * EACH TIME THEY ARE SENT, THEY ARE COMBINED WITH THE FUNCTION * ' * HIGH NIBBLE (REPRESENTED AS x IN $xy) * ' * * FOR THIS EXAMPLE: FUNCTION = $4y OR %0100yyyy OR $40 (MASKED) * ' * WHICH IS LED = ON, RS = DATA, R/W = WRITE, E = INHIBIT * ' * * SO, SENDING THE HEX DATA IN THIS EXAMPLE OF "H" IS: * ' * LCD_DAT = $44, LCDWRITE, FOLLOWED BY LCD_DAT = $48, LCDWRITE * ' * * THE SUB LCDWRITE WILL SEND LCD_DAT VIA I2C TO THE ARDUINO MODULE * ' * AND THEN TOGGLE THE 'E'(ENABLE) BIT ON AND OFF TO 'LATCH' THE DATA* ' * INTO THE LCD MODULE. THIS IS WHY LCDWRITE HAS 3 I2CWRITE'S IN IT. * ' * * ' *************************************************************************** ' ' Define OSC 20 'USE EXTERNAL 20MHZ CRYSTAL (PINS 2 AND 3) 'DEFINE I2C_SLOW 1 'SEEMS TO WORK FASTER AND WELL IN THE FASTER MODE CMCON = $7 'SET COMPARITOR PORTS TO DIGITAL MASK CON $0F 'SET MASK TO %00001111 TO CLEAR TOP NIBBLE C VAR GPIO.1 'IC PIN 6 IS SCL D VAR GPIO.0 'IC PIN 7 IS SDA ADDR VAR BYTE 'HOLDER FOR I2C ADDRESS LCD_DAT VAR BYTE 'HOLDER FOR I2C LCD MODULE DATA ***SEE ABOVE ^ FCHAR VAR BYTE 'CHARICTOR OR COMMAND TO BE SENT FTEMP VAR BYTE 'NEEDED TO MANIPULATE FCHAR AND PRESERVE FCHAR VALUE E VAR LCD_DAT.BIT4 'HOLDER FOR ENABLE BIT (xxxE xxxx) RS VAR LCD_DAT.BIT6 'HOLDER FOR REGISTER SELECT BIT (xRSxx xxxx) NUM_GEN VAR WORD 'LOOP COUNTER HOLDER FOR THE VALUE TO BE DISPLAYED NUM_GEN = 0 'MAKE SURE VALUE STARTS AT 0 (REDUNDENT) ADDR = $40 'SET I2C 7 BIT ADDRESS $20 + A '0' FOR PBP BYTE VALUE LCD_DAT = $00 'PRESET LCD_DAT VALUE TO 0 TO BE SURE E = 0 'PRESET ENABLE AND REGISTER SELECT BITS TO O RS = 0 ' (ALSO TO BE SURE) PAUSE 1000 'WAIT 1 SECOND FOR THE LCD MODULE TO RESET '*************** 'LCD MODULE SETUP STARTS HERE ************************** LCD_DAT = $02 'SETUP LCD MODULE FOR 4-BIT MODE GOSUB LCDWRITE GOSUB LCDWRITE 'NOTE: MUST SEND $02 TWICE LCD_DAT = $08 GOSUB LCDWRITE LCD_DAT = $00 'DISP ON, CURS ON, NO BLINK UPPER NIBBLE GOSUB LCDWRITE '...SEND LCD_DAT = $0E 'DISP ON, CURS ON, NO BLINK LOWER NIBBLE GOSUB LCDWRITE '...SEND LCD_DAT = $00 'SETUP ENTRY MODE UPPER NIBLE GOSUB LCDWRITE '...SEND LCD_DAT = $06 'SETUP ENTRY MODE LOWER NIBLE GOSUB LCDWRITE '...SEND LCD_DAT = $00 'RETURN TO HOME UPPER NIBLE GOSUB LCDWRITE '...SEND LCD_DAT = $02 'RETURN TO HOME LOWER NIBLE GOSUB LCDWRITE '...SEND '**************** LCD MAIN DISPLAY LOOP STARTS HERE ********************* MAIN: fOR NUM_GEN = 0 TO 65535 'MAIN LOOP COUNTER AND NUMBER TO BE DISPLAYED FCHAR = NUM_GEN DIG 4 'THE NEXT 17 LINES ARE USED TO CALCULATE THE FCHAR = FCHAR + 48 'ASCII VALUE TO BE SENT TO THE LCD DISPLAY... GOSUB CONSTRUCT_CHAR FCHAR = NUM_GEN DIG 3 FCHAR = FCHAR + 48 GOSUB CONSTRUCT_CHAR FCHAR = "," 'NO ASCII CONVERSION NEEDED FOR " , " GOSUB CONSTRUCT_CHAR FCHAR = NUM_GEN DIG 2 FCHAR = FCHAR + 48 GOSUB CONSTRUCT_CHAR FCHAR = NUM_GEN DIG 1 FCHAR = FCHAR + 48 GOSUB CONSTRUCT_CHAR FCHAR = NUM_GEN DIG 0 FCHAR = FCHAR + 48 GOSUB CONSTRUCT_CHAR LCD_DAT = $00 'SEND UPPER NIBBLE 'RETURN TO HOME' COMMAND GOSUB LCDWRITE LCD_DAT = $02 'SEND LOWER NIBBLE 'RETURN TO HOME' COMMAND GOSUB LCDWRITE nEXT NUM_GEN 'NEXT NUMBER TO BE DISPLAYED... UNTIL 65535 PAUSE 2000 'PAUSE 2 SECONDS WHEN NUM_GEN ROLLS OVER GOTO MAIN 'LOOP FOREVER '************ CONSTRUCT_CHAR SUB- CONSTRUCT CHARICTERS AND SEND OUT ************ CONSTRUCT_CHAR: FTEMP = FCHAR 'MOVE THE UPPER NIBBLE TO THE LOWER NIBBLE FTEMP = FTEMP >> 4 ' (UPPER NIBBLE IS SENT FIRST IN 4-BIT MODE) LCD_DAT = FTEMP 'NOTE: UPPER NIBBLE IS GOING TO BE ALL "0" ... RS = 1 ' SO, SET THE RS TO 'DATA' GOSUB LCDWRITE 'SEND UPPER NIBBLE TO LCD FTEMP = FCHAR 'MASK THE UPPER NIBBLE WITH '0' FTEMP = FTEMP & MASK ' (LOWER NIBBLE IS SENT SECOND IN 4-BIT MODE) LCD_DAT = FTEMP 'NOTE: UPPER NIBBLE IS GOING TO BE ALL "0" ... RS = 1 ' SO, SET THE RS TO 'DATA' GOSUB LCDWRITE 'SEND LOWER NIBBLE TO LCD RETURN '************* LCDWRITE SUB - SENDING AND LATCHING DATA TO LCD ***************** LCDWRITE: I2CWRITE D,C,ADDR,[LCD_DAT] 'LOAD DATA ONTO LCD PORT (NOT LATCHED YET) E = 1 'SET ENABLE BIT I2CWRITE D,C,ADDR,[LCD_DAT] 'LATCH DATA BY SETTING ENABLE PIN ON LCD MODULE E = 0 'CLEAR ENABLE BIT I2CWRITE D,C,ADDR,[LCD_DAT] 'CLEAR ENABLE PIN ON LCD MODULE RETURN '**************** 'END ******************************************** END