Menu

a-ads Ad Unit #2456538

Ad Unit #2456555

Navbar

a-ads Ad Unit #2456538

Monday, February 2, 2026

ATMega644P TWI PCF8574AP Matrix Keypad LCD

A matrix keypad could save the number of micro-controller I/O usage. For instant a 4x4 matrix keypad uses only 8 pins of a micro-controller but it yield 16 different key values. Using an 8-bit micro-controller digital I/O port is common for most of programmers. 

ATMega644P TWI PCF8574AP Matrix Keypad LCD

However when the there is a I/O constraint we need an I/O expansion, for example adding serial interface I/O expansion chip to a micro-controller.These chips need only a few wires of a micro-controller.

ATMega644P TWI PCF8574AP Matrix Keypad LCD
16 Key Membrane Switch Keypad 4X4 3X4 Matrix Keyboard For Arduino Diy Kit

 

In this post I will show an example of using the PCF8574AP to make a 4x4 matrix keypad with a character LCD. For more information about using the PCF8574 series please visit these posts,

  1. ATMega644P TWI PCF8574 I/O Expansion Interfacing 
  2. PIC16F887 PCF8574AP I2C LCD Example using XC8 
  3. PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8 
  4. PIC16F887 PCF8574 I2C Example using XC8 
  5. A DIY TWI LCD Using PCF8574AP For Arduino 
  6. ATMega32 TWI interfaces to PCF8574A parallel port expansion 
  7. Reading The Digital Input Output From PCF8574 Using PIC12F629 

The TWI master micro-controller of the ATMega644P periodically scan for any key press. The result of will display on an on-board 16x2 character LCD.

Source Code:

  1. /*
  2. * 10-i2c_pcf8574ap_keypad.c
  3. *
  4. * Created: 2/2/2026 9:32:41 PM
  5. * Author : Admin
  6. */

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

  10. //DIY PCF8574AP LCD Module (A2:A0=0)
  11. const char pcf8574_w=0x40;
  12. const char pcf8574_r=0x41;
  13. //PCF8574 (A2:A0=0)
  14. const char pcf8574a_w=0x70;
  15. const char pcf8574a_r=0x71;
  16. //DIY Arduino PCF8574T LCD Module
  17. const char pcf8574T_LCD_W=0x4E;
  18. const char pcf8574T_LCD_R=0x4F;

  19. void i2cInit(void){
  20. TWSR|=0x00; //Prescaler Selection Bit
  21. TWBR=0xF0; //Baud Rate Generator
  22. TWCR=(1<<TWEN); //Enable The TWI Module
  23. PORTC|=(1<<0);
  24. PORTC|=(1<<1);
  25. }

  26. void i2cStart(void){
  27. TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  28. while((TWCR&(1<<TWINT))==0);
  29. }

  30. void i2cWrite(unsigned char data){
  31. TWDR=data;
  32. TWCR=(1<<TWINT)|(1<<TWEN);
  33. while((TWCR&(1<<TWINT))==0);
  34. }

  35. unsigned char i2cRead(char ACK){
  36. if(ACK==0)
  37. TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
  38. else
  39. TWCR=(1<<TWINT)|(1<<TWEN);
  40. while((TWCR&(1<<TWINT))==0);
  41. return TWDR;
  42. }

  43. void i2cStop(){
  44. TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
  45. _delay_us(10);
  46. }

  47. void pcf8574Write(char data){
  48. i2cStart();
  49. i2cWrite(pcf8574a_w);
  50. i2cWrite(data);
  51. i2cStop();
  52. }

  53. char pcf8574Read(void){
  54. i2cStart();
  55. i2cWrite(pcf8574a_r);
  56. char temp=i2cRead(1);
  57. i2cStop();
  58. return temp;
  59. }

  60. uint8_t key_16[][4]={'1','2','3','A',
  61. '4','5','6','B',
  62. '7','8','9','C',
  63. '*','0','#','D'};

  64. uint8_t keyScan(void){
  65. char data=0,temp,key;
  66. for(uint8_t i=0;i<4;i++){
  67. data=0xFF;
  68. data&=~(1<<i);
  69. pcf8574Write(data);
  70. _delay_ms(5);
  71. data=pcf8574Read();
  72. data&=0xF0;
  73. if((data&0x10)==0) {temp=key_16[i][0]; break;}
  74. else if((data&0x20)==0){temp=key_16[i][1]; break;}
  75. else if((data&0x40)==0){temp=key_16[i][2]; break;}
  76. else if((data&0x80)==0){temp=key_16[i][3]; break;}
  77. else temp=0;
  78. _delay_ms(10);
  79. }
  80. return temp;
  81. }

  82. int main(void)
  83. {
  84. /* Replace with your application code */
  85. i2cInit();
  86. lcd_init();
  87. lcd_text("ATMega644P TWI");
  88. lcd_xy(1,2);
  89. lcd_text("PCF8574AP KeyPad");
  90. _delay_ms(10000);
  91. lcd_clear();
  92. char temp,charCount=0,newLine=0,line=1;
  93. while (1)
  94. {
  95. temp=keyScan();
  96. if(temp!=0){
  97. lcd_data(temp);
  98. charCount++;
  99. _delay_ms(500);
  100. }
  101. if(charCount>16){
  102. newLine=1;
  103. charCount=0;
  104. line+=1;
  105. }
  106. if(newLine){
  107. newLine=0;
  108. if(line==2) lcd_xy(1,2);
  109. else{
  110. lcd_xy(1,1);
  111. lcd_command(0x01);
  112. _delay_ms(5);
  113. line=1;
  114. }
  115. }
  116. }
  117. }



