728x90

728x90

Tuesday, February 17, 2026

ATMega644P SPI SN74HC595N TC1604A LCD

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.

ATMega644P SPI SN74HC595N TC1604A LCD 

 

 ATMega644P SPI SN74HC595N TC1604A LCD

In this example the ATMega644P master SPI send HD44780 LCD data and command to the LCD via an SN74HC595N shift registers chip.

ATMega644P SPI SN74HC595N TC1604A LCD
A finished Assembling. SN74HC595N is soldered on-board. A 16x4 LCD stays at the top.

 

ATMega644P SPI SN74HC595N TC1604A LCD
Soldering side

 

ATMega644P SPI SN74HC595N TC1604A LCD
Schematic Diagram

 The original post uses Arduino Uno to control this LCD module.

Source Code "main.c":

  1. /*
  2. * 12-spi_74hc595_1604.c
  3. *
  4. * Created: 2/17/2026 3:27:49 PM
  5. * Author : Admin
  6. */

  7. #include <stdio.h>
  8. #include <avr/io.h>
  9. #include <util/delay.h>
  10. #define F_CPU 16000000UL

  11. #define DDR_SPI DDRB
  12. #define PRT_SPI PORTB
  13. #define DD_MOSI 5
  14. #define DD_MISO 6
  15. #define DD_SCK 7
  16. #define DD_SS 4

  17. void SPI_MasterInit(void)
  18. {
  19. /* Set MOSI and SCK output, all others input */
  20. DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
  21. /* Enable SPI, Master, set clock rate fck/16
  22. data is sample at the falling edge of SCK*/
  23. SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
  24. }

  25. void SPI_MasterTransmit(char cData)
  26. {
  27. /* Start transmission */
  28. SPDR = cData;
  29. /* Wait for transmission complete */
  30. while(!(SPSR & (1<<SPIF)))
  31. ;
  32. }

  33. void SPI_SlaveInit(void)
  34. {
  35. /* Set MISO output, all others input */
  36. DDR_SPI = (1<<DD_MISO);
  37. /* Enable SPI */
  38. SPCR = (1<<SPE);
  39. }

  40. char SPI_SlaveReceive(void)
  41. {
  42. /* Wait for reception complete */
  43. while(!(SPSR & (1<<SPIF)))
  44. ;
  45. /* Return Data Register */
  46. return SPDR;
  47. }

  48. /*TWI LCD Driver*/
  49. #define RS 1
  50. #define RW 2
  51. #define EN 3
  52. #define BL 0


  53. char backLight=0;

  54. void lcd_delay(unsigned int counts){
  55. for (unsigned int i=0;i<counts;i++);
  56. }

  57. void spi_lcd_command(char command){
  58. char data;
  59. data=command&0xF0;
  60. SPI_MasterTransmit(data|(backLight<<BL)|(1<<EN));
  61. PRT_SPI&=~(1<<DD_SS);
  62. PRT_SPI|=(1<<DD_SS);
  63. SPI_MasterTransmit(data|(backLight<<BL));
  64. PRT_SPI&=~(1<<DD_SS);
  65. PRT_SPI|=(1<<DD_SS);
  66. data=command<<4;
  67. SPI_MasterTransmit(data|(backLight<<BL)|(1<<EN));
  68. PRT_SPI&=~(1<<DD_SS);
  69. lcd_delay(10);
  70. PRT_SPI|=(1<<DD_SS);
  71. SPI_MasterTransmit(data|(backLight<<BL));
  72. PRT_SPI&=~(1<<DD_SS);
  73. PRT_SPI|=(1<<DD_SS);
  74. }

  75. void spi_lcd_data(char command){
  76. char data;
  77. data=command&0xF0;
  78. SPI_MasterTransmit(data|(backLight<<BL)|(1<<EN)|(1<<RS));
  79. PRT_SPI&=~(1<<DD_SS);
  80. PRT_SPI|=(1<<DD_SS);
  81. SPI_MasterTransmit(data|(backLight<<BL)|(1<<RS));
  82. PRT_SPI&=~(1<<DD_SS);
  83. PRT_SPI|=(1<<DD_SS);
  84. lcd_delay(50);
  85. data=command<<4;
  86. SPI_MasterTransmit(data|(backLight<<BL)|(1<<EN)|(1<<RS));
  87. PRT_SPI&=~(1<<DD_SS);
  88. PRT_SPI|=(1<<DD_SS);
  89. SPI_MasterTransmit(data|(backLight<<BL)|(1<<RS));
  90. PRT_SPI&=~(1<<DD_SS);
  91. PRT_SPI|=(1<<DD_SS);
  92. }

  93. void spi_lcd_xy(int8_t x, int8_t y){
  94. //16x2
  95. //char addr[]={0x80,0xC0};
  96. //16x4
  97. char addr[]={0x80,0xC0,0x90,0xD0};
  98. spi_lcd_command(addr[y-1]+x-1);
  99. }

  100. void spi_lcd_line_1(void){
  101. spi_lcd_command(0x80);
  102. }

  103. void spi_lcd_line_2(void){
  104. spi_lcd_command(0xC0);
  105. }

  106. void spi_lcd_line_3(void){
  107. spi_lcd_command(0x90);
  108. }

  109. void spi_lcd_line_4(void){
  110. spi_lcd_command(0xD0);
  111. }

  112. void spi_lcd_cursor_off(void){
  113. spi_lcd_command(0x0C);
  114. }

  115. void spi_lcd_text(char *txt){
  116. while(*txt) spi_lcd_data(*txt++);
  117. }

  118. void i2c_lcdClear(void){
  119. spi_lcd_command(0x01);
  120. _delay_ms(10);
  121. }

  122. void spi_lcd_init(void){
  123. SPI_MasterTransmit(0);
  124. lcd_delay(500);
  125. spi_lcd_command(0x33);
  126. lcd_delay(10);
  127. spi_lcd_command(0x32);
  128. lcd_delay(10);
  129. spi_lcd_command(0x28);
  130. lcd_delay(10);
  131. spi_lcd_command(0x0F);
  132. lcd_delay(10);
  133. spi_lcd_command(0x01);
  134. _delay_ms(10);
  135. spi_lcd_command(0x06);
  136. lcd_delay(10);
  137. }

  138. int main(void)
  139. {
  140. /* Replace with your application code */
  141. _delay_ms(1000);
  142. SPI_MasterInit();
  143. PRT_SPI|=(1<<DD_SS); //Set CS Pin High
  144. spi_lcd_init();
  145. spi_lcd_line_1();
  146. spi_lcd_text("ATMega644P SPI");
  147. spi_lcd_line_2();
  148. spi_lcd_text("SN74HC595N LCD");
  149. spi_lcd_line_3();
  150. spi_lcd_text("TC1604A-01(R)");
  151. spi_lcd_line_4();
  152. spi_lcd_text("Example Using C");
  153. unsigned char data[7],msg[16];
  154. while (1)
  155. {
  156. }
  157. }





AVR Hardware Experiment:

ATMega644P SPI SN74HC595N TC1604A LCD
Tested ATMega644P

For a full tutorial list of ATMega644P using C in Microchip Studio IDE please see this page.


 

 

No comments:

Post a Comment

320x50

Search This Blog

tyro-728x90