|
Page 1 of 7 Myke Predko described this 2-wire LCD interface on his site. (Myke's site is gone - go to Rentron's Myke Predko page now). It uses a 74LS174 Hex D Flip-Flop wired as a shift register, with a sneaky method of using the sixth flip-flop and the data bit to do the E line. I built one and wrote some C code for it. Works well.
2008-05-29: Added an LM35DZ sensor and turned it into a thermometer. 2008-06-02: Added a clock with 32.768kHz crystal. 2008-06-03: Added time set buttons and 12-hour time 2008-06-05: Added seconds button & PWM backlight control button
There's lots of wiring from the 74LS174 to the LCD, but only two control lines from the PIC. So you could run an LCD with an 8-pin PIC and have pins left over to actually do something with. 
LCD plugged in (left) and working (right). 
This is early source code. I'm sure I'll improve it from here. This was the first working version. two_wire_lcd.c#include "two_wire_lcd.h"
char string[] = " ";
void main(void) { trisb=0; delay_ms(500); lcd_init(); while(1){ lcd_line1(); sprintf(string,"PIC 16F628",0); lcd_string(string); delay_ms(1000); lcd_line2(); sprintf(string,"2-Wire 74LS174",0); lcd_string(string); delay_ms(1000); } }
void lcd_string(char *senpoint) { while(*senpoint != '\0') { lcd_char(*senpoint); senpoint++; } }
void lcd_line1(void) { lcd_cmd(0x80); }
void lcd_line2(void) { lcd_cmd(0xc0); }
void lcd_cmd(unsigned char letter) { unsigned char temp; temp=letter; temp=temp>>4; lcd_nybble(temp,0); temp=letter; temp=temp&0x0f; lcd_nybble(temp,0); }
void lcd_char(unsigned char letter) { unsigned char temp; temp=letter; temp=temp>>4; lcd_nybble(temp,1); temp=letter; temp=temp&0x0f; lcd_nybble(temp,1); }
void lcd_nybble(unsigned char nyb,unsigned char rs) { int i; data=0; //clear the 174 for(i=0;i<6;i++){ //repeat for 6 bits clock=1;clock=0; //write 0's to the 174 } data=1; //output the AND value clock=1;clock=0; data=rs; //output the RS bit value clock=1;clock=0; for(i=0;i<4;i++){ //output the nybble if((nyb & 0x08) != 0) data=1; else data=0; clock=1;clock=0; nyb=nyb<<1; } // clock=1;clock=0; e_togg(); }
void lcd_init(void) { lcd_nybble(0x03,0); delay_ms(5); e_togg(); delay_us(160); e_togg(); delay_us(160); lcd_nybble(0x02,0); delay_us(160); lcd_cmd(0x28); //set 4-bit mode and 2 lines delay_us(160); lcd_cmd(0x10); //cursor move & shift left delay_us(160); lcd_cmd(0x06); //entry mode = increment delay_us(160); lcd_cmd(0x0d); //display on - cursor blink on delay_us(160); lcd_cmd(0x01); //clear display delay_us(160); }
void e_togg(void) { data=1;data=0; } two_wire_lcd.h#include <system.h> #include <stdio.h> #pragma DATA _CONFIG, _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _MCLRE_ON
#define clock portb.4 #define data portb.3
void lcd_string(char *); void lcd_line1(void); void lcd_line2(void); void lcd_cmd(unsigned char); void lcd_char(unsigned char); void lcd_nybble(unsigned char,unsigned char); void lcd_init(void); void e_togg(void);
|