The HD44780 character LCD type uses parallel interface with controller, even it operates in 4-bit data transfer mode. Currently most electronic hobbyists use an additional shift register or an I/O expanding chip, especially the PCF8574T chip.
![]() |
| Character LCD With PCF8574T |
In this example, I use SN74HC164 shift register to interface between controller and character LCD.
![]() |
| Schematic Diagram |
I use two wires - serial data and serial clock to interface between controller and SN74HC164. However I use one additional pin to interacts with LCD Enable pin. It's because I have difficulty during programming.
/* * SPI74164LCD.c * * Created: 7/7/2023 9:48:09 AM * Author : Admin */ #include <avr/io.h> #define F_CPU 4000000UL #include <util/delay.h> void masterInit(void){ /*Set MOSI, SCK and SS Output*/ DDRB|=(1<<4)|(1<<5)|(1<<7); /*Enable SPI Master Set Clock Rate Fclk/4*/ SPCR|=(1<<SPE)|(1<<MSTR); } void masterTransmit(unsigned char spiData){ /*Start The Transmission*/ SPDR = spiData; /*Wait For Completion*/ while(!(SPSR&(1<<SPIF))); } void lcdCmd(unsigned char cmd){ masterTransmit(cmd&0xF0); PORTB|=(1<<4); _delay_us(100); PORTB&=~(1<<4); _delay_us(100); masterTransmit(cmd<<4); PORTB|=(1<<4); _delay_us(100); PORTB&=~(1<<4); _delay_us(100); } void lcdDat(unsigned char dat){ masterTransmit((dat&0xF0)|1); PORTB|=(1<<4); _delay_us(100); PORTB&=~(1<<4); _delay_us(100); masterTransmit((dat<<4)|1); PORTB|=(1<<4); _delay_us(100); PORTB&=~(1<<4); _delay_us(100); } void lcdInit(){ masterTransmit(0x00); _delay_ms(20); lcdCmd(0x33); _delay_us(100); lcdCmd(0x32); _delay_us(100); lcdCmd(0x28); _delay_us(100); lcdCmd(0x0F); _delay_us(100); lcdCmd(0x01); _delay_ms(2); lcdCmd(0x06); _delay_us(100); } void lcdStr( char *str){ unsigned char i=0; while(str[i]!=0){ lcdDat(str[i]); i++; } } void lcdXY(unsigned char x, unsigned char y){ unsigned char tbe[]={0x80,0xC0,0x94,0xD4}; // 20x4 lcdCmd(tbe[y-1]+x-1); _delay_us(100); } void lcdClear(){ lcdCmd(0x01); _delay_us(10); } int main(void) { masterInit(); lcdInit(); lcdXY(1,1); lcdStr("ATMEGA32 SN74HC164"); lcdXY(1,2); lcdStr("Character LCD "); lcdXY(1,3); lcdStr("Interfacing Using"); lcdXY(1,4); lcdStr("Three Wires......."); lcdCmd(0x0F); _delay_ms(100); while (1) { } }
Click here to download source file.
![]() |
| Simulating Program |























