// 3-wire LCD test code for 24-pin PIC18F for the // cpik compiler (v0.7.1), July 10 2012 by WTN (mod Sept 7 2015) // command lines: // cpik -c -p p18f2525 cpik_lcd_test.c // cpik -o cpik_lcd_test.asm -p p18f2525 cpik_lcd_test.slb stdio-small.slb // cpik -a -p p18f2525 cpik_lcd_test.asm // May be used for any purpose, provided as-is and without warranty. #include #include #include #pragma _CONFIG1H _OSC_INTIO67_1H #pragma _CONFIG2L _PWRT_ON_2L & _BOREN_ON_2L & _BORV_0_2L #pragma _CONFIG2H _WDT_OFF_2H #pragma _CONFIG3H _MCLRE_ON_3H #pragma _CONFIG4L _LVP_OFF_4L & _XINST_OFF_4L #define ADFM ADCON2.7 #define GODONE ADCON0.1 // RA0 = analog input 0 // RA1 = analog input 1 // RA2 = analog input 2 // RA3 = analog input 3 // RA4 = output LCD backlight default 0 // RA5 = analog input 4 // RB2 = analog input 8 // RB5 = output LCD E default 0 // RB6 = output LCD CLK default 0 // RB7 = output LCD DAT/RS default 0 #define portadirs 0b11101111 #define portbdirs 0b00011111 #define portcdirs 0b11111111 #define portadefaults 0b00000000 #define portbdefaults 0b00000000 #define portcdefaults 0b00000000 #define LCDbacklight LATA.4:1 #define LCDenable LATB.5:1 #define LCDclock LATB.6:1 #define LCDdata LATB.7:1 // program declarations long readanalog(unsigned char analog_channel); void myputch(char c); // lcd code declarations void loopdelay(unsigned long count); void delayms(unsigned long ms); void writeLCDbyte(unsigned char c); void initLCD(); void setLCDshift(unsigned char c); void sendLCDcommand(unsigned char c); void sendLCDdata(unsigned char c); // program variables long analogvalue; long var1; float fvar1; int8_t main() { set_putchar_vector(&myputch); //direct stdio to putch INTCON = 0; // no interrupts OSCCON = 0b01110000; // set for 8mhz clock ADCON1 = 0b00000110; // use AN0-4,AN8, rest digital CMCON = 0; // no comparators LATA = portadefaults; // set default pin states LATB = portbdefaults; LATC = portcdefaults; TRISA = portadirs; // set pin directions TRISB = portbdirs; TRISC = portcdirs; initLCD(); printf("Hello World"); LCDbacklight = 1; delayms(1000L); LCDbacklight = 0; printf("\rNice to See"); while(1) { analogvalue=readanalog(8); // jitters too much analogvalue=0L; // discard 1st reading then for (var1=0L;var1<32L;var1++) { // average 32 readings analogvalue=analogvalue+readanalog(8); } analogvalue=analogvalue/32L; writeLCDbyte(160); //position to line 2 char 13 fvar1 = (float) analogvalue; fvar1 = fvar1 / 204.8F; // printf("%1fV",fvar1 + 0.05); fvar1 = fvar1 + 0.05F; //rounding var1 = (long) fvar1; printf("%ld.",var1); //print int part var1 = (fvar1 - (long) var1) * 10L; printf("%ldV",var1); //print 1st number after dp delayms(1000L); } return 0; } void myputch(char c) { // chain stdout to writeLCDbyte unsigned char c1; // use writeLCDbyte directly for bytes >=128 c1 = (unsigned char) c; writeLCDbyte(c1); } long readanalog(unsigned char analog_channel) { // read analog input, channel = 0 for AN0 etc // does not set up port I/O, just reads long analog_value; ADCON0 = analog_channel * 4 + 1; ADFM = 1; // right justified GODONE = 1; // start conversion while (GODONE); // wait to complete analog_value = ADRESL; analog_value = analog_value + (ADRESH * 256L); return analog_value; } // =========== LCD driver code =========================================== // Created July 4 2012 by WTN (adapted to cpik 7/10/12) // For 3-wire LCD interface with 8-bit connection... // define LCDenable to pin connected to E line // define LCDdata to pin connected to shift reg data and RS line // define LCDclock to shift reg clock pin (74HC164) // // Partial support for Parallax-like LCD commands... // 8 move cursor left // 9 move cursor right // 12 clear screen // 21 turn off display // 22 turn on display (cursor off, blink off) // 23 turn on display (cursor off, blink on) // 24 turn on display (cursor on, blink off) // 25 turn on display (cursor on, blink on) // 128 position to 1st line (129-143 for chars 2-15) // 148 position to 2nd line (149-163 for chars 2-15) // 13 position to "next" line (alternates lines, does not clear) // does not support line feed or other fancy stuff // (Parallax is a trademark of the Parallax Inc. company, // who makes a serial LCD that implements similar commands.) // // Usage... // initLCD(); // use writeLCDbyte(byte) to send command numbers/characters // // Also supplies loopdelay(loops) and delayms(ms) subroutines // set mscalibrate constant for number of loops for 1ms delay unsigned char LCDcurrentline; // global var for CR support #define mscalibrate 200L // approx for 8mhz clock void loopdelay(unsigned long count) { while(count--); return; } void delayms(unsigned long ms) { unsigned long i; for(i=0;i127U) { if (c<148U) { //positions on 1st line 128-143 sendLCDcommand(128); LCDcurrentline = 0; numberofshifts=c-128; while (numberofshifts) { sendLCDcommand(0b00010100); numberofshifts--; } } else { //positions on 2nd line 148-163 sendLCDcommand(192); LCDcurrentline = 1; numberofshifts=c-148; while (numberofshifts) { sendLCDcommand(0b00010100); numberofshifts--; } } } else sendLCDdata(c); return; } void initLCD() { setLCDshift(0); LCDenable=1; delayms(50L); LCDenable=0; sendLCDcommand(0b00111000); delayms(10L); sendLCDcommand(0b00111000); delayms(10L); sendLCDcommand(0b00111000); delayms(10L); sendLCDcommand(0b00111000); delayms(10L); sendLCDcommand(0b00000100); sendLCDcommand(0b00001100); sendLCDcommand(0b00000001); LCDcurrentline = 0L; return; } void setLCDshift(unsigned char c) { int i; LCDclock = 0; for (i=0;i<8;i++) { if (c & 0x80) LCDdata = 1; else LCDdata = 0; c = c << 1; LCDclock = 1; loopdelay(1L); LCDclock = 0; } return; } void sendLCDcommand(unsigned char c) { setLCDshift(c); LCDdata=0; LCDenable=1; loopdelay(1L); LCDenable=0; delayms(3L); return; } void sendLCDdata(unsigned char c) { setLCDshift(c); LCDdata=1; LCDenable=1; loopdelay(1L); LCDenable=0; delayms(3L); return; } // ===== end LCD driver code ===== // end LCD test program