Menu

Adskeeper - header widge

728x90

Search This Blog

468x60

Navbar

AdsKeeper - IAB Display Standard Ad Unit

Wednesday, October 14, 2026

dsPIC30F2010 I2C PCF8574T HD44780 LCD

Introduction

In previous post, I use the PCF8574AP DIP-16 chip to expand the output of dsPIC30F2010. Since this chip is an 8-bit bi-directional I/O device, it can be used to connect to any I/O peripheral devices. even an HD44780 character LCD. 

 

dsPIC30F2010 I2C PCF8574T HD44780 LCD
Test Program

A character LCD module comes with a PCF8574T is very popular and low cost. It is commonly an Arduino LCD module widely used among the students and electronic hobbyists. There are a lot of Arduino programming examples for this stuffs. 

 

dsPIC30F2010 Simple I2C LCD using PCF8574T 

Controlling an HD44780 character LCD via a PCF8574T is very easy with some additional code to process the 4-bit data transfer mode of the LCD chip controller. In this example, the I2C master micro-controller send some character to a 16x2 character LCD via a PCF8574T chip. 

Schematic:

dsPIC30F2010 I2C PCF8574T HD44780 LCD
Schematic

 This post show a full I2C devices interfacing examples using an ATMega644P AVR chip.

MikroC Source Code:



  1. const char PCF8574_W=0x40;
  2. const char PCF8574_R=0x41;
  3. const char PCF8574T_LCD_W=0x4E;
  4. const char PCF8574T_LCD_R=0x4F;
  5. const char PCF8574A_W=0x70;
  6. const char PCF8574A_R=0x71;

  7. void pcf8574_write(char _data){
  8. I2C1_Start(); // issue I2C start signal
  9. I2C1_Write(PCF8574T_LCD_W); // send byte via I2C (device address + W)
  10. I2C1_Write(_data); // send byte (data address)
  11. I2C1_Stop(); // issue I2C stop signal
  12. }

  13. /*TWI LCD Driver*/
  14. #define RS 0
  15. #define RW 1
  16. #define EN 2
  17. #define BL 3

  18. #define i2c_lcd_cursor_off() i2c_lcd_command(0x0C)
  19. #define i2c_lcd_line_1() i2c_lcd_command(0x80)
  20. #define i2c_lcd_line_2() i2c_lcd_command(0xC0)

  21. char backLight=1;

  22. void i2c_lcd_command(char command){
  23. char _data;
  24. _data=command&0xF0;
  25. pcf8574_write(_data|(backLight<<BL)|(1<<EN));
  26. //_delay_us(10);
  27. pcf8574_write(_data|(backLight<<BL));
  28. //_delay_us(50);

  29. _data=command<<4;
  30. pcf8574_write(_data|(backLight<<BL)|(1<<EN));
  31. //_delay_us(10);
  32. pcf8574_write(_data|(backLight<<BL));
  33. //_delay_us(50);
  34. }

  35. void i2c_lcd__data(char command){
  36. char _data;
  37. _data=command&0xF0;
  38. pcf8574_write(_data|(backLight<<BL)|(1<<EN)|(1<<RS));
  39. //_delay_us(10);
  40. pcf8574_write(_data|(backLight<<BL)|(1<<RS));
  41. Delay_us(50);

  42. _data=command<<4;
  43. pcf8574_write(_data|(backLight<<BL)|(1<<EN)|(1<<RS));
  44. //Delay_us(10);
  45. pcf8574_write(_data|(backLight<<BL)|(1<<RS));
  46. //Delay_us(50);
  47. }

  48. void i2c_lcd_xy(char x, char y){
  49. char addr[]={0x80,0xC0};
  50. i2c_lcd_command(addr[y-1]+x-1);
  51. }

  52. void i2c_lcd_text(char *txt){
  53. while(*txt) i2c_lcd__data(*txt++);
  54. }

  55. void i2c_lcd_clear(void){
  56. i2c_lcd_command(0x01);
  57. Delay_ms(5);
  58. }

  59. void i2c_lcd_init(void){
  60. pcf8574_write(0);
  61. Delay_ms(10);
  62. i2c_lcd_command(0x33);
  63. Delay_us(10);
  64. i2c_lcd_command(0x32);
  65. Delay_us(10);
  66. i2c_lcd_command(0x28);
  67. Delay_us(10);
  68. i2c_lcd_command(0x0F);
  69. Delay_us(10);
  70. i2c_lcd_command(0x01);
  71. Delay_ms(10);
  72. i2c_lcd_command(0x06);
  73. Delay_us(10);
  74. }

  75. void main(){
  76. char temp = 0, i = 0;
  77. I2C1_Init(10000); // initialize I2C communication
  78. Delay_ms(10);
  79. i2c_lcd_init();
  80. Delay_ms(10);
  81. i2c_lcd_text("dsPIC30F2010 I2C");
  82. i2c_lcd_line_2();
  83. i2c_lcd_text("PCF8574T LCD");
  84. i2c_lcd_cursor_off();

  85. while(1){

  86. }
  87. }