Schematic:

ATMega644P TWI PCF8574AP Matrix Keypad LCD
Schematic and Simulation
Simulation Program

 

ATMega644P Experiment Board:

ATMega644P TWI PCF8574AP Matrix Keypad LCD


ATMega644P TWI PCF8574AP Matrix Keypad LCD


This PCB was offered by PCBWay.

I have been using PCBWay for many years now. PCBWay fabricate PCBs at low cost, fast processing time for only 24 hours, and fast delivery time using any carrier options. This double side 10cmx10cm can be fabricate at only 5USD for 5 to 10pcs by PCBWay. It's a standard PCB with silk screen and solder mask.

A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
10 PCBs for only 5USD
 

For different size of PCB we can instantly quote on PCBWay website using a zip PCB Gerber file without account.

A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
PCBWay Instant Quote

 

 

 

Sunday, February 1, 2026

ATMega644P TWI PCF8574 I/O Expansion Interfacing

Overview

The PCF8574/PCF8574A is a TWI I/O expansion chip with an 8-bit quasi-bidirectional
 bi-directional pin. Those two version PCF8574 and PCF8574A are identical in functionalities but they have a different slave address 0x40 (write) for the PCF8574 and 0x70 (write) for the PCF8574A. This chip is very easy to find due to a variety of manufactures such as NXP and Texas Instruments etc.

ATMega644P TWI PCF8574 I/O Expansion Interfacing 

This chip is applicable for,

  • LED signs and displays
  • Servers 
  • Key pads
  • Industrial control
  • Medical equipment
  • PLC
  • Cellular telephones
  • Mobile devices
  • Gaming machines
  • Instrumentation and test measurement.

For electronic hobbyists and students this chip is commonly found in an HD44780 LCD controller or even a matrix keypad.

Since it uses TWI its communication protocol could be done from scratch even using a micro-controller without a TWI module inside. Software bit banging is a preferred method for most of programmers since since they don't need to know about the detail of the device's communication protocol. It's user friendly to most hobbyists and students since it has ad DIP package. It's widely available both in a single DIP chip or even in a module at very low cost. Arduino is the most common micro-controller that's very easily to interface and program with this chip. 

