728x90

Showing posts with label Shift Registers. Show all posts
Showing posts with label Shift Registers. Show all posts

Wednesday, February 18, 2026

ATMega644P SPI SN74HC595 and SN74HC165 4x8 Matrix KeyPad Driving

In previous post I use these two SPI chips, SN74HC595 and SN74HC165 to expand the inputs/outputs of an MCU. Here I use these two chip pair to make a matrix keypad. These two 8-bit I/O expansion chip can build up to a 8x8 matrix keypad that yield 64 different keys. But I make only a 4x8 matrix keypad since it's not important.

ATMega644P SPI SN74HC595 and SN74HC165 4x8 Matrix KeyPad Driving
Simulating Program

The 8-bit output port of the SN74HC595 is a column scanner while the lower nibble input port of the SN74HC165 is a row detector (active high). Whenever any key press found the program assign a specific key in its keypad array.

Source Code "main.c":

  1. /*
  2. * 12-spi_sn74hc165_sn74hc595n_keypad.c
  3. *
  4. * Created: 2/18/2026 2:03:34 PM
  5. * Author : Admin
  6. */

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

  10. #define DDR_SPI DDRB
  11. #define PRT_SPI PORTB

  12. #define DD_SH 3
  13. #define DD_SS 4
  14. #define DD_MOSI 5
  15. #define DD_MISO 6
  16. #define DD_SCK 7


  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. SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
  23. }

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

  32. void SPI_SlaveInit(void)
  33. {
  34. /* Set MISO output, all others input */
  35. DDR_SPI = (1<<DD_MISO);
  36. /* Enable SPI */
  37. SPCR = (1<<SPE);
  38. }
  39. char SPI_SlaveReceive(void)
  40. {
  41. /* Wait for reception complete */
  42. while(!(SPSR & (1<<SPIF)))
  43. ;
  44. /* Return Data Register */
  45. return SPDR;
  46. }

  47. const char key_16[4][8]={'1','2','3','4','5','6','7','8',
  48. '9','0','A','B','C','D','E','F',
  49. 'G','H','I','J','K','L','M','N',
  50. 'O','P','Q','R','S','T','U','V'};

  51. char key_scan(void){
  52. char data=0,temp,key;
  53. for(char i=0;i<8;i++){
  54. SPI_MasterTransmit(1<<i);
  55. PRT_SPI&=~(1<<DD_SS);
  56. _delay_us(10);
  57. PRT_SPI|=(1<<DD_SS);
  58. _delay_ms(5);
  59. PRT_SPI&=~(1<<DD_SH);
  60. PRT_SPI|=(1<<DD_SH);
  61. SPI_MasterTransmit(0);
  62. data=SPI_SlaveReceive();
  63. if(data==0x01) {temp=key_16[0][i]; break;}
  64. else if(data==0x02) {temp=key_16[1][i]; break;}
  65. else if(data==0x04){temp=key_16[2][i]; break;}
  66. else if(data==0x08){temp=key_16[3][i]; break;}
  67. else temp=0;
  68. _delay_ms(10);
  69. }
  70. return temp;
  71. }

  72. int main(void)
  73. {
  74. /* Replace with your application code */
  75. SPI_MasterInit();
  76. lcd_init();
  77. DDR_SPI|=(1<<DD_SH);
  78. char data=0;
  79. char temp,charCount=0,newLine=0,line=1;
  80. lcd_text("ATMega644P SPI");
  81. lcd_xy(1,2);
  82. lcd_text("MATRIX KEYPAD");
  83. _delay_ms(5000);
  84. lcd_clear();
  85. while (1)
  86. {
  87. temp=key_scan();
  88. if(temp!=0){
  89. lcd_data(temp);
  90. charCount++;
  91. _delay_ms(500);
  92. }
  93. if(charCount>16){
  94. newLine=1;
  95. charCount=0;
  96. line+=1;
  97. }
  98. if(newLine){
  99. newLine=0;
  100. if(line==2) lcd_xy(1,2);
  101. else{
  102. lcd_xy(1,1);
  103. lcd_command(0x01);
  104. _delay_ms(5);
  105. line=1;
  106. }
  107. }
  108. _delay_ms(100);
  109. }
  110. }






The character LCD uses the parallel port of the ATMega644P. But we can control this LCD by adding one more SN74HC595 and one additional Slave Select (SS) pin. 

ATMega644P SPI SN74HC595 and SN74HC165 4x8 Matrix KeyPad Driving
Simulating Program

I separate these two chip using different Slave Select pins. The SN74HC165 doesn't need serial data input. It only need serial clock and Slave Select pins controlled by the MCU. However I think we can cascade this two chip using a shared SPI pins. If I have more time I will test it using this method.


 

