Menu

Adskeeper - header widge

728x90

Search This Blog

468x60

Navbar

AdsKeeper - IAB Display Standard Ad Unit

Monday, October 12, 2026

dsPIC30F2010 and SN74HC595N 16x4 Character LCD

Introduction

The SN74HC595N outputs can control any devices such relays, LED, or even a HD44780-based character LCD. Using a single SN74HC595N shift registers a master MCU can control a character LCD using the LCD 4-bit data transfer mode.

 

dsPIC30F2010 and SN74HC595N 16x4 Character LCD
Information Screen

I made my own serial character LCD using a SN74HC595N chip, a TC1604-01 16x4 HD44780 LCD, some passive components, and a DIY PCB.

 

dsPIC30F2010 and SN74HC595N 16x4 Character LCD
DIY SN74HC595N 16x4 Serial LCD using TC1604-01 HD44780

However using its 4-bit data transfer mode, we need to care about the LCD RS and Enable Pin since the nibbles have to transfer twice. 

dsPIC30F2010 LCD Programming in MikroC

I need to write my own LCD driver routine for this example. However the source code is difficult than using the direct 4-bit LCD interface.

We can wire your own SPI LCD using the schematic below.

Schematic: 

 

dsPIC30F2010 and SN74HC595N 16x4 Character LCD
Schematic Diagram

 

However the 16x2 and the 16x4 LCD pin outs are the same. We can use one of these.

In this example, the dsPIC30F2010 show some texts on this serial LCD module. 

MikroC Source Code:

 

  1. /*TWI LCD Driver*/
  2. #define RS 1
  3. #define RW 2
  4. #define EN 3
  5. #define BL 0

  6. // Chip Select Pin
  7. sbit Chip_Select at LATE3_bit;
  8. sbit Chip_Select_Direction at TRISE3_bit;

  9. char backLight=0;

  10. void lcd_delay(unsigned int counts){
  11. unsigned int i=0;
  12. for (i=0;i<counts;i++);
  13. }

  14. void spi_lcd_command(char command){
  15. char _data;
  16. _data=command&0xF0;
  17. SPI1_Write(_data|(backLight<<BL)|(1<<EN));
  18. Chip_Select = 0; // Select SPI chip
  19. Chip_Select = 1; // Deselect SPI chip

  20. SPI1_Write(_data|(backLight<<BL));
  21. Chip_Select = 0; // Select SPI chip
  22. Chip_Select = 1; // Deselect SPI chip

  23. _data=command<<4;
  24. SPI1_Write(_data|(backLight<<BL)|(1<<EN));

  25. Chip_Select = 0; // Select SPI chip
  26. lcd_delay(10);

  27. Chip_Select = 1; // Deselect SPI chip
  28. SPI1_Write(_data|(backLight<<BL));
  29. Chip_Select = 0; // Select SPI chip
  30. Chip_Select = 1; // Deselect SPI chip
  31. }

  32. void spi_lcd___data(char command){
  33. char __data;
  34. __data=command&0xF0;
  35. SPI1_Write(__data|(backLight<<BL)|(1<<EN)|(1<<RS));
  36. Chip_Select = 0; // Select SPI chip
  37. Chip_Select = 1; // Deselect SPI chip
  38. SPI1_Write(__data|(backLight<<BL)|(1<<RS));
  39. Chip_Select = 0; // Select SPI chip
  40. Chip_Select = 1; // Deselect SPI chip
  41. lcd_delay(50);

  42. __data=command<<4;
  43. SPI1_Write(__data|(backLight<<BL)|(1<<EN)|(1<<RS));
  44. Chip_Select = 0; // Select SPI chip
  45. Chip_Select = 1; // Deselect SPI chip
  46. SPI1_Write(__data|(backLight<<BL)|(1<<RS));
  47. Chip_Select = 0; // Select SPI chip
  48. Chip_Select = 1; // Deselect SPI chip
  49. }

  50. void spi_lcd_xy(char x, char y){
  51. //16x2
  52. //char addr[]={0x80,0xC0};
  53. //16x4
  54. char addr[]={0x80,0xC0,0x90,0xD0};
  55. spi_lcd_command(addr[y-1]+x-1);
  56. }

  57. void spi_lcd_line_1(void){
  58. spi_lcd_command(0x80);
  59. }

  60. void spi_lcd_line_2(void){
  61. spi_lcd_command(0xC0);
  62. }

  63. void spi_lcd_line_3(void){
  64. spi_lcd_command(0x90);
  65. }

  66. void spi_lcd_line_4(void){
  67. spi_lcd_command(0xD0);
  68. }

  69. void spi_lcd_cursor_off(void){
  70. spi_lcd_command(0x0C);
  71. }

  72. void spi_lcd_text(char *txt){
  73. while(*txt) spi_lcd___data(*txt++);
  74. }

  75. void i2c_lcdClear(void){
  76. spi_lcd_command(0x01);
  77. Delay_ms(10);
  78. }

  79. void spi_lcd_init(void){

  80. SPI1_Write(0);
  81. lcd_delay(500);
  82. spi_lcd_command(0x33);
  83. lcd_delay(10);
  84. spi_lcd_command(0x32);
  85. lcd_delay(10);
  86. spi_lcd_command(0x28);
  87. lcd_delay(10);
  88. spi_lcd_command(0x0F);
  89. lcd_delay(10);
  90. spi_lcd_command(0x01);
  91. Delay_ms(20);
  92. spi_lcd_command(0x06);
  93. lcd_delay(50);
  94. }

  95. void main() {
  96. Chip_Select = 1;
  97. Chip_Select_Direction = 0; // Set CS# pin as Output
  98. SPI1_Init(); // Initialize SPI module
  99. spi_lcd_init();
  100. Chip_Select = 1;
  101. spi_lcd_line_1();
  102. spi_lcd_text("dsPIC30F2010 SPI");
  103. spi_lcd_line_2();
  104. spi_lcd_text("SN74HC595N LCD");
  105. spi_lcd_line_3();
  106. spi_lcd_text("Programming with");
  107. spi_lcd_line_4();
  108. spi_lcd_text("MikroC for dsPIC");
  109. while(1){
  110. }
  111. }

 