ATMega644P TWI PCF8574 I/O Expansion Interfacing
A PCF8574AP DIP
ATMega644P TWI PCF8574 I/O Expansion Interfacing
A character LCD with a PCF8574T

 This 16-pin I2C device is very simple to use.

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Block diagram

 There a DIP and two SMD versions.

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Pinning information

 These pins are power supply pins, TWI pins, interrupt output pins and 8-bit I/O pin.

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Pin description

 We can use multiple PCF8574 series on a single TWI bus depends on the additional address selecting pins A2:A0.

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Device address

 Some master MCU use only a 7-bit address for example the Arduino.

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Address maps
ATMega644P TWI PCF8574 I/O Expansion Interfacing
Address maps

There are only devices slave address and I/O port register without additional data direction and control registers. Its I/O port is similar to the 8051 micro-controller series. The master MCU just need to read and write the I/O port.

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Writing to the port (Output mode)

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Reading from a port (Input mode)

The PCF8574/74A provides an open-drain output (INT) which can be fed to a corresponding input of the microcontroller. As soon as a port input ischanged, the INT will be active (LOW) and notify the microcontroller.


An interrupt is generated at any rising or falling edge of the port inputs. After time tv(Q), the
signal INT is valid.

 

The interrupt will reset to HIGH when data on the port is changed to the original setting or data is read or written by the master.


In the Write mode, the interrupt may be reset (HIGH) on the rising edge of the acknowledge bit of the address byte and also on the rising edge of the write to port pulse. The interrupt will always be reset (HIGH) on the falling edge of the write to port pulse. The interrupt is reset (HIGH) in the Read mode on the rising edge of the read from port pulse .


During the interrupt reset, any I/O change close to the read or write pulse may not generate an interrupt, or the interrupt will have a very short pulse. After the interrupt is reset, any change in I/Os will be detected and transmitted as an INT.


At power-on reset all ports are in Input mode and the initial state of the ports is HIGH, therefore, for any port pin that is pulled LOW or driven LOW by external source, the interrupt output will be active (output LOW).

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Interrupt output (INT)

 

ATMega644 TWI and PCF8574AP 

Using the PCF8574AP with an AVR micro-controller could be done from scratch via its TWI or software bit banging. However I have wrote some of its most commonly used routine of hardware TWI in previous post.

ATMega644P TWI PCF8574 I/O Expansion Interfacing
AVR Experiment Board

 

In this introductory example, the ATMega644P TWI master just send data to the PCF8574AP that its output port connects to LEDs.

Source Code:

  1. /*
  2. * 10-i2c_pcf8574ap.c
  3. *
  4. * Created: 2/1/2026 8:28:10 PM
  5. * Author : Admin
  6. */

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

  10. const char pcf8574_w=0x40;
  11. const char pcf8574_r=0x41;
  12. const char pcf8574a_w=0x70;
  13. const char pcf8574a_r=0x71;

  14. void i2cInit(void){
  15. TWSR|=0x00; //Prescaler Selection Bit
  16. TWBR=0xF0; //Baud Rate Generator
  17. TWCR=(1<<TWEN); //Enable The TWI Module
  18. PORTC|=(1<<0);
  19. PORTC|=(1<<1);
  20. }

  21. void i2cStart(void){
  22. TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  23. while((TWCR&(1<<TWINT))==0);
  24. }

  25. void i2cWrite(unsigned char data){
  26. TWDR=data;
  27. TWCR=(1<<TWINT)|(1<<TWEN);
  28. while((TWCR&(1<<TWINT))==0);
  29. }

  30. unsigned char i2cRead(char ACK){
  31. if(ACK==0)
  32. TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
  33. else
  34. TWCR=(1<<TWINT)|(1<<TWEN);
  35. while((TWCR&(1<<TWINT))==0);
  36. return TWDR;
  37. }

  38. void i2cStop(){
  39. TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
  40. _delay_us(10);
  41. }

  42. int main(void)
  43. {
  44. /* Replace with your application code */
  45. i2cInit();
  46. char temp=0;
  47. while (1)
  48. {
  49. i2cStart();
  50. i2cWrite(pcf8574a_w);
  51. i2cWrite(~temp);
  52. i2cStop();
  53. temp++;
  54. _delay_ms(250);
  55. }
  56. }

