Learn To Write Code For 8051, Arduino, AVR, dsPIC, PIC, STM32 ARM Microcontroller, etc.
Coding Embedded Controller With C/C++.
Printed Circuit Board (PCB) Project For Electronics Hobbyists.
The PCF8574 could be used for a HD44780 based character LCD controlling using the 4-bit data transfer mode. The popular one's is an Arduino TWI LCD driving using this chip.
A long hours running program
This chip has only 8 bits inputs/outputs. So it can interface with an 8-bit character LCD using the 4-bit data transfer mode. Using this method the micro-processor need to send the 8-bit command or data two time, first the higher nibble and then the lower nibble. For more information about using the PCF8574 please see this post. If you are a beginner in micro-controller programming you can see this post about 4-bit LCD interfacing.
I use use my own DIY PCF8574AP character LCD module. Its schematic is shown below.
PCF8574AP Character LCD Module Schematic
Its slave address are 0x70 and 0x71.
DIY PCF8574AP Character LCD Module
DIY PCF8574AP Character LCD Module
You can use an Arduino PCF8574 LCD module with different address.
Arduino PCF8574 LCD module
Arduino PCF8574 LCD module
In this example, The micro-controller send a counter variable to the display. It updates for every 250ms. I use the I2C module of PIC16F887. The program written in C using MPLABX IDE and its XC8 C compiler. It's free to use.
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.
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.
The I2C slave address of PCF8574AP (DIP-16) is 0x70 (write) and 0x71 (read) when A2...A0 are wired to GND.
PCF8574AP 16-Pin DIP
I use the on-board TinSharp TC1604A-01 16x4 character LCD module I posses.
I use the 4-bit data transfer mode to save the I/O pins of micro-controller.
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.
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.
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.
Keypad scanning runs very flexible without error on this PIC DIY prototype board.
If you use the PCF8574 you need to change its I2C slave address.
A keypad scanning program is common for most of micro-controller programming students. It usually done by the Assembly language programming in a micro-processor class in university. However using C compiler to program the keypad scanning process is very easy, and it's almost readable for most C programmers.
Simulating Program
Using a single 8-bit I/O port can make a 4x4 (16 keys) matrix keypad. It's divided into two nibbles, one nibble for output and another nibble for input data.
Arduino 4x4 Matrix Keypad Module
In this example, I use a PIC16F887 micro-controller to scan a 4x4 matrix keypad. Input key will show on a 16x2 character LCD.
/*
* File: main.c
* Author: Admin
*
* Created on January 16, 2024, 7:46 PM
*/
#include <xc.h>
#include "config.h"
#include "LCD4Bits.h"
#define _XTAL_FREQ 8000000UL
uint8_t key_16[][4]={'7','8','9','F',
'4','5','6','E',
'1','2','3','D',
'A','0','B','C'};
uint8_t scanKey(void){
char data=0,temp;
for(uint8_t i=0;i<4;i++){
PORTB=1<<i;
data=PORTB&0xF0;
if(data&(1<<4)){temp=key_16[i][0];break;}
elseif(data&(1<<5)){temp=key_16[i][1];break;}
elseif(data&(1<<6)){temp=key_16[i][2];break;}
elseif(data&(1<<7)){temp=key_16[i][3];break;}
else temp=0;
__delay_ms(10);
}
return temp;
}
void main(void){
OSCCONbits.IRCF=7;
uint8_t temp,count=0,row=0;
PORTB=0;
TRISB=0xF0;
ANSELH=0;
lcdInit();
while(1){
temp=scanKey();
if(temp!=0){
lcdData(temp);
count++;
__delay_ms(250);
}
if(count>16){count=0; lcdCommand(0xC0); row+=1;}
if(row>=2){
count=0;
lcdXY(1,1);
lcdCommand(0x01);
__delay_ms(10);
row=0;
}
}
return;
}
After a 16 key-press count, a new line will start. After two lines, the display will clear, and it will return home.