Pic Lab, PIC16, Experiment #6, LCD display

Task: To learn how to control LCD display

Tools: PIC16f628a, LCD 2×16, proteus

an old website page has been used there

Let me try to make the display work in the proteus

Let’s make a simple schematic in proteus:

The next thing we need to do is to write functions to control the display, I made an easy way and just went to the samples directory of my compiler and took all the files I need, but modified a bit for work with my pins

A lcd.c file:

/*
 *    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    <htc.h>
#include    "lcd.h"
 
#define    LCD_RS RA1
#define    LCD_RW RA2
#define LCD_EN RA3
 
#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;
 
 CMCON  = 0x07;    // Disable analog pins on PORTA
 
 init_value = 0x3;
 TRISA=0;
 TRISB=0;
 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
}

ldc.h

/*
 *    LCD interface header file
 *    See lcd.c for more info
 */
 
/* write a byte to the LCD in 4 bit mode */
 
extern void lcd_write(unsigned char);
 
/* Clear and home the LCD */
 
extern void lcd_clear(void);
 
/* write a string of characters to the LCD */
 
extern void lcd_puts(const char * s);
 
/* Go to the specified position */
 
extern void lcd_goto(unsigned char pos);
 
/* intialize the LCD - call before anything else */
 
extern void lcd_init(void);
 
extern void lcd_putch(char);
 
/*    Set the cursor position */
 
#define    lcd_cursor(x)    lcd_write(((x)&0x7F)|0x80)

aaand the test program is here:

#include <htc.h>
#include "lcd.h"
#define _XTAL_FREQ 4000000
 
__CONFIG(WDTDIS & UNPROTECT & MCLREN & LVPDIS & HS);
 
void main() {
lcd_init();
 lcd_goto(0);    // select first line
 lcd_puts("PIC manual");
 lcd_goto(0x40);    // Select second line
 lcd_puts("SARGE.PP.UA");
 
 for(;;);
 
}

The sources here

1 thought on “Pic Lab, PIC16, Experiment #6, LCD display

  1. Pingback: Pic Lab, PIC16, Experiment #6.2, LCD display | diymicro.org

Leave a Reply

Your email address will not be published.