The SN74HC595N is an output expansion chip that could drive any devices, LED, relay or even writing data to LCD. A character LCD is easily controlled by this chip in write mode. A single chip SN74HC595N can control the HD44780 using its 4-bit data transfer mode.
In this example the ATMega644P master SPI send HD44780 LCD data and command to the LCD via an SN74HC595N shift registers chip.
![]() |
| A finished Assembling. SN74HC595N is soldered on-board. A 16x4 LCD stays at the top. |
![]() |
| Soldering side |
![]() |
| Schematic Diagram |
The original post uses Arduino Uno to control this LCD module.
Source Code "main.c":
- /*
- * 12-spi_74hc595_1604.c
- *
- * Created: 2/17/2026 3:27:49 PM
- * Author : Admin
- */
- #include <stdio.h>
- #include <avr/io.h>
- #include <util/delay.h>
- #define F_CPU 16000000UL
- #define DDR_SPI DDRB
- #define PRT_SPI PORTB
- #define DD_MOSI 5
- #define DD_MISO 6
- #define DD_SCK 7
- #define DD_SS 4
- void SPI_MasterInit(void)
- {
- /* Set MOSI and SCK output, all others input */
- DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
- /* Enable SPI, Master, set clock rate fck/16
- data is sample at the falling edge of SCK*/
- SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
- }
- void SPI_MasterTransmit(char cData)
- {
- /* Start transmission */
- SPDR = cData;
- /* Wait for transmission complete */
- while(!(SPSR & (1<<SPIF)))
- ;
- }
- void SPI_SlaveInit(void)
- {
- /* Set MISO output, all others input */
- DDR_SPI = (1<<DD_MISO);
- /* Enable SPI */
- SPCR = (1<<SPE);
- }
- char SPI_SlaveReceive(void)
- {
- /* Wait for reception complete */
- while(!(SPSR & (1<<SPIF)))
- ;
- /* Return Data Register */
- return SPDR;
- }
- /*TWI LCD Driver*/
- #define RS 1
- #define RW 2
- #define EN 3
- #define BL 0
- char backLight=0;
- void lcd_delay(unsigned int counts){
- for (unsigned int i=0;i<counts;i++);
- }
- void spi_lcd_command(char command){
- char data;
- data=command&0xF0;
- SPI_MasterTransmit(data|(backLight<<BL)|(1<<EN));
- PRT_SPI&=~(1<<DD_SS);
- PRT_SPI|=(1<<DD_SS);
- SPI_MasterTransmit(data|(backLight<<BL));
- PRT_SPI&=~(1<<DD_SS);
- PRT_SPI|=(1<<DD_SS);
- data=command<<4;
- SPI_MasterTransmit(data|(backLight<<BL)|(1<<EN));
- PRT_SPI&=~(1<<DD_SS);
- lcd_delay(10);
- PRT_SPI|=(1<<DD_SS);
- SPI_MasterTransmit(data|(backLight<<BL));
- PRT_SPI&=~(1<<DD_SS);
- PRT_SPI|=(1<<DD_SS);
- }
- void spi_lcd_data(char command){
- char data;
- data=command&0xF0;
- SPI_MasterTransmit(data|(backLight<<BL)|(1<<EN)|(1<<RS));
- PRT_SPI&=~(1<<DD_SS);
- PRT_SPI|=(1<<DD_SS);
- SPI_MasterTransmit(data|(backLight<<BL)|(1<<RS));
- PRT_SPI&=~(1<<DD_SS);
- PRT_SPI|=(1<<DD_SS);
- lcd_delay(50);
- data=command<<4;
- SPI_MasterTransmit(data|(backLight<<BL)|(1<<EN)|(1<<RS));
- PRT_SPI&=~(1<<DD_SS);
- PRT_SPI|=(1<<DD_SS);
- SPI_MasterTransmit(data|(backLight<<BL)|(1<<RS));
- PRT_SPI&=~(1<<DD_SS);
- PRT_SPI|=(1<<DD_SS);
- }
- void spi_lcd_xy(int8_t x, int8_t y){
- //16x2
- //char addr[]={0x80,0xC0};
- //16x4
- char addr[]={0x80,0xC0,0x90,0xD0};
- spi_lcd_command(addr[y-1]+x-1);
- }
- void spi_lcd_line_1(void){
- spi_lcd_command(0x80);
- }
- void spi_lcd_line_2(void){
- spi_lcd_command(0xC0);
- }
- void spi_lcd_line_3(void){
- spi_lcd_command(0x90);
- }
- void spi_lcd_line_4(void){
- spi_lcd_command(0xD0);
- }
- void spi_lcd_cursor_off(void){
- spi_lcd_command(0x0C);
- }
- void spi_lcd_text(char *txt){
- while(*txt) spi_lcd_data(*txt++);
- }
- void i2c_lcdClear(void){
- spi_lcd_command(0x01);
- _delay_ms(10);
- }
- void spi_lcd_init(void){
- SPI_MasterTransmit(0);
- lcd_delay(500);
- spi_lcd_command(0x33);
- lcd_delay(10);
- spi_lcd_command(0x32);
- lcd_delay(10);
- spi_lcd_command(0x28);
- lcd_delay(10);
- spi_lcd_command(0x0F);
- lcd_delay(10);
- spi_lcd_command(0x01);
- _delay_ms(10);
- spi_lcd_command(0x06);
- lcd_delay(10);
- }
- int main(void)
- {
- /* Replace with your application code */
- _delay_ms(1000);
- SPI_MasterInit();
- PRT_SPI|=(1<<DD_SS); //Set CS Pin High
- spi_lcd_init();
- spi_lcd_line_1();
- spi_lcd_text("ATMega644P SPI");
- spi_lcd_line_2();
- spi_lcd_text("SN74HC595N LCD");
- spi_lcd_line_3();
- spi_lcd_text("TC1604A-01(R)");
- spi_lcd_line_4();
- spi_lcd_text("Example Using C");
- unsigned char data[7],msg[16];
- while (1)
- {
- }
- }
AVR Hardware Experiment:
| Tested ATMega644P |
For a full tutorial list of ATMega644P using C in Microchip Studio IDE please see this page.







