Thursday, January 18, 2024

PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8

The PCF8574 series is popular among Arduino users especially the character LCD driving. Its output port is 8-bit bi-directional. So we can use this chip to make a 4x4 matrix keypad. The microprocessor uses only two pins (SDA and SCL) via its I2C communication module to interface with this serial matrix keypad.

PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8
Hardware Experiment on PIC16F887 Prototype Board


I use a 4x4 membrane keypad module for Arduino. It's low cost that we doesn't need to make our own PCB.

PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8
16 Key Membrane Switch Keypad 4X4 3X4 Matrix Keyboard For Arduino Diy Kit
 


The I2C slave address of PCF8574AP (DIP-16) is 0x70 (write) and 0x71 (read) when A2...A0 are wired to GND.

PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8
PCF8574AP 16-Pin DIP

I use the on-board TinSharp TC1604A-01 16x4 character LCD module I posses.


PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8


I use the 4-bit data transfer mode to save the I/O pins of micro-controller.

PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8

Using the MPLABX IDE and its XC8 C compiler is pretty easy. Generated firmware is light-weight comparable the Assembly language. This program keep scanning the key press. Key value will show on the character LCD. The display is auto make a new line when ever the character counts reach 16. The the display is full it will clear the display and return home.


  1. /*
  2.  * File: main.c
  3.  * Author: Admin
  4.  *
  5.  * Created on January 17, 2024, 9:07 PM
  6.  */
  7.  
  8. #include <xc.h>
  9. #include "config.h"
  10. #include "lcd.h"
  11. #include "pcf8574.h"
  12.  
  13. #define _XTAL_FREQ 8000000UL
  14.  
  15. uint8_t key_16[][4]={'1','2','3','A',
  16. '4','5','6','B',
  17. '7','8','9','C',
  18. '*','0','#','D'};
  19.  
  20. uint8_t keyScan(void){
  21. char data=0,temp,key;
  22. for(uint8_t i=0;i<4;i++){
  23. data=0xFF;
  24. data&=~(1<<i);
  25. pcf8574Write(data);
  26. __delay_ms(5);
  27. data=pcf8574Read();
  28. data&=0xF0;
  29. if((data&0x10)==0) {temp=key_16[i][0]; break;}
  30. else if((data&0x20)==0){temp=key_16[i][1]; break;}
  31. else if((data&0x40)==0){temp=key_16[i][2]; break;}
  32. else if((data&0x80)==0){temp=key_16[i][3]; break;}
  33. else temp=0;
  34. __delay_ms(10);
  35. }
  36. return temp;
  37. }
  38.  
  39. void main(void) {
  40. OSCCONbits.IRCF=7;
  41. i2c_init(100000);
  42. lcdInit();
  43. __delay_ms(100);
  44. uint8_t temp,charCount=0,newLine=0,line=1;
  45. while(1){
  46. temp=keyScan();
  47. if(temp!=0){
  48. lcdData(temp);
  49. charCount++;
  50. __delay_ms(250);
  51. }
  52. if(charCount>=16){
  53. newLine=1;
  54. charCount=0;
  55. line+=1;
  56. }
  57. if(newLine){
  58. newLine=0;
  59. if(line==2) lcdXY(1,2);
  60. else if(line==3) lcdXY(1,3);
  61. else if(line==4) lcdXY(1,4);
  62. else{
  63. lcdCommand(0x01);
  64. __delay_ms(5);
  65. line=1;
  66. }
  67. }
  68. }
  69. return;
  70. }
  71.  

Click here to download this example from GitHub. I use Proteus to draw its schematic.


PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8
Program Simulation

Proteus simulation will work at slow speed due to custom firmware simulation. Using the prototype board, the firmware operation works very well without error and slowness. 


PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8

This DIY PCB has a 20MHz crystal oscillator. But the PIC16F887 has an internal 8MHz RC oscillator. So I left the XTAL1 and XTAL2 pin unconnected.

PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8

Keypad scanning runs very flexible without error on this PIC DIY prototype board.


PIC16F887 PCF8574AP I2C 4x4 KeyPad using XC8


 

If you use the PCF8574 you need to change its I2C slave address.

No comments:

Post a Comment

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (54) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (46) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (66) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (2) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (30) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)