I tested this program on my DIY dsPIC30F1010 Prototype Board. It works fine. 

 

dsPIC30F2010 and SN74HC595N 16x4 Character LCD
DIY dsPIC30F1010 Prototype Board

 

 

dsPIC30F2010 Simple DVM Serial LCD

There are one on-board POT. So we can make a simple 5VDC serial display digital voltmeter.  The variable DC input voltage is connect to RB4(AN4) pin via  a POT. Its maximum measurement is 5VDC since the supply and ADC reference voltage is 5VDC.


dsPIC30F2010 and SN74HC595N 16x4 Character LCD
dsPIC30F2010 and SN74HC595N 16x4 Character LCD


MikroC Source Code:

 

  1. /*TWI LCD Driver*/
  2. #define RS 1
  3. #define RW 2
  4. #define EN 3
  5. #define BL 0

  6. // Chip Select Pin
  7. sbit Chip_Select at LATE3_bit;
  8. sbit Chip_Select_Direction at TRISE3_bit;

  9. char backLight=0;

  10. void lcd_delay(unsigned int counts){
  11. unsigned int i=0;
  12. for (i=0;i<counts;i++);
  13. }

  14. void spi_lcd_command(char command){
  15. char _data;
  16. _data=command&0xF0;
  17. SPI1_Write(_data|(backLight<<BL)|(1<<EN));
  18. Chip_Select = 0; // Select SPI chip
  19. Chip_Select = 1; // Deselect SPI chip

  20. SPI1_Write(_data|(backLight<<BL));
  21. Chip_Select = 0; // Select SPI chip
  22. Chip_Select = 1; // Deselect SPI chip

  23. _data=command<<4;
  24. SPI1_Write(_data|(backLight<<BL)|(1<<EN));

  25. Chip_Select = 0; // Select SPI chip
  26. lcd_delay(10);

  27. Chip_Select = 1; // Deselect SPI chip
  28. SPI1_Write(_data|(backLight<<BL));
  29. Chip_Select = 0; // Select SPI chip
  30. Chip_Select = 1; // Deselect SPI chip
  31. }

  32. void spi_lcd___data(char command){
  33. char __data;
  34. __data=command&0xF0;
  35. SPI1_Write(__data|(backLight<<BL)|(1<<EN)|(1<<RS));
  36. Chip_Select = 0; // Select SPI chip
  37. Chip_Select = 1; // Deselect SPI chip
  38. SPI1_Write(__data|(backLight<<BL)|(1<<RS));
  39. Chip_Select = 0; // Select SPI chip
  40. Chip_Select = 1; // Deselect SPI chip
  41. lcd_delay(50);

  42. __data=command<<4;
  43. SPI1_Write(__data|(backLight<<BL)|(1<<EN)|(1<<RS));
  44. Chip_Select = 0; // Select SPI chip
  45. Chip_Select = 1; // Deselect SPI chip
  46. SPI1_Write(__data|(backLight<<BL)|(1<<RS));
  47. Chip_Select = 0; // Select SPI chip
  48. Chip_Select = 1; // Deselect SPI chip
  49. }

  50. void spi_lcd_xy(char x, char y){
  51. //16x2
  52. //char addr[]={0x80,0xC0};
  53. //16x4
  54. char addr[]={0x80,0xC0,0x90,0xD0};
  55. spi_lcd_command(addr[y-1]+x-1);
  56. }

  57. void spi_lcd_line_1(void){
  58. spi_lcd_command(0x80);
  59. }

  60. void spi_lcd_line_2(void){
  61. spi_lcd_command(0xC0);
  62. }

  63. void spi_lcd_line_3(void){
  64. spi_lcd_command(0x90);
  65. }

  66. void spi_lcd_line_4(void){
  67. spi_lcd_command(0xD0);
  68. }

  69. void spi_lcd_cursor_off(void){
  70. spi_lcd_command(0x0C);
  71. }

  72. void spi_lcd_text(char *txt){
  73. while(*txt) spi_lcd___data(*txt++);
  74. }

  75. void i2c_lcdClear(void){
  76. spi_lcd_command(0x01);
  77. Delay_ms(10);
  78. }

  79. void spi_lcd_init(void){

  80. SPI1_Write(0);
  81. lcd_delay(500);
  82. spi_lcd_command(0x33);
  83. lcd_delay(10);
  84. spi_lcd_command(0x32);
  85. lcd_delay(10);
  86. spi_lcd_command(0x28);
  87. lcd_delay(10);
  88. spi_lcd_command(0x0C);
  89. lcd_delay(10);
  90. spi_lcd_command(0x01);
  91. Delay_ms(20);
  92. //spi_lcd_command(0x06);
  93. lcd_delay(50);
  94. }

  95. void main() {
  96. unsigned int temp_res;
  97. float voltage=0;
  98. char text[16];
  99. TRISB = 0xFFFF; // PORTB is input
  100. ADC1_Init(); // Enable ADC module
  101. Delay_ms(10);
  102. Chip_Select = 1;
  103. Chip_Select_Direction = 0; // Set CS# pin as Output
  104. SPI1_Init(); // Initialize SPI module
  105. spi_lcd_init();
  106. Chip_Select = 1;
  107. spi_lcd_line_1();
  108. spi_lcd_text("dsPIC30F2010 ADC");
  109. spi_lcd_line_2();
  110. spi_lcd_text("SN74HC595N SPI");
  111. spi_lcd_line_3();
  112. spi_lcd_text("LCD Voltmeter");
  113. spi_lcd_line_4();
  114. spi_lcd_text("MikroC for dsPIC");
  115. Delay_ms(5000);
  116. spi_lcd_command(0x01);
  117. Delay_ms(20);
  118. while(1){
  119. // Get 10-bit results of AD conversion
  120. temp_res = ADC1_Read(4);
  121. voltage = (5.0 * temp_res)/1023;
  122. spi_lcd_line_1();
  123. spi_lcd_text(" AN4 ADC:");
  124. spi_lcd_line_2();
  125. sprintf(text," %4d Decimal",temp_res);
  126. spi_lcd_text(text);
  127. spi_lcd_line_3();
  128. spi_lcd_text(" Voltage:");
  129. spi_lcd_line_4();
  130. sprintf(text," %0.4f Volts",voltage);
  131. spi_lcd_text(text);
  132. Delay_ms(500);
  133. }
  134. }


