Monday, November 2, 2015

2-Wire LCD MikroC Library

Serial 2-Wire LCD MikroC Library (for HD44780 compliant controllers)
Interface PIC16F877A with 2-wire LCD
I finished building a new LCD library which makes the interfacing of the LCD displays more simple and needs only two wires.
In general the LCDs needs 6 data lines to operate in 4-bit mode but there are some microcontrollers don't have this number of available pins like the PIC12F family, which means that we have to find a solution to decrease the number of pins used by the LCD display.
The idea is sending data serially to the LCD display via shift register, this shift register is serial-in parallel-out which receives serial data from the microcontroller via two pins data pin and clock pin and then cuts this data into six (6) parts.
How to install new mikroC library:
To install a new library for mikroC pro for PIC compiler follow the following steps:
Step-1: most of new libraries comes in mpkg format and to open this format a software from MikroElectronica called Package Manager is needed and can be downloaded from its page HERE 
Step-2: after installing Package Manager open the library file and a window like the following will be opened:
package manager install new library

Step-3: go to the library below and choose the microcontrollers you want to add this library to and click on Install as shown by the following image:
add new library to mikroc

Step-4: open MikroC pro for PIC and check on the new library as shown below:
how to add new mikroc library
Library Download:

Serial LCD Library 

When the serial Lcd library is used, the following variables must be declared as in this example where the data line mapped at RD0 and the clock line at RD1:
sbit Serial_LCD_DATA at RD0_bit;
sbit Serial_LCD_CLK at RD1_bit;
sbit Serial_LCD_DATA_Direction at TRISD0_bit;
sbit Serial_LCD_CLK_Direction at TRISD1_bit;
 

Library Routines:

Serial_Lcd_Init();
Serial_Lcd_Out(char row, char column, char *text);
Serial_Lcd_Chr(char row, char column, char out_char);
Serial_Lcd_Cmd(char out_char);   // Sends command to Lcd.
The available commands of the serial Lcd library are the same as of the commands of Lcd library provided by MikroElectronica and these commands are:

     Lcd Command           Purpose
_LCD_FIRST_ROW  Move cursor to the 1st row
_LCD_SECOND_ROW  Move cursor to the 2nd row
_LCD_THIRD_ROW  Move cursor to the 3rd row
_LCD_FOURTH_ROW  Move cursor to the 4th row
_LCD_CLEAR  Clear display
_LCD_RETURN_HOME  Return cursor to home position, returns a shifted display  to  its original position. Display data RAM is unaffected.
_LCD_CURSOR_OFF  Turn off cursor
_LCD_UNDERLINE_ON  Underline cursor on
_LCD_BLINK_CURSOR_ON  Blink cursor on
_LCD_MOVE_CURSOR_LEFT  Move cursor left without changing display data RAM
_LCD_MOVE_CURSOR_RIGHT  Move cursor right without changing display data RAM
_LCD_TURN_ON  Turn Lcd display on
_LCD_TURN_OFF  Turn Lcd display off
_LCD_SHIFT_LEFT  Shift display left without changing display data RAM
_LCD_SHIFT_RIGHT  Shift display right without changing display data RAM
2-Wire LCD Library Example:
PIC16F877A and 2-wire LCD Display:
 This is just an example of how to interface PIC16F877A with a 1602 2-wire LCD display with the help of our library. The following is circuit schematic.
Note that simulation may has some errors.
pic16f877a 2 wire lcd mikroc

For simulation you have to pick the diode 1N4148 as shown on the picture below:

pic16f877a 2 wire lcd mikroc
Here the shift register used is CD4094 but other types of shift registers such as 74HC164 or 74HC595 can be used.
2-Wire LCD example mikroC Code:

// 2-Wire serial LCD display library with PIC16F877A
// Written by: BENCHEROUDA Okba
// http://www.elecnote.blogspot.com
// electronnote@gmail.com
// Use at your own risk

// LCD module connections
sbit Serial_LCD_DATA at RD0_bit;
sbit Serial_LCD_CLK at RD1_bit;
sbit Serial_LCD_DATA_Direction at TRISD0_bit;
sbit Serial_LCD_CLK_Direction at TRISD1_bit;
// End LCD module connections

 char i;
void main() {
 Serial_LCD_Init();
 Serial_LCD_Cmd(_LCD_CLEAR);
 Serial_LCD_Cmd(_LCD_CURSOR_OFF);

 Serial_Lcd_Out(1,17,"2-Wire");
 Serial_Lcd_Out(2,15,"Serial LCD");
 for(i=0; i<11; i++) {             // Move text to the left 16 times
      Serial_Lcd_Cmd(_LCD_SHIFT_LEFT);    // Shift display to the left
      Delay_ms(100);
    }
 delay_ms(5000);
 Serial_Lcd_Cmd(_LCD_CLEAR);
 Serial_Lcd_Out(1,17,"www.elecnote.");
 Serial_Lcd_Out(2,17,"blogspot.com");
 for(i=0; i<14; i++) {
      Serial_Lcd_Cmd(_LCD_SHIFT_LEFT);
      Delay_ms(100);
    }
 for(i=0; i<4; i++) {
      Serial_Lcd_Cmd(_LCD_TURN_OFF);   // Turn Lcd display off
      Delay_ms(500);
      Serial_Lcd_Cmd(_LCD_TURN_ON);    // Turn Lcd display on
      Delay_ms(500);
    }
 delay_ms(5000);
 Serial_Lcd_Cmd(_LCD_CLEAR);
 Serial_Lcd_Out(1,3,"Hello world!");
 while(1) {
   for (i =0; i<200; i++){
   Serial_Lcd_Chr(2, 8, (i/100) + 48);
   Serial_Lcd_Chr(2, 9, ((i/10) % 10) + 48);
   Serial_Lcd_Chr(2, 10, (i % 10) + 48);
   Delay_ms(200);}
    }
}

2-Wire LCD example Videos:
The following video shows our project in real circuit:


And the following video shows the simulation using Proteus and has more explanations:

References: