Push Buttons with a 16*2 LCD

Thread Starter

rkcliu

Joined May 27, 2011
4
Hi All about circuits community,

I'm new to this forum and just a question that is completely burning me up.

I'm programming a 16F690 in hitech C and MPLAB and I'm writing to an LCD screen.
The thing is that when I activate the -3State on "Release from Reset" - setting in MPLAB, my LCD goes back to the original screen (ie. black 5*8 dots on the top line).

My push buttons do seem to work as the corresponding LED's on my dev board light up.

However, when I program the PIC with the -3State on "Release from Reset" - setting, my LCD does show results, but I am unable to move through the different options using my push buttons.

Please help. Thanks
 
Last edited:

Thread Starter

rkcliu

Joined May 27, 2011
4
Hi, Its quite a bit. And also, I'm using an external weak pull up resistor for RA2

Rich (BB code):
MAIN:
__________________________________________


 #include <htc.h>
 #include "lcd.h"
 
__CONFIG(FOSC_INTRCCLK  & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF);

unsigned char receive = 0;
unsigned char counter = 1;

void init(void)        //Initialise all the appropriate pins
{

 /*
    //PORTA as interrupt on change (button press)
    IOCA0 = 1;            //If I set every IOCA pin individually,
    IOCA1 = 1;            //then there isnt any debouncing...
    IOCA2 = 1;            //WEIRD!! Maybe its the IOCA pin 6 and 7?
    IOCA3 = 1;
    IOCA4 = 1;
*/
    //EUSART
    BRGH = 0;
    BRG16 = 0;
    SPBRG = 0x33;        //Decimal --> 51. To set Baud Rate to 1200.
    TXEN = 1;            //I made this TXEN, check if it works
    SYNC = 0;
    SPEN = 1;
    RCIE = 1;    
 
/*
    BRGH = 0;
    BRG16 = 0;
    SPBRG = 0x33;
    RCSTA = 0b10000000;
    TXSTA = 0b00100000;
    PIE1 = 0b00100000;
*/
    //Setting to Digital and setting inputs/outputs
    ANSEL = 0x00;        //Digital Ports
    ANSELH = 0x00;
    TRISA = 0xFF;        //Setting inputs and outputs
    TRISB = 0x00;
    TRISC = 0x00;
    IOCA = 0xFF;
    CM1CON0 = 0;
    CM2CON0 = 0; 

    //INTCON
    GIE = 1;             //Global interrupt enable
    PEIE = 1;            //Peripheral interrupts
    RABIE = 1;             //Enable PortA/B IOC

    //counter =1;
}


void increment(void)
{    
/*
    counter++;
    display_value(counter);
    RABIF = 0;

    _delay(100000);
*/

    if (counter == 0b00000111)
    {
        counter = 1;
    }
    else 
    {
        counter++;
    }
    display_value(counter);
    RABIF = 0;

    _delay(100000);

}

void decrement(void)
{
/*
    counter--;
    display_value(counter);
    RABIF = 0; 

    _delay(100000);
*/
    if (counter == 0b00000001)
    {
        counter = 7;
    }
    else 
    {
        counter--;
    }
    display_value(counter);
    RABIF = 0;

    _delay(100000);

}

void confirm(void)
{
    TXREG = counter;
    TXIE = 1;
}

void receive_data(void)
{    
    receive = RCSTA;
    //PORTC = receive;
}


void main(void)
{
    init();
    lcd_init();
    lcd_goto(0);
    lcd_puts("1/11 Voltage");
    lcd_goto(0x40);
    lcd_puts("Confirm?");
    
    while (1)
    {
    }
    
}


void interrupt isr(void) 
{
if((RABIF) && (RA2==1))
    {
        decrement();
    }
if((RABIF) && (RA3==1))
    {
        increment();
    }

if(RABIF && RA0)
    {
        confirm();
    }
if (RCIF)
    {
        receive_data();
    }
}
_____________________________________________________

LCD.h

