Home PIC 16F88 2-Wire LCD Interface

Main Menu

2-Wire LCD Interface
Article Index
2-Wire LCD Interface
The 16F628 Gets Dumped
LM35DZ Thermometer
Improved Thermometer
Adding A Clock
Time set buttons & 12-hour
Clock Improvements
All Pages

thumbMyke 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.

Breadboard 1 Breadboard 2

 

LCD plugged in (left) and working (right). 

LCD plugged in LCD alive

 

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);