I test this example on my DIY dsPIC30F2010 Prototype Board. It works fine.

 

dsPIC30F2010 I2C PCF8574T HD44780 LCD
My DIY dsPIC30F2010 Prototype Board

dsPIC30F2010 5V DVM I2C LCD using PCF8574T 

There is one on-board POT. So I made a simple 5VDC Digital Volt Meter with this I2C LCD. The schematic remains the same a above.

 

dsPIC30F2010 I2C PCF8574T HD44780 LCD
Test Program

 

MikroC Source Code:



  1. const char PCF8574_W=0x40;
  2. const char PCF8574_R=0x41;
  3. const char PCF8574T_LCD_W=0x4E;
  4. const char PCF8574T_LCD_R=0x4F;
  5. const char PCF8574A_W=0x70;
  6. const char PCF8574A_R=0x71;

  7. void pcf8574_write(char _data){
  8. I2C1_Start(); // issue I2C start signal
  9. I2C1_Write(PCF8574T_LCD_W); // send byte via I2C (device address + W)
  10. I2C1_Write(_data); // send byte (data address)
  11. I2C1_Stop(); // issue I2C stop signal
  12. }

  13. /*TWI LCD Driver*/
  14. #define RS 0
  15. #define RW 1
  16. #define EN 2
  17. #define BL 3

  18. #define i2c_lcd_cursor_off() i2c_lcd_command(0x0C)
  19. #define i2c_lcd_line_1() i2c_lcd_command(0x80)
  20. #define i2c_lcd_line_2() i2c_lcd_command(0xC0)

  21. char backLight=1;

  22. void i2c_lcd_command(char command){
  23. char _data;
  24. _data=command&0xF0;
  25. pcf8574_write(_data|(backLight<<BL)|(1<<EN));
  26. //_delay_us(10);
  27. pcf8574_write(_data|(backLight<<BL));
  28. //_delay_us(50);

  29. _data=command<<4;
  30. pcf8574_write(_data|(backLight<<BL)|(1<<EN));
  31. //_delay_us(10);
  32. pcf8574_write(_data|(backLight<<BL));
  33. //_delay_us(50);
  34. }

  35. void i2c_lcd__data(char command){
  36. char _data;
  37. _data=command&0xF0;
  38. pcf8574_write(_data|(backLight<<BL)|(1<<EN)|(1<<RS));
  39. //_delay_us(10);
  40. pcf8574_write(_data|(backLight<<BL)|(1<<RS));
  41. Delay_us(50);

  42. _data=command<<4;
  43. pcf8574_write(_data|(backLight<<BL)|(1<<EN)|(1<<RS));
  44. //Delay_us(10);
  45. pcf8574_write(_data|(backLight<<BL)|(1<<RS));
  46. //Delay_us(50);
  47. }

  48. void i2c_lcd_xy(char x, char y){
  49. char addr[]={0x80,0xC0};
  50. i2c_lcd_command(addr[y-1]+x-1);
  51. }

  52. void i2c_lcd_text(char *txt){
  53. while(*txt) i2c_lcd__data(*txt++);
  54. }

  55. void i2c_lcd_clear(void){
  56. i2c_lcd_command(0x01);
  57. Delay_ms(10);
  58. }

  59. void i2c_lcd_init(void){
  60. pcf8574_write(0);
  61. Delay_ms(10);
  62. i2c_lcd_command(0x33);
  63. Delay_us(10);
  64. i2c_lcd_command(0x32);
  65. Delay_us(10);
  66. i2c_lcd_command(0x28);
  67. Delay_us(10);
  68. i2c_lcd_command(0x0F);
  69. Delay_us(10);
  70. i2c_lcd_command(0x01);
  71. Delay_ms(10);
  72. i2c_lcd_command(0x06);
  73. Delay_us(10);
  74. }

  75. void main(){
  76. unsigned int adc_rd;
  77. char text[16];
  78. long tlong;
  79. float voltage;
  80. ADPCFG = 0xFFFF; // Configure AN pins as digital
  81. I2C1_Init(10000); // initialize I2C communication
  82. Delay_ms(10);
  83. i2c_lcd_init();
  84. Delay_ms(10);
  85. i2c_lcd_text("dsPIC30F2010 I2C");
  86. i2c_lcd_line_2();
  87. i2c_lcd_text("ADC PCF8574T LCD");
  88. i2c_lcd_cursor_off();
  89. Delay_ms(10000);
  90. i2c_lcd_clear();
  91. while(1){
  92. adc_rd = ADC1_read(4); // get ADC value from 2nd channel
  93. voltage = 5.0*adc_rd/1023;
  94. i2c_lcd_line_1();
  95. sprintf(text,"AN4 ADC: %4d 10", adc_rd);
  96. i2c_lcd_text(text);
  97. i2c_lcd_line_2();
  98. sprintf(text,"Voltage: %.2f V", voltage);
  99. i2c_lcd_text(text);
  100. Delay_ms(500);
  101. }
  102. }

 