For a full tutorial page of ATMega644P Programming Using C please visit this page. 

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.

On-Board DS1307 Real Time Clock

I use a software TWI I wrote to read date and time from the on-board DS1307 RTC that will show on this SPI LCD. 

ATMega644P SPI SN74HC595N TC1604A LCD
AVR ATMega644P Experiment Board

 Source Code "main.c":

  1. /*
  2. * ds1307_1604.c
  3. *
  4. * Created: 2/19/2026 2:09:32 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. SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
  23. }

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

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

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

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


  52. char backLight=0;

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

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

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

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

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

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

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

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

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

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

  117. void spi_lcd_clear(void){
  118. spi_lcd_command(0x01);
  119. _delay_ms(10);
  120. }

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

  137. // DS1307 RTC Routine

  138. const char DS1307_W=0xD0;
  139. const char DS1307_R=0xD1;
  140. void rtc_init(void){
  141. char rtc[8]={0x30,0x10,0x21,0x04,0x11,0x02,0x26,1<<4};
  142. for (char i=0;i<8;i++)
  143. {
  144. twi_start();
  145. //D0 is DS1307 Write Address
  146. twi_write(DS1307_W);
  147. //Select Control Register
  148. twi_write(i);
  149. //Enable SQWE bit blinks at 1 Hz
  150. twi_write(rtc[i]);
  151. twi_stop();
  152. _delay_ms(10);
  153. }
  154. }

  155. char rtc[7], msg[16];
  156. void rtc_read(void){
  157. for(char i=0;i<7;i++){
  158. /*Second Register*/
  159. twi_start();
  160. twi_write(DS1307_W);
  161. /*Select Second register*/
  162. twi_write(i);
  163. twi_stop();
  164. _delay_ms(10);
  165. twi_start();
  166. twi_write(DS1307_R);
  167. rtc[i]=twi_read();
  168. twi_stop();
  169. _delay_ms(10);
  170. }
  171. }

  172. int main(void)
  173. {
  174. /* Replace with your application code */
  175. SPI_MasterInit();
  176. PRT_SPI|=(1<<DD_SS); //Set CS Pin High
  177. spi_lcd_init();
  178. spi_lcd_line_1();
  179. spi_lcd_text("ATMega644P SPI");
  180. spi_lcd_line_2();
  181. spi_lcd_text("SN74HC595N LCD");
  182. spi_lcd_line_3();
  183. spi_lcd_text("TC1604A-01(R)");
  184. spi_lcd_line_4();
  185. spi_lcd_text("Real Time Clock");
  186. unsigned char data[7],msg[16];
  187. //rtc_init();
  188. _delay_ms(5000);
  189. spi_lcd_clear();
  190. spi_lcd_cursor_off();
  191. while (1)
  192. {
  193. rtc_read();
  194. spi_lcd_line_1();
  195. spi_lcd_text("DS1307 RTC Chip");
  196. spi_lcd_line_2();
  197. spi_lcd_line_2();
  198. spi_lcd_text("Software TWI");
  199. spi_lcd_line_3();
  200. sprintf(msg,"Time: %02X:%02X:%02X",rtc[2],rtc[1],rtc[0]);
  201. spi_lcd_text(msg);
  202. spi_lcd_line_4();
  203. sprintf(msg,"Date: %02X/%02X/20%02X",rtc[4],rtc[5],rtc[6]);
  204. spi_lcd_text(msg);
  205. }
  206. }







Its software TWI driver is place in separate file.

