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.
Program Testing on Prototype Board |
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.
/* * File: main.c * Author: Admin * * Created on January 19, 2024, 3:36 PM */ #include <xc.h> #include "config.h" #include "pcf8574.h" #include <stdio.h> #define _XTAL_FREQ 8000000UL #define RS 0 #define RW 1 #define EN 2 #define BL 3 __bit backLight=0; void i2c_lcdCommand(uint8_t command){ uint8_t data; data=command&0xF0; pcf8574Write(data|(backLight<<BL)|(1<<EN)); __delay_us(10); pcf8574Write(data|(backLight<<BL)); __delay_us(50); data=command<<4; pcf8574Write(data|(backLight<<BL)|(1<<EN)); __delay_us(10); pcf8574Write(data|(backLight<<BL)); __delay_us(50); } void i2c_lcdData(uint8_t command){ uint8_t data; data=command&0xF0; pcf8574Write(data|(backLight<<BL)|(1<<EN)|(1<<RS)); __delay_us(10); pcf8574Write(data|(backLight<<BL)|(1<<RS)); __delay_us(50); data=command<<4; pcf8574Write(data|(backLight<<BL)|(1<<EN)|(1<<RS)); __delay_us(10); pcf8574Write(data|(backLight<<BL)|(1<<RS)); __delay_us(50); } void i2c_lcdXY(int8_t x, int8_t y){ int8_t addr[]={0x80,0xC0}; i2c_lcdCommand(addr[y-1]+x-1); } void i2c_lcdText(int8_t *txt){ while(*txt) i2c_lcdData(*txt++); } void i2c_lcdClear(void){ i2c_lcdCommand(0x01); __delay_ms(5); } void i2c_lcdInit(void){ i2c_init(100000); __delay_us(10); pcf8574Write(0); __delay_ms(10); i2c_lcdCommand(0x33); __delay_us(10); i2c_lcdCommand(0x32); __delay_us(10); i2c_lcdCommand(0x28); __delay_us(10); i2c_lcdCommand(0x0F); __delay_us(10); i2c_lcdCommand(0x01); __delay_ms(5); i2c_lcdCommand(0x06); __delay_us(10); } void main(void) { OSCCONbits.IRCF=7; i2c_lcdInit(); backLight=1; __delay_ms(1000); i2c_lcdText(" PIC16F887 I2C"); i2c_lcdXY(1,2); i2c_lcdText(" PCF8574AP LCD"); long counter=0; uint8_t msg[10]; __delay_ms(2000); i2c_lcdClear(); i2c_lcdCommand(0x0C); i2c_lcdText("Counter Variable"); while(1){ sprintf(msg,"%u",counter); i2c_lcdXY(1,2); i2c_lcdText(msg); counter++; __delay_ms(250); } return; }
I use Proteus VSM to design and simulating this program before it will be tested on a prototype board.
Simulating Program in Proteus |
Simulating Program in Proteus |
Click here to download this example from GitHub.
No comments:
Post a Comment