Schematic:

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Schematic and Simulation

AVR Experiment Board:

ATMega644P TWI PCF8574 I/O Expansion Interfacing
AVR Experiment Board

ATMega644P TWI PCF8574 I/O Expansion Interfacing
AVR Experiment Board

I have been using PCBWay for many years now. PCBWay fabricate PCBs at low cost, fast processing time for only 24 hours, and fast delivery time using any carrier options. This double side 10cmx10cm can be fabricate at only 5USD for 5 to 10pcs by PCBWay. It's a standard PCB with silk screen and solder mask.

A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
10 PCBs for only 5USD
 

For different size of PCB we can instantly quote on PCBWay website using a zip PCB Gerber file without account.

A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
PCBWay Instant Quote

 

However the I/O port of this chip is bi-directional. So we can use it read the input from any sensors or buttons. This example the master MCU read the input from the lower nibble of the PCF8574AP and display it back to the higher nibble of the PCF8574AP.

Source Code:

  1. /*
  2. * 10-i2c_pcf8574ap_r_w.c
  3. *
  4. * Created: 2/1/2026 8:49:04 PM
  5. * Author : Admin
  6. */

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

  10. const char pcf8574_w=0x40;
  11. const char pcf8574_r=0x41;
  12. const char pcf8574a_w=0x70;
  13. const char pcf8574a_r=0x71;

  14. void i2cInit(void){
  15. TWSR|=0x00; //Prescaler Selection Bit
  16. TWBR=0xF0; //Baud Rate Generator
  17. TWCR=(1<<TWEN); //Enable The TWI Module
  18. PORTC|=(1<<0);
  19. PORTC|=(1<<1);
  20. }

  21. void i2cStart(void){
  22. TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  23. while((TWCR&(1<<TWINT))==0);
  24. }

  25. void i2cWrite(unsigned char data){
  26. TWDR=data;
  27. TWCR=(1<<TWINT)|(1<<TWEN);
  28. while((TWCR&(1<<TWINT))==0);
  29. }

  30. unsigned char i2cRead(char ACK){
  31. if(ACK==0)
  32. TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
  33. else
  34. TWCR=(1<<TWINT)|(1<<TWEN);
  35. while((TWCR&(1<<TWINT))==0);
  36. return TWDR;
  37. }

  38. void i2cStop(){
  39. TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
  40. _delay_us(10);
  41. }

  42. int main(void)
  43. {
  44. /* Replace with your application code */
  45. i2cInit();
  46. char temp=0;
  47. i2cStart();
  48. i2cWrite(pcf8574a_w);
  49. i2cWrite(0x0F);
  50. i2cStop();
  51. while (1)
  52. {
  53. i2cStart();
  54. i2cWrite(pcf8574a_r);
  55. temp=i2cRead(1);
  56. i2cStop();
  57. temp<<=4;
  58. i2cStart();
  59. i2cWrite(pcf8574a_w);
  60. i2cWrite(temp|0x0F);
  61. i2cStop();
  62. }
  63. }





Schematic:

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Schematic and Simulation

AVR Experiment Board: 

ATMega644P TWI PCF8574 I/O Expansion Interfacing
Program Test on my AVR Prototype Board

 

 


 

 

Ad Unit #2456555

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) AVR PCB (2) 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 (76) Interrupt (22) IoT PCB (1) 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) Module PCB (1) 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) PIC16 (105) 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) PICMicro PCB (4) 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)