Source Code "twi.c": 

  1. /*
  2. * twi.c
  3. *
  4. * Created: 2/19/2026 2:13:04 PM
  5. * Author: Admin
  6. */

  7. #include <avr/io.h>

  8. #define TWI_PORT PORTC
  9. #define TWI_SDA_IN PINC
  10. #define TWI_DIR DDRC

  11. const char SDA=1;
  12. const char SCL=0;
  13. const char PULSE=10;

  14. void delay_counts(unsigned int count){
  15. for(unsigned int i=0;i<count;i++);
  16. }

  17. void twi_start(void){
  18. TWI_DIR|=(1<<SDA)|(1<<SCL);
  19. TWI_PORT|=(1<<SDA)|(1<<SCL);
  20. delay_counts(PULSE);
  21. TWI_PORT&=~(1<<SDA);
  22. delay_counts(PULSE);
  23. TWI_PORT&=~(1<<SCL);
  24. delay_counts(PULSE);
  25. }

  26. void twi_stop(void){
  27. TWI_PORT&=~(1<<SCL);
  28. TWI_PORT&=~(1<<SDA);
  29. TWI_PORT|=(1<<SCL);
  30. delay_counts(PULSE);
  31. TWI_PORT|=(1<<SDA);
  32. delay_counts(PULSE);
  33. TWI_PORT|=(1<<SDA)|(1<<SCL);
  34. delay_counts(PULSE);
  35. }

  36. void twi_write(char data){
  37. char temp=0;
  38. TWI_DIR|=(1<<SDA)|(1<<SCL);
  39. for (unsigned char i=0;i<9;i++)
  40. {
  41. TWI_PORT&=~(1<<SCL);
  42. delay_counts(PULSE);
  43. if(i<8){
  44. temp=data&0x80;
  45. if(temp==0) TWI_PORT&=~(1<<SDA);
  46. else TWI_PORT|=(1<<SDA);
  47. }
  48. else{
  49. TWI_PORT&=~(1<<SDA);
  50. TWI_DIR&=~(1<<SDA);
  51. while(TWI_SDA_IN&(1<<SDA)==0);
  52. }
  53. TWI_PORT|=(1<<SCL);
  54. delay_counts(PULSE);
  55. data<<=1;
  56. }
  57. TWI_DIR|=(1<<SDA)|(1<<SCL);
  58. }

  59. char twi_read(void){
  60. char temp=0,data=0;
  61. TWI_DIR&=~(1<<SDA);
  62. for (unsigned char i=0;i<9;i++)
  63. {
  64. TWI_PORT&=~(1<<SCL);
  65. delay_counts(PULSE);
  66. if(i<8){
  67. /*
  68. data<<=1;
  69. temp=TWI_SDA_IN&(1<<SDA);
  70. if(temp==(1<<SDA)) data|=1;
  71. else data|=0;
  72. */
  73. temp=TWI_SDA_IN&(1<<SDA);
  74. temp>>=1;
  75. data|=(temp<<(7-i));
  76. }
  77. else{
  78. while((TWI_SDA_IN&(1<<SDA))==0);
  79. }
  80. TWI_PORT|=(1<<SCL);
  81. delay_counts(PULSE);
  82. }
  83. return data;
  84. }


Schematic and Simulation:

ATMega644P SPI SN74HC595N TC1604A LCD
Schematic

 AVR ATmega644P Experiment Board:

It works fine without error on my AVR Experiment Board.

ATMega644P SPI SN74HC595N TC1604A LCD 

 

ATMega644P SPI SN74HC595N TC1604A LCD 

 

 

 

 

Search This Blog

Labels

23K256 (1) 24C16B (2) 25AA010A (2) 8051 (7) 93AA46B (1) ADC (34) Analog Comparator (1) Arduino (16) ARM (13) AT89C52 (7) ATMega32 (58) ATMega644P (27) AVR (87) Bootloader (1) CCS PICC (31) Change Notify Interrupt (CNI) (2) DAC (2) DHT11 (4) Display (133) Distance Sensor (3) ds1307 (10) DS18B20 (5) ds3231 (1) ds3232 (2) dsPIC (5) dsPIC30F1010 (3) dsPIC30F2010 (5) EEPROM (5) Environment Sensor (5) ESP32 (1) esp8266 (1) Graphical LCD (2) I2C (38) ILI9341 (1) Input/Output (75) Interrupt (22) Keil (5) Keypad (16) KS0108 (2) LCD (75) LM35 (3) Master/Slave (2) MAX7221 (1) MCP23017 (8) MCP23S17 (7) MCP4921 (1) MCP4922 (2) Meter (3) MikroC (2) Motor (15) MPLABX (73) Nokia 5110 LCD (4) OLED (2) One-Wire (7) Oscillator (8) PCB (10) PCD8544 (3) PCF8574 (10) PIC (108) PIC12F (3) PIC16F628A (3) PIC16F630 (2) PIC16F716 (4) PIC16F818 (11) PIC16F818/819 (3) PIC16F84A (16) PIC16F876A (2) PIC16F877A (9) PIC16F88 (2) PIC16F887 (60) PIC18 (19) PIC18F1220 (5) PIC18F2550 (5) PIC18F4550 (12) PICKit2 (1) Pin Change Interrupt (1) PWM (12) RTC (12) SBN0064G (1) Sensor (13) SH1106 (3) Shift Register (13) Shift Registers (10) Software TWI (2) SPI (39) ST7735 (1) STM32 (11) STM32 Black Pill (1) STM32 Blue Pill (12) STM32 HAL (5) STM32CubeIDE (13) STM32F103C8T6 (9) STM32F401CCU6 (1) SysTick (4) temperature sensor (13) TFT (1) TG12864A (1) Thermometer (22) Timer/Counter (32) TM1637 (2) twi (10) UART (8) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (96)