Skip to main content

Experiment No. 3: LCD Interface in 4-bit Mode

The objective of this experiment is to interface a 16x2 LCD to PIC16F628A in 4-bit mode. This means the data transfer will use only four pins of the microcontroller. There is no additional hardware setup needed for this experiment, as we have a ready-made LCD interface female header. We only need to define the data transfer and control pins in the software. Remember, the LCD interface in our development board uses the following pins of PIC16F628A:
Data Transfer : D4 -> RB4, D5 -> RB5, D6 -> RB6, D7 -> RB7
RS -> RA0, and EN -> RA1



Circuit Diagram:
For those who want to do this on a protoborad, here is the circuit:
Software:
 Note: Never forget to disable the comparator functions on PORTA.0, 1, 2, 3 pins if you are going to use those pins as digital I/O.
/*
 * Project name:
     Test LCD in 4-bit mode
 * Copyright:
     (c) Rajendra Bhatt, 2009.
 * Description:
     This code demonstrates how to display test message on a LCD which
     is connected to PIC16F628A through PORTB. D4-D7 pins of LCD are
     connected to RB4-RB7, whereas RS and EN pins connected to RA0 and RA1
     respectively.
     MCU:             PIC16F628A
     Oscillator:      XT, 4.0 MHz
*/
// LCD module connections
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections
// Define Messages
 char message1[] = "Testing LCD";
 char message2[] = "using PIC16F628A";
 char message3[] = "Test Successful!";
 char message4[] = "2009/09/18";
void main() {
  CMCON  |= 7;                       // Disable Comparators
  Lcd_Init();                        // Initialize LCD
  do {
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
  Lcd_Out(1,1,message1);             // Write message1 in 1st row
  Lcd_Out(2,1,message2);             // Write message1 in 2nd row
  Delay_ms(2000);
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Out(1,1,message3);             // Write message3 in 1st row
  Lcd_Out(2,1,message4);
  Delay_ms(2000);
  } while(1);
}

Experiment Output Video:



If you don't see any message on the display, try adjusting the contrast level using Contrast Adjustment Potentiometer.


