#include "PicLCD.h" /////////////////////////////////////////////////////////////////////////// //// PICDEM2_LCD.C //// //// Driver for common PICDEM2 PLUS LCD modules //// //// //// //// lcd_init() Must be called before any other function. //// //// //// //// lcd_putc(c) Will display c on the next position of the LCD. //// //// The following have special meaning: //// //// \f Clear display //// //// \n Go to start of second line //// //// \b Move back one position //// //// //// //// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) //// //// //// //// lcd_getc(x,y) Returns character at position x,y on LCD //// //// //// /////////////////////////////////////////////////////////////////////////// #define data_byte 0 #define cmd_byte 1 #define lcd_pwr PIN_D7 #define lcd_en PIN_D6 #define lcd_rw PIN_D5 #define lcd_rs PIN_D4 #define lcd_D3 PIN_D3 #define lcd_D2 PIN_D2 #define lcd_D1 PIN_D1 #define lcd_D0 PIN_D0 #define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines #define lcd_line_two 0x40 // LCD RAM address for the second line #define d_cycle 1 void lcd_send_nibble( BYTE n ) { output_bit(lcd_D0,(n&1)); output_bit(lcd_D1,(n&2)); output_bit(lcd_D2,(n&4)); output_bit(lcd_D3,(n&8)); delay_cycles(d_cycle); output_high(lcd_en); delay_us(20); output_low(lcd_en); } BYTE lcd_get_nibble() { BYTE i=0; if (input(lcd_D0)) i=i+1; if (input(lcd_D1)) i=i+2; if (input(lcd_D2)) i=i+4; if (input(lcd_D3)) i=i+8; return(i); } BYTE lcd_read_byte() { BYTE low,high; output_high(lcd_rw); delay_cycles(d_cycle); output_high(lcd_en); delay_cycles(d_cycle); high = lcd_get_nibble(); //using d0:d3 for 4 bit data bus output_low(lcd_en); delay_cycles(d_cycle); output_high(lcd_en); delay_us(1); low = lcd_get_nibble(); //using d0:d3 for 4 bit data bus output_low(lcd_en); return((high<<4) | low); } void lcd_send_byte( BYTE A0, BYTE n ) { //A0: 0=instruction, 1=Data output_low(lcd_rs); if ( bit_test(lcd_read_byte(),7) ) delay_ms(100); // if busy, delay if (A0==1){output_high(lcd_rs);} //0=Instruction and 1=Data delay_cycles(d_cycle); output_low(lcd_rw); delay_cycles(d_cycle); output_low(lcd_en); lcd_send_nibble(n >> 4); lcd_send_nibble(n & 0xf); } void lcd_init() { BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0x0f, 0x01, 0x06}; // These bytes need to be sent to the LCD for initialization. BYTE i; output_high(lcd_pwr); //Turn on LCD delay_ms(100); output_low(lcd_rs); output_low(lcd_rw); output_low(lcd_en); delay_ms(15); for(i=1;i<=3;++i) { lcd_send_nibble(3); delay_ms(5); } lcd_send_nibble(2); for(i=0;i<=3;++i){ lcd_send_byte(data_byte,LCD_INIT_STRING[i]); } } void lcd_gotoxy( BYTE x, BYTE y) { BYTE Data; if(y!=1) Data=lcd_line_two; else Data=0; Data+=x-1; lcd_send_byte(0,0x80|Data); } void lcd_putc( char c) { switch (c) { case '\f' : lcd_send_byte(data_byte,1); delay_ms(2); break; case '\n' : lcd_gotoxy(1,2); break; case '\b' : lcd_send_byte(data_byte,0x10); break; default : lcd_send_byte(cmd_byte,c); break; } } char lcd_getc( BYTE x, BYTE y) { char value; lcd_gotoxy(x,y); while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low output_high(lcd_rs); value = lcd_read_byte(); output_low(lcd_rs); return(value); } void main() { setup_adc_ports(NO_ANALOGS); setup_adc(ADC_OFF); setup_psp(PSP_DISABLED); setup_spi(FALSE); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); output_low(pin_b0); lcd_init(); while (1) { delay_ms(1000); lcd_putc('\f'); delay_ms(250); output_high(pin_b0); delay_ms(250); lcd_putc('A'); output_b(5); delay_ms(250); output_b(10); delay_ms(250); output_b(5); lcd_putc('g'); delay_ms(250); output_high(pin_b0); printf(lcd_putc,"1234545"); printf(lcd_putc,"Too much for line 1"); lcd_putc('y'); lcd_putc('z'); lcd_gotoxy(0x1,2); printf(lcd_putc,"Line 2"); delay_ms(1000); lcd_gotoxy(0x1,1); printf(lcd_putc,"Line one"); } // http://ww1.microchip.com/downloads/en/DeviceDoc/51275b.pdf }