Task: To learn how to control LCD display
Tools: PIC16f628a, LCD 2×16, proteus
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
Pingback: Pic Lab, PIC16, Experiment #6.2, LCD display | diymicro.org