// 3-wire LCD test code for 24-pin PIC18F for the // SDCC compiler (v3.2.0), July 7 2012 by WTN (mod Sept 7 2015) // Command line: sdcc -mpic16 -p18f2525 --use-non-free sdcc_lcd_test.c // May be used for any purpose, provided as-is and without warranty. #include #include #include #pragma config OSC=INTIO67,MCLRE=ON,WDT=OFF,PWRT=ON,BOREN=OFF,LVP=OFF,XINST=OFF // bit macros #define testbit(var, bit) ((var) & (1 <<(bit))) #define setbit(var, bit) ((var) |= (1 << (bit))) #define clrbit(var, bit) ((var) &= ~(1 << (bit))) // 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 LATAbits.LATA4 #define LCDenable LATBbits.LATB5 #define LCDclock LATBbits.LATB6 #define LCDdata LATBbits.LATB7 // program declarations int readanalog(unsigned char analog_channel); // lcd code declarations void loopdelay(unsigned int count); void delayms(unsigned int ms); // void putchar(char arg) __wparam; // already declared void initLCD(void); void setLCDshift(unsigned char c); void sendLCDcommand(unsigned char c); void sendLCDdata(unsigned char c); // program variables int analogvalue; int var1; float fvar1; char buffer[10]; void main(void) { 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; stdout = STREAM_USER; // tell SDCC where to stream to initLCD(); printf("Hello World"); LCDbacklight = 1; // flash backlight for approx 1 sec delayms(1000); // use to calibrate mscalibrate define LCDbacklight = 0; // leave off to save battery while debugging printf("\rNice to See"); while(1) { analogvalue=readanalog(8); // jitters too much analogvalue=0; // discard 1st reading then for (var1=0;var1<32;var1++) { // average 32 readings analogvalue=analogvalue+readanalog(8); } analogvalue=analogvalue/32; putchar((char)160); //position to line 2 char 13 fvar1 = (float) analogvalue; fvar1 = fvar1 / 204.8; // fvar1 = voltage assuming 5V supply // printf("%3.1fV",fvar1 + 0.05); // no float print by default... so fake it... fvar1 = fvar1 + 0.05; //rounding var1 = (int) fvar1; printf("%d.",var1); //print int part var1 = (fvar1 - (int) var1) * 10; printf("%dV",var1); //print 1st number after dp delayms(1000); } } int readanalog(unsigned char analog_channel) { // read analog input, channel = 0 for AN0 etc // does not set up port I/O, just reads int analog_value; ADCON0 = (int) analog_channel * 4 + 1; ADCON2bits.ADFM = 1; // right justified ADCON0bits.GO = 1; // start conversion while (ADCON0bits.GO); // wait to complete analog_value = ADRESL; analog_value = analog_value + (ADRESH * 256); return analog_value; } // =========== LCD driver code =========================================== // Created July 4 2012 by WTN (putchar modified for SDCC 7/7/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 printf to print strings // use putchar to send command numbers // // 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 270 // very approx for 8mhz clock void loopdelay(unsigned int count) { while(count--); return; } void delayms(unsigned int ms) { unsigned int i; for(i=0;i127) { if (c<148) { //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(void) { setLCDshift(0); LCDenable=1; delayms(50); LCDenable=0; sendLCDcommand(0b00111000); delayms(10); sendLCDcommand(0b00111000); delayms(10); sendLCDcommand(0b00111000); delayms(10); sendLCDcommand(0b00111000); delayms(10); sendLCDcommand(0b00000100); sendLCDcommand(0b00001100); sendLCDcommand(0b00000001); LCDcurrentline = 0; 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(1); LCDclock = 0; } return; } void sendLCDcommand(unsigned char c) { setLCDshift(c); LCDdata=0; LCDenable=1; loopdelay(1); LCDenable=0; delayms(3); return; } void sendLCDdata(unsigned char c) { setLCDshift(c); LCDdata=1; LCDenable=1; loopdelay(1); LCDenable=0; delayms(3); return; } // ===== end LCD driver code ===== // end LCD test program