pic16f690 - LCD works in proteus but not on breadboard

Thread Starter

ushir1

Joined Nov 20, 2022
2
Hello everyone. Im have some trouble getting an LCD to work with a 4*4 keypad and pic16f690. The code works in proteus, but when i test on the breadboard, will all the same connections, it does not display anything. What could be the problem?

I have attached the code and circuit design below.

Thank you in advance
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,709
Welcome to AAC!

Proteus does not always do a good job of finding faults using hardware peripherals including LCD with a 44780 type controller.

Init_LCD:
Init_LCD
         Print1 0x38
         call S_delay
         Print1 0x0C
         call S_delay
         Print1 0x01
         call S_delay
         Print1 0x80
         call S_delay
         Return
Reading the 44780 datasheet:
Write 38h
delay
Write 0Ch
delay
Write 30h
delay
Write 30h (again) to set 8 bit interface
delay
Then write the display configuration as desired

See figure 23 in the attached datasheet LCD Controller 44780.pdf. The other files have some nice information that is more approachable.

Also, be sure that the contrast control is hooked up correctly. With power on, rotating the contrast pot should cause the display to go from clear to dark boxes even without the processor running.
Don't forget the power-up delay of 15ms +.

Good luck!
 

Attachments

John P

Joined Oct 14, 2008
1,992
The PIC16F690 is outdated. A modern replacement like the PIC16F18345 would have more features, run faster and cost less. But maybe you have a box of PIC16F690's and don't want to buy anything new!
 

Picbuster

Joined Dec 2, 2013
1,040
Hello everyone. Im have some trouble getting an LCD to work with a 4*4 keypad and pic16f690. The code works in proteus, but when i test on the breadboard, will all the same connections, it does not display anything. What could be the problem?

I have attached the code and circuit design below.

Thank you in advance
Hi,
This Display driver works with pic16Fxxx pic 18fxxx
and yes you have to adjust a few things.

Picbuster
C:
 #define _XTAL_FREQ 20000000   // set to your speed



#include <stdio.h>
#include    <htc.h>
#include    "lcd.h"


//========== Proto types ======================
extern void lcd_puts(const char * s);
extern void lcd_clear(void);



//------------------------------------------------------------------------------

void Lcd_On(void)
         {
              // if (LCD_needed)
         
                 Lcd_Pwr=1;
                __delay_ms(5);
                lcd_init();
                __delay_ms(20);
                 lcd_clear();
                
                 return;
           }

/*


void LCD_STROBE()
{
   if (W_Display)
    {
        LCD_EN=0;
        __delay_us(20);
        LCD_EN=1;
    }
    else 
        LCD_EN1=0;
        __delay_us(20);
        LCD_EN1=1; 
 }
*/


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

/*
 *     Clear and home the LCD
 */

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

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

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

/* write one character to the LCD */

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


/*
 * Go to the specified position
 */

void lcd_Cmd(char c)
{
    LCD_RS = 0;    // write characters
    lcd_write( c );
    return;
}





void lcd_goto(unsigned char pos)
{
    LCD_RS = 0;
    lcd_write(0x80+pos);
    return;
}
    
/* initialise the LCD - put into 4 bit mode */
void lcd_init()
{
    char init_value;
    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(0xC); // Display On, Cursor On, Cursor Blink was 0xE
    lcd_clear();    // Clear screen
        lcd_write(0x6); // Set entry Mode

   //============================  display.h file ===================
/*
 *    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 */


    
/* intialize the LCD - call before anything else */

extern void lcd_init(void);

extern void lcd_putch(char);



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

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

// use your ports
#define    LCD_RS          PORTEbits.RE0
#define    LCD_RW          PORTEbits.RE1
#define LCD_EN             PORTEbits.RE2
#define Display_Bl        PORTEbits.RE3
#define LCD_DATA        PORTH      // use your output port

//#define    lcd_cursor(x)    lcd_write(((x)&0x7F)|0x80)

//================================================
//N number of chars per line example 20 chars per line and 4 lines
char Dbuf[N];
#define DR1 0
#define DR2 64
#define DR3 20
#define DR4 84
//=========================================
//==================== main =================
               lcd_clear();
                lcd_goto(DR1);
                lcd_puts("                    "); // clear one line or clear all lines use   lcd_clear();
                lcd_goto(DR1);
                lcd_puts("                    ");
                lcd_goto(DR1);          //
                lcd_puts("Gynotec      ");
                lcd_goto(DR1+15);
                lcd_puts(Identify.Version);    
                lcd_goto(DR1);          //
                lcd_puts("Your text    ");
                lcd_goto(DR1+15);
                lcd_puts(Your_string);       // your string <= N chars[\code]
Mod edit: code tags - JohnInTX
 
Last edited by a moderator:
What are the specs of the LCD? Besides the HD44780 controller there is also the ST7066. The initialization is slightly different, but after that they work the same.

Also in your code you need to send 0x30 as the first command tat least wo times before 0x38 as a sort of software reset. The timing of these first few steps and the number of times to repeat 0x30 is where the major differences in the two controllers are.

Are you at least getting solid blocks on power up? If not the contrast needs adjusted as MrChips pointed out. If it is a two line display the top row should be solid blocks, and the bottom row will be clear. If four row the top and third rows are usually solid block.
 
Top