DIY dsPIC30F2010 Prototype Board:

 

dsPIC30F2010 and SN74HC595N 16x4 Character LCD
ADC Voltage Reading


dsPIC30F2010 and SN74HC595N 16x4 Character LCD
ADC Voltage Reading


dsPIC30F2010 and SN74HC595N 16x4 Character LCD
ADC Voltage Reading


dsPIC30F2010 and SN74HC595N 16x4 Character LCD
Information Screen

 

 


 

 

 

 

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 (39) 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 (12) dsPIC30F1010 (3) dsPIC30F2010 (12) EEPROM (5) Environment Sensor (6) ESP32 (1) esp8266 (1) Graphical LCD (3) HD44780 (10) I2C (38) ILI9341 (1) Input/Output (83) Interrupt (22) IoT PCB (1) Keil (5) Keypad (16) KS0108 (3) LCD (84) LM35 (4) Master/Slave (2) MAX7221 (1) MCP23017 (8) MCP23S17 (7) MCP4921 (1) MCP4922 (2) Meter (3) MikroC (2) MikroC ARM (1) MikroC dsPIC (7) Module PCB (2) Motor (15) MPLABX (73) Nokia 5110 LCD (4) OLED (2) One-Wire (7) Oscillator (8) PCB (13) PCD8544 (3) PCF8574 (10) PIC (116) 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 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)