/* 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);

 extern void display_value(unsigned char c);
     
 /* 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)

___________________________________________

LCD.C

#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 RB6
 //#define    LCD_RW RB5
 #define     LCD_EN RB4
 
 #define     LCD_DATA    PORTC
 
 #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);
 }

void display_value(unsigned char c)
{
    switch (c)
    {
    case 1:
        lcd_goto(0);
        lcd_puts("1/11 RMS Voltage");
        lcd_goto(0x40);
        lcd_puts("Confirm?        ");
        break;
    
    case 2:
        lcd_goto(0);
        lcd_puts("2/11 RMS Current");
        lcd_goto(0x40);
        lcd_puts("Confirm?");
        break;
    
    case 3:
        lcd_goto(0);
        lcd_puts("3/11 P. Factor  ");
        lcd_goto(0x40);
        lcd_puts("Confirm?");
        break;

    case 4:
        lcd_goto(0);
        lcd_puts("4/11 P. Real    ");
        lcd_goto(0x40);
        lcd_puts("Confirm?");
        break;

    case 5:
        lcd_goto(0);
        lcd_puts("5/11 P. Reactive");
        lcd_goto(0x40);
        lcd_puts("Confirm?");
        break;

    case 6:
        lcd_goto(0);
        lcd_puts("6/11 E. Real    ");
        lcd_goto(0x40);
        lcd_puts("Confirm?");
        break;

    case 7:
        lcd_goto(0);
        lcd_puts("7/11 Inst. Power");
        lcd_goto(0x40);
        lcd_puts("Confirm?");
        break;
    }
}

     
 /* 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(50);                        // 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(0x0F);                         // Display On, Cursor On, Cursor Blink
     lcd_clear();                                // Clear screen
     lcd_write(0x06);                         // Set entry Mode
 }
 
Last edited by a moderator:

ErnieM

Joined Apr 24, 2011
8,377
Hi rkcliu!

Just about everyone stumbles trying to get an LCD working.

First off, see that # sign on the advances post window? It's for posting code and makes it more readable. Please use it in the future. :D

Next, can you also post a schematic?

Finally, see if your LCD can do something simple: Don't read buttons and fuss and such to make something to display. Just set up the LCD and try to write "HELLO WORLD" to it. When you get that to work then go on to the rest.
 

Thread Starter

rkcliu

Joined May 27, 2011
4
Hi

Thanks ErnieM, that Hash technique was noted...

I managed to find the problem, it was a hardware problem...

My power rail just needed some caps due to the high frequency switches from the buttons and the micro. I also put in another external weak pull up resistor on RA3, even though it is stated that there is an internal one..

Now I have another problem, I'm struggling to pass a variable into the LCD, I can print any strings that I want using my lcd_puts function, but I'm actually receiving values from another friend. Thing is I read in forums that people tend to pass it serially, however, I'm not able to as my serial port is already used for sending the command to another micro.

Also, I need to do an itoa conversion but i get the warning

"illegal conversion of integer to pointer"
 

ErnieM

Joined Apr 24, 2011
8,377
Glad you got it to work.

Now I have another problem, I'm struggling to pass a variable into the LCD, I can print any strings that I want using my lcd_puts function, but I'm actually receiving values from another friend. Thing is I read in forums that people tend to pass it serially, however, I'm not able to as my serial port is already used for sending the command to another micro.
Huh? I don't understand.

Also, I need to do an itoa conversion but i get the warning

"illegal conversion of integer to pointer"
Post the offending code (just the call and all parameter definitions should do).
 

Thread Starter

rkcliu

Joined May 27, 2011
4
Sorry for the late reply ErnieM

Been so swamped by this project but I did finally get it complete :D

The itoa function built into Hitech C, I was unable to implement it :(
However, I did manage to implement another technique of displaying my integer/float values, by digging out each number... and then displaying the characters on the LCD whilst moving the cursor. Its a crude technique but it works :)

Thanks for the replies,
rkcliu
 

ErnieM

Joined Apr 24, 2011
8,377
The itoa function built into Hitech C, I was unable to implement it :(
Is it truly built in or is it a library function?

To use stuff from libraries you typically have to include the correct dot-h file as you did at the top of your code. I don't use that compiler (I have it), and it looks like that function is in the stdlib library, so add:

Rich (BB code):
#include <stdlib.h>
 
Top