Saturday, January 20, 2024

PIC16F887 PCF8574AP I2C LCD Example using XC8

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.

PIC16F887 PCF8574AP I2C LCD Example using XC8
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.

PIC16F887 PCF8574AP I2C LCD Example using XC8
Program Testing on Prototype Board

 I use use my own DIY PCF8574AP character LCD module. Its schematic is shown below.

PIC16F887 PCF8574AP I2C LCD Example using XC8
PCF8574AP Character LCD Module Schematic

Its slave address are 0x70 and 0x71.

PIC16F887 PCF8574AP I2C LCD Example using XC8
DIY PCF8574AP Character LCD Module

PIC16F887 PCF8574AP I2C LCD Example using XC8
DIY PCF8574AP Character LCD Module

You can use an Arduino PCF8574 LCD module with different address.

PIC16F887 PCF8574AP I2C LCD Example using XC8
Arduino PCF8574 LCD module

PIC16F887 PCF8574AP I2C LCD Example using XC8
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.

  1. /*
  2.  * File: main.c
  3.  * Author: Admin
  4.  *
  5.  * Created on January 19, 2024, 3:36 PM
  6.  */
  7.  
  8. #include <xc.h>
  9. #include "config.h"
  10. #include "pcf8574.h"
  11. #include <stdio.h>
  12.  
  13. #define _XTAL_FREQ 8000000UL
  14.  
  15. #define RS 0
  16. #define RW 1
  17. #define EN 2
  18. #define BL 3
  19.  
  20. __bit backLight=0;
  21.  
  22. void i2c_lcdCommand(uint8_t command){
  23. uint8_t data;
  24. data=command&0xF0;
  25. pcf8574Write(data|(backLight<<BL)|(1<<EN));
  26. __delay_us(10);
  27. pcf8574Write(data|(backLight<<BL));
  28. __delay_us(50);
  29.  
  30. data=command<<4;
  31. pcf8574Write(data|(backLight<<BL)|(1<<EN));
  32. __delay_us(10);
  33. pcf8574Write(data|(backLight<<BL));
  34. __delay_us(50);
  35. }
  36.  
  37. void i2c_lcdData(uint8_t command){
  38. uint8_t data;
  39. data=command&0xF0;
  40. pcf8574Write(data|(backLight<<BL)|(1<<EN)|(1<<RS));
  41. __delay_us(10);
  42. pcf8574Write(data|(backLight<<BL)|(1<<RS));
  43. __delay_us(50);
  44.  
  45. data=command<<4;
  46. pcf8574Write(data|(backLight<<BL)|(1<<EN)|(1<<RS));
  47. __delay_us(10);
  48. pcf8574Write(data|(backLight<<BL)|(1<<RS));
  49. __delay_us(50);
  50. }
  51.  
  52. void i2c_lcdXY(int8_t x, int8_t y){
  53. int8_t addr[]={0x80,0xC0};
  54. i2c_lcdCommand(addr[y-1]+x-1);
  55. }
  56.  
  57. void i2c_lcdText(int8_t *txt){
  58. while(*txt) i2c_lcdData(*txt++);
  59. }
  60.  
  61. void i2c_lcdClear(void){
  62. i2c_lcdCommand(0x01);
  63. __delay_ms(5);
  64. }
  65.  
  66. void i2c_lcdInit(void){
  67. i2c_init(100000);
  68. __delay_us(10);
  69. pcf8574Write(0);
  70. __delay_ms(10);
  71. i2c_lcdCommand(0x33);
  72. __delay_us(10);
  73. i2c_lcdCommand(0x32);
  74. __delay_us(10);
  75. i2c_lcdCommand(0x28);
  76. __delay_us(10);
  77. i2c_lcdCommand(0x0F);
  78. __delay_us(10);
  79. i2c_lcdCommand(0x01);
  80. __delay_ms(5);
  81. i2c_lcdCommand(0x06);
  82. __delay_us(10);
  83. }
  84.  
  85. void main(void) {
  86. OSCCONbits.IRCF=7;
  87. i2c_lcdInit();
  88. backLight=1;
  89. __delay_ms(1000);
  90. i2c_lcdText(" PIC16F887 I2C");
  91. i2c_lcdXY(1,2);
  92. i2c_lcdText(" PCF8574AP LCD");
  93. long counter=0;
  94. uint8_t msg[10];
  95. __delay_ms(2000);
  96. i2c_lcdClear();
  97. i2c_lcdCommand(0x0C);
  98. i2c_lcdText("Counter Variable");
  99. while(1){
  100. sprintf(msg,"%u",counter);
  101. i2c_lcdXY(1,2);
  102. i2c_lcdText(msg);
  103. counter++;
  104. __delay_ms(250);
  105. }
  106. return;
  107. }
  108.  

I use Proteus VSM to design and simulating this program before it will be tested on a prototype board.

PIC16F887 PCF8574AP I2C LCD Example using XC8
Simulating Program in Proteus

PIC16F887 PCF8574AP I2C LCD Example using XC8
Simulating Program in Proteus


Click here to download this example from GitHub.

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 (56) 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 (47) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (71) 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 (3) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (31) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)