Using program C sprintf function is very easy to convert any data type into an array of ASCII characters. But it requires a lot of memory space. For limited ROM and RAM space, we can process the text, character, integer and floating point numbers one-by-one before sending it to UART or LCD stream. This post shows a simple number to ASCII character converting.

Archive: 

dsPIC30F2010 I2C PCF8574T HD44780 LCD
ADC Read Voltage 0.00 V

dsPIC30F2010 I2C PCF8574T HD44780 LCD
ADC Read Voltage 2.74 V

dsPIC30F2010 I2C PCF8574T HD44780 LCD
ADC Read Voltage 5.00 V


 See this short video on Youtube:

 


 

 



 

 




 

 

 

 

No comments:

Post a Comment

Adskeep- Standard Ads

336x280

DIY Electronic Projects And Instruments

AdsKeeper - 2091654

Labels

23K256 (1) 24C16B (2) 25AA010A (2) 8051 (7) 93AA46B (1) ADC (40) Analog Comparator (1) Arduino (16) ARM (32) AT89C52 (7) ATMega32 (59) ATMega644P (27) AVR (88) AVR PCB (2) Bootloader (1) CCS PICC (31) Change Notify Interrupt (CNI) (2) DAC (2) DHT11 (5) Display (156) Distance Sensor (3) dot matrix (1) ds1307 (10) DS18B20 (6) ds3231 (1) ds3232 (2) dsPIC (15) dsPIC30F1010 (3) dsPIC30F2010 (15) EEPROM (5) Environment Sensor (6) ESP32 (1) esp8266 (1) Graphical LCD (3) HD44780 (11) I2C (40) ILI9341 (1) Input/Output (83) Interrupt (22) IoT PCB (1) Keil (5) Keypad (16) KS0108 (3) LCD (86) LM35 (4) Master/Slave (2) MAX7221 (1) MCP23017 (8) MCP23S17 (7) MCP4921 (1) MCP4922 (2) Meter (3) MikroC (2) MikroC ARM (1) MikroC dsPIC (10) Module PCB (2) Motor (15) MPLABX (73) Nokia 5110 LCD (5) OLED (2) One-Wire (7) Oscillator (8) PCB (13) PCD8544 (3) PCF8574 (12) PIC (119) 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 (15) SH1106 (3) Shift Register (15) Shift Registers (19) SN74HC595N (9) Software SPI (1) Software TWI (2) SPI (44) sprinf (3) ST7735 (1) STM32 (29) STM32 Black Pill (1) STM32 Blue Pill (12) STM32 HAL (23) STM32CubeIDE (32) STM32F103C8T6 (9) STM32F103R6 (18) STM32F401CCU6 (1) SysTick (7) temperature sensor (15) TFT (1) TG12864A (1) Thermometer (22) Timer/Counter (32) TM1637 (2) twi (10) UART (11) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (96)