Comments

  1. What does your code look like for the lcd functions:
    Lcd_Init()
    Lcd_Out()
    Lcd_Cmd()

    I am currently working on a project with a PIC18 and an LCD with a KS0066 controller. I have got the LCD to initialize but just to a blinking cursor on the first line. I am having trouble writing messages to the lcd still. Any ideas?

    ReplyDelete
    Replies
    1. I am using this program to interface lcd with pic16f628a.please check whether it is correcr or not?


      /*
      * LCD interface example
      * Uses routines from delay.c
      * This code will interface to a standard LCD controller
      * like the Hitachi HD44780. It uses it in 4 bit mode, with
      * the hardware connected as follows (the standard 14 pin
      * LCD connector is used):
      *
      * PORTD bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
      * PORTA bit 3 is connected to the LCD RS input (register select)
      * PORTA bit 1 is connected to the LCD EN bit (enable)
      *
      * To use these routines, set up the port I/O (TRISA, TRISD) then
      * call lcd_init(), then other routines as required.
      *
      */

      #ifndef _XTAL_FREQ
      // Unless specified elsewhere, 4MHz system frequency is assumed
      #define _XTAL_FREQ 4000000
      #endif


      #include
      #include "lcd.h"

      #define LCD_RS RA3
      #define LCD_RW RA2
      #define LCD_EN RA1

      #define LCD_DATA PORTB

      #define LCD_STROBE() ((LCD_EN = 1),(LCD_EN=0))

      /* write a byte to the LCD in 4 bit mode */

      void
      lcd_write(unsigned char c)
      {
      __delay_us(40);
      LCD_DATA = ( ( c >> 4 ) & 0x0F );
      LCD_STROBE();
      LCD_DATA = ( c & 0x0F );
      LCD_STROBE();
      }

      /*
      * Clear and home the LCD
      */

      void
      lcd_clear(void)
      {
      LCD_RS = 0;
      lcd_write(0x1);
      __delay_ms(2);
      }

      /* write a string of chars to the LCD */

      void
      lcd_puts(const char * s)
      {
      LCD_RS = 1; // write characters
      while(*s)
      lcd_write(*s++);
      }

      /* write one character to the LCD */

      void
      lcd_putch(char c)
      {
      LCD_RS = 1; // write characters
      lcd_write( c );
      }


      /*
      * Go to the specified position
      */

      void
      lcd_goto(unsigned char pos)
      {
      LCD_RS = 0;
      lcd_write(0x80+pos);
      }

      /* initialise the LCD - put into 4 bit mode */
      void
      lcd_init()
      {
      char init_value;

      // ADCON1 = 0x06; // Disable analog pins on PORTA
      TRISA=0;
      TRISB=0;

      CMCON = 0b00000111; // disable comparators
      init_value = 0x3;

      LCD_RS = 0;
      LCD_EN = 0;
      LCD_RW = 0;

      __delay_ms(15); // wait 15mSec after power applied,
      LCD_DATA = init_value;
      LCD_STROBE();
      __delay_ms(5);
      LCD_STROBE();
      __delay_us(200);
      LCD_STROBE();
      __delay_us(200);
      LCD_DATA = 2; // Four bit mode
      LCD_STROBE();

      lcd_write(0x28); // Set interface length
      lcd_write(0xF); // Display On, Cursor On, Cursor Blink
      lcd_clear(); // Clear screen
      lcd_write(0x6); // Set entry Mode
      }



      and

      include
      #include "lcd.h"


      void
      main(void)
      {
      TRISB = 0x00;
      TRISA = 0x00;
      CMCON = 0b00000111; // disable comparators
      PORTB = 0x00; // all low
      PORTA = 0x00;
      lcd_init();
      lcd_goto(0); // select first line
      lcd_puts("1234");
      //lcd_goto(0x40); // Select second line
      //lcd_puts("Hello world");

      for(;;);
      }

      Delete
  2. What do you mean by "code look like for LCD"? Do you mean how my code looks in assembly language?

    ReplyDelete
  3. Basically where is the rest of your code? For the LCD commands that I listed above. I wanted to take a look at them to see if I was sending data to the LCD correctly.

    Did you write your code in assembly and then write your main file code in C. I didn't think that was possible.

    ReplyDelete
  4. Lcd_Init(), Lcd_Out(), Lcd_Cmd() are built in library functions for interfacing LCD to PIC using mikroC compiler for PIC. When you compile, mikroC will convert these functions to assembly language. Read mikroC manual here: http://www.mikroe.com/en/download/

    ReplyDelete
  5. I have to do a project of an alarm system... and a part of it is a lcd display... i would like to test yours, but i don't really know how pic works...
    do you have the schematic of this circuit you used?
    thank you

    ReplyDelete
  6. The complete schematic of my circuit board is available here.
    http://pic16f628a.blogspot.com/2009/09/pic16f628a-development-board-part-1.html

    ReplyDelete
  7. Hey Josilene,
    I have posted the circuit that you were looking for.
    Thanks

    ReplyDelete
  8. Can you please upload a tutorial for Nokia 3310 LCD interface to PIC16F628A?

    ReplyDelete
  9. I done the all but nothing is showing on LCD just a blank screen with back green light. i also tried with contrast low,high and medium also but nothing on screen how to check this out or troubleshooting this....

    Thanks in advance.

    ReplyDelete
  10. While compiling the source code with MikroC, what are your configuration bit settings? Click on the Edit Project and see the details on the configuration bit window, and tell me what they are. Did you connect the circuit diagram correctly?
    RB4-RB7 should go to D4-D7, and RA0 and RA1 should be connected to RS and E pins of the LCD. Don't forget to ground the R/W pin of the LCD.

    ReplyDelete
  11. My mcu is pic16F628A-i/p-20Mhz, could work with 4Mhz osc?

    ReplyDelete
  12. Yes, it will work with 4 MHz too. 20 MHz is the maximum clock speed it can operate.

    ReplyDelete
  13. hello..sorry to bother but i have questions for u based on this link>>http://learnpicmicrocontrollers.blogspot.com/2010/09/gas-sensor-using-pic16f84a.html?showComment=1308144300271#c63258762780533144<<,i have questions for u..i'm confius about this project,how to program the lcd?what code do we need to use?i want to do this project very badly..i hope u can help me and please reply this A.S.A.P to my email otaku_9177@yahoo.com

    ReplyDelete
  14. You better find your answer here

    http://www.electronics-lab.com/projects/test/014/index.html

    ReplyDelete
  15. The lcd doesnt display the words unlike what i expected.
    What could have caused this problem?
    Can i ask for the hex value for the configuration bit
    (ex. 3D18)for mplab?

    THx in advance!

    ReplyDelete
  16. Hi Mr Raj, I had constructed the circuit same as yours in proteus,it runs well. But comes to hardware, big problem occurs. I use PICKIT2 to program the hex file into PIC16F628A and construct it, it gives me 1 line of black square. I use the resonator of 4Mhz and 2 x 22pf capacitors. My LCD is qy1602a .
    What could it be the problem?

    ReplyDelete
  17. This comment has been removed by the author.

    ReplyDelete
  18. sir, may i have your hex file? i constructed exactly the same circuit and same coding using mikroc pro. my lcd just give up a line of black square.

    ReplyDelete
  19. You haven't connected LCD_RW pin to PIC???
    Why..???

    ReplyDelete

Post a Comment

Popular posts from this blog

Contact less tachometer using PIC16F628A

Introduction
Tachometer is a device that gives you the information about the rotational speed of any shaft or disc. It usually measures the speed in revolutions per minute (RPM). Today we are going to make a simple tachometer that could measure the rotation speed of a disk without making any physical contact (that's why it is contact less) with the rotating object. The range of this tachometer is 0 - 9999 RPM and displays the RPM on a multiplexed 4-digit seven-segment display. Of course, we are going to do this project on our usual PIC16F628A development board.

Infrared sensor
Contact-less measurement of RPM will be achieved through an IR sensor. An IR diode will send a beam of infrared towards the rotating disc, and any reflected pulse will be received by a photo diode. The resistance of a photo diode drops drastically when exposed to infrared. An infrared is reflected by a white surface and absorbed by the dark ones. The test disc for this project is shown below. You can see the …

Experiment No. 2 : Push Button and Seven Segment Display Interface

In this experiment, we will program the PIC16F628A as an UP/DOWN Decade Counter. The count value will be displayed on a Seven-Segment Display and will be incremented/decremented by two push buttons on the board.

Experimental Setup:
The board has built in interface for a multiplexed 4-digit seven segment display (HS-5461AS2 from www.futurlec.com).We will select only one digit by connecting a Digit Select pin to Vcc, as shown in figure below. A black jumper wire is used for this purpose. The seven segments will be driven through PORTB (already wired on the board). Connect Push Buttons (PB3 and PB4) to RA1 and RA0 female headers using jumper wires.


PIC16F628A Development Board

The development board we are going to make for our experimental microcontroller PIC16F628A will look like this. Here are the features it is going to have:
Access to all I/O pins through female header pins4 Push Buttons for Input4 LEDs for OutputAn LCD Interface PortA 4-digit Seven-Segment Display InterfaceLCD Backlight Switch and Contrast AdjustmentICSP Programming (Very Important)