/* * TESTLCD.C * * Test a Hitachi HD44780 based LCD module by using the PC parallel * port to write a string to the display. Compile with a Borland C * or C++ compiler (DOS target). To simplify things long delays are * used rather than checking the BUSY flag. (Note: early versions of * Turbo C had a bug in the delay() routine.) * * * Usage: * testlcd print the default string * testlcd string print the given string (but not "-") * testlcd - print stdin (and scroll if necessary) * * * The LCD is connected with a 4-bit data interface: * * LPT Signal LPT pin LCD Signal LCD pin * ========== ======= ========== ======= * SELECT PRINTER 17 DB7 14 * INIT PRINTER 16 DB6 13 * AUTO LINEFEED 14 DB5 12 * STROBE 1 DB4 11 * D0 2 EN 6 * D1 3 R/W 5 * D2 4 RS 4 * VO (*) 3 * VDD (+5V) 2 * GND 25 VSS 1 * * * (*) VO is connected to the slider of a 10k pot between VDD * and VSS * * * Copyright (C) 1996 David Tait * Free for non-profit use and like anything that's free this software * comes with absolutely no warranty * * Version 0.0 3rd March 1996 * */ #include #include #include #define CHARS 16 /* LCD width in chars */ #define out_data(w) outportb(c_reg,(w)^0xB) /* bits 3,1,0 inverted */ #define out_cntl(en,rw,rs) outportb(d_reg,(en)|((rw)<<1)|((rs)<<2)) #define move_to(a) write8(0x80+a,0,1) #define home() write8(2,0,5) #define cur_off() write8(0xC,0,1) int d_reg; int c_reg; void idle(void) { out_cntl(0,1,1); out_data(0xF); /* all O/C ouputs high and can be used as inputs */ } void setup(void) { d_reg = peek(0, 0x408); /* port address of LPT1 data register */ c_reg = d_reg+2; /* port address of LPT1 control register */ } void write4(int w, int rs, int ms) { out_data(w); out_cntl(0,0,rs); /* cycle EN */ out_cntl(1,0,rs); out_cntl(0,0,rs); delay(ms); } void write8(int w, int rs, int ms) { write4((w&0xF0)>>4,rs,0); /* write high nibble */ write4(w&0xF,rs,ms); /* then low nibble */ } void init_lcd(int n) { idle(); delay(15); /* not necessary here of course */ write4(3,0,5); /* set 8-bit mode */ write4(3,0,5); /* and again */ write4(3,0,5); /* and again */ write4(2,0,5); /* set 4-bit mode */ write8(0x20+8*n,0,5); /* set 4-bit mode, n+1 lines, 5x7 dots */ write8(6,0,5); /* set cursor to move forward */ write8(1,0,5); /* clear display */ write8(0xF,0,5); /* display on, cursor on, blink */ idle(); } void print(char *s) { while ( *s ) write8(*s++,1,1); idle(); } void scroll(void) { int c, n=0; init_lcd(0); /* select one line mode */ cur_off(); while ( (c=getchar()) != EOF ) { if ( n == CHARS ) write8(7,0,1); /* need to enable scrolling now */ write8(c,1,1); delay(150); ++n; } idle(); } void main(int argc, char *argv[]) { setup(); init_lcd(1); /* two line mode */ if ( argc < 2 ) { /* print default string */ print("Look:"); move_to(40); print("4bit mode works!"); home(); cur_off(); idle(); } else if ( *argv[1]=='-' ) scroll(); /* or print stdin */ else print(argv[1]); /* or print argument */ }