Push Buttons with a 16*2 LCD

Discussion in 'Embedded Systems and Microcontrollers' started by rkcliu, May 27, 2011.

  1. rkcliu

    Thread Starter New Member

    May 27, 2011
    4
    0
    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: May 27, 2011
  2. debjit625

    Well-Known Member

    Apr 17, 2010
    790
    186
    Please post your code so that we can help you.

    Welcome to AAC.
     
  3. rkcliu

    Thread Starter New Member

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

    Code ( (Unknown Language)):
    1.  
    2. MAIN:
    3. __________________________________________
    4.  
    5.  
    6.  #include <htc.h>
    7.  #include "lcd.h"
    8.  
    9. __CONFIG(FOSC_INTRCCLK  & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF);
    10.  
    11. unsigned char receive = 0;
    12. unsigned char counter = 1;
    13.  
    14. void init(void)        //Initialise all the appropriate pins
    15. {
    16.  
    17.  /*
    18.     //PORTA as interrupt on change (button press)
    19.     IOCA0 = 1;            //If I set every IOCA pin individually,
    20.     IOCA1 = 1;            //then there isnt any debouncing...
    21.     IOCA2 = 1;            //WEIRD!! Maybe its the IOCA pin 6 and 7?
    22.     IOCA3 = 1;
    23.     IOCA4 = 1;
    24. */
    25.     //EUSART
    26.     BRGH = 0;
    27.     BRG16 = 0;
    28.     SPBRG = 0x33;        //Decimal --> 51. To set Baud Rate to 1200.
    29.     TXEN = 1;            //I made this TXEN, check if it works
    30.     SYNC = 0;
    31.     SPEN = 1;
    32.     RCIE = 1;    
    33.  
    34. /*
    35.     BRGH = 0;
    36.     BRG16 = 0;
    37.     SPBRG = 0x33;
    38.     RCSTA = 0b10000000;
    39.     TXSTA = 0b00100000;
    40.     PIE1 = 0b00100000;
    41. */
    42.     //Setting to Digital and setting inputs/outputs
    43.     ANSEL = 0x00;        //Digital Ports
    44.     ANSELH = 0x00;
    45.     TRISA = 0xFF;        //Setting inputs and outputs
    46.     TRISB = 0x00;
    47.     TRISC = 0x00;
    48.     IOCA = 0xFF;
    49.     CM1CON0 = 0;
    50.     CM2CON0 = 0;
    51.  
    52.     //INTCON
    53.     GIE = 1;             //Global interrupt enable
    54.     PEIE = 1;            //Peripheral interrupts
    55.     RABIE = 1;             //Enable PortA/B IOC
    56.  
    57.     //counter =1;
    58. }
    59.  
    60.  
    61. void increment(void)
    62. {    
    63. /*
    64.     counter++;
    65.     display_value(counter);
    66.     RABIF = 0;
    67.  
    68.     _delay(100000);
    69. */
    70.  
    71.     if (counter == 0b00000111)
    72.     {
    73.         counter = 1;
    74.     }
    75.     else
    76.     {
    77.         counter++;
    78.     }
    79.     display_value(counter);
    80.     RABIF = 0;
    81.  
    82.     _delay(100000);
    83.  
    84. }
    85.  
    86. void decrement(void)
    87. {
    88. /*
    89.     counter--;
    90.     display_value(counter);
    91.     RABIF = 0;
    92.  
    93.     _delay(100000);
    94. */
    95.     if (counter == 0b00000001)
    96.     {
    97.         counter = 7;
    98.     }
    99.     else
    100.     {
    101.         counter--;
    102.     }
    103.     display_value(counter);
    104.     RABIF = 0;
    105.  
    106.     _delay(100000);
    107.  
    108. }
    109.  
    110. void confirm(void)
    111. {
    112.     TXREG = counter;
    113.     TXIE = 1;
    114. }
    115.  
    116. void receive_data(void)
    117. {    
    118.     receive = RCSTA;
    119.     //PORTC = receive;
    120. }
    121.  
    122.  
    123. void main(void)
    124. {
    125.     init();
    126.     lcd_init();
    127.     lcd_goto(0);
    128.     lcd_puts("1/11 Voltage");
    129.     lcd_goto(0x40);
    130.     lcd_puts("Confirm?");
    131.    
    132.     while (1)
    133.     {
    134.     }
    135.    
    136. }
    137.  
    138.  
    139. void interrupt isr(void)
    140. {
    141. if((RABIF) && (RA2==1))
    142.     {
    143.         decrement();
    144.     }
    145. if((RABIF) && (RA3==1))
    146.     {
    147.         increment();
    148.     }
    149.  
    150. if(RABIF && RA0)
    151.     {
    152.         confirm();
    153.     }
    154. if (RCIF)
    155.     {
    156.         receive_data();
    157.     }
    158. }
    159. _____________________________________________________
    160.  
    161. LCD.h
    162.  
    163. /* write a byte to the LCD in 4 bit mode */
    164.  
    165.  extern void lcd_write(unsigned char);
    166.  
    167.  /* Clear and home the LCD */
    168.  
    169.  extern void lcd_clear(void);
    170.  
    171.  /* write a string of characters to the LCD */
    172.  
    173.  extern void lcd_puts(const char * s);
    174.  
    175.  /* Go to the specified position */
    176.  
    177.  extern void lcd_goto(unsigned char pos);
    178.  
    179.  extern void display_value(unsigned char c);
    180.      
    181.  /* intialize the LCD - call before anything else */
    182.  
    183.  extern void lcd_init(void);
    184.  
    185.  
    186.  
    187.  extern void lcd_putch(char);
    188.  
    189.  /*    Set the cursor position */
    190.  
    191.  #define    lcd_cursor(x)    lcd_write(((x)&0x7F)|0x80)
    192.  
    193. ___________________________________________
    194.  
    195. LCD.C
    196.  
    197. #ifndef _XTAL_FREQ
    198.   // Unless specified elsewhere, 4MHz system frequency is assumed
    199.   #define _XTAL_FREQ 4000000
    200.  #endif
    201.  
    202.  
    203.  #include <htc.h>
    204.  #include "lcd.h"
    205.  
    206.  #define    LCD_RS RB6
    207.  //#define    LCD_RW RB5
    208.  #define     LCD_EN RB4
    209.  
    210.  #define     LCD_DATA    PORTC
    211.  
    212.  #define    LCD_STROBE()    ((LCD_EN = 1),(LCD_EN=0))
    213.  
    214.  /* write a byte to the LCD in 4 bit mode */
    215.  
    216.  void
    217.  lcd_write(unsigned char c)
    218.  {
    219.      __delay_us(40);
    220.      LCD_DATA = ( ( c >> 4 ) & 0x0F );
    221.      LCD_STROBE();
    222.      LCD_DATA = ( c & 0x0F );
    223.      LCD_STROBE();
    224.  }
    225.  
    226.  
    227.  /*
    228.   *     Clear and home the LCD
    229.   */
    230.  
    231.  void
    232.  lcd_clear(void)
    233.  {
    234.      LCD_RS = 0;
    235.      lcd_write(0x1);
    236.      __delay_ms(2);
    237.  }
    238.  
    239.  /* write a string of chars to the LCD */
    240.  
    241.  void
    242.  lcd_puts(const char * s)
    243.  {
    244.      LCD_RS = 1;    // write characters
    245.      while(*s)
    246.          lcd_write(*s++);
    247.  }
    248.  
    249.  /* write one character to the LCD */
    250.  
    251.  void
    252.  lcd_putch(char c)
    253.  {
    254.      LCD_RS = 1;    // write characters
    255.      lcd_write( c );
    256.  }
    257.  
    258.  
    259.  /*
    260.   * Go to the specified position
    261.   */
    262.  
    263.  void
    264.  lcd_goto(unsigned char pos)
    265.  {
    266.      LCD_RS = 0;
    267.      lcd_write(0x80+pos);
    268.  }
    269.  
    270. void display_value(unsigned char c)
    271. {
    272.     switch (c)
    273.     {
    274.     case 1:
    275.         lcd_goto(0);
    276.         lcd_puts("1/11 RMS Voltage");
    277.         lcd_goto(0x40);
    278.         lcd_puts("Confirm?        ");
    279.         break;
    280.    
    281.     case 2:
    282.         lcd_goto(0);
    283.         lcd_puts("2/11 RMS Current");
    284.         lcd_goto(0x40);
    285.         lcd_puts("Confirm?");
    286.         break;
    287.    
    288.     case 3:
    289.         lcd_goto(0);
    290.         lcd_puts("3/11 P. Factor  ");
    291.         lcd_goto(0x40);
    292.         lcd_puts("Confirm?");
    293.         break;
    294.  
    295.     case 4:
    296.         lcd_goto(0);
    297.         lcd_puts("4/11 P. Real    ");
    298.         lcd_goto(0x40);
    299.         lcd_puts("Confirm?");
    300.         break;
    301.  
    302.     case 5:
    303.         lcd_goto(0);
    304.         lcd_puts("5/11 P. Reactive");
    305.         lcd_goto(0x40);
    306.         lcd_puts("Confirm?");
    307.         break;
    308.  
    309.     case 6:
    310.         lcd_goto(0);
    311.         lcd_puts("6/11 E. Real    ");
    312.         lcd_goto(0x40);
    313.         lcd_puts("Confirm?");
    314.         break;
    315.  
    316.     case 7:
    317.         lcd_goto(0);
    318.         lcd_puts("7/11 Inst. Power");
    319.         lcd_goto(0x40);
    320.         lcd_puts("Confirm?");
    321.         break;
    322.     }
    323. }
    324.  
    325.      
    326.  /* initialise the LCD - put into 4 bit mode */
    327.  void lcd_init()
    328.  {
    329.      char init_value;    
    330.  
    331.      init_value = 0x3;    
    332.  
    333.      LCD_RS = 0;
    334.      LCD_EN = 0;
    335.      //LCD_RW = 0;
    336.      
    337.      __delay_ms(50);                        // wait 15mSec after power applied,
    338.      LCD_DATA     = init_value;
    339.      LCD_STROBE();
    340.      __delay_ms(5);
    341.      LCD_STROBE();
    342.      __delay_us(200);
    343.      LCD_STROBE();
    344.      __delay_us(200);
    345.      
    346.      LCD_DATA = 2;                            // Four bit mode
    347.      LCD_STROBE();
    348.  
    349.      lcd_write(0x28);                         // Set interface length
    350.      lcd_write(0x0F);                         // Display On, Cursor On, Cursor Blink
    351.      lcd_clear();                                // Clear screen
    352.      lcd_write(0x06);                         // Set entry Mode
    353.  }
    354.  
     
    Last edited by a moderator: May 28, 2011
  4. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    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.
     
  5. rkcliu

    Thread Starter New Member

    May 27, 2011
    4
    0
    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"
     
  6. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Glad you got it to work.

    Huh? I don't understand.

    Post the offending code (just the call and all parameter definitions should do).
     
  7. rkcliu

    Thread Starter New Member

    May 27, 2011
    4
    0
    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
     
  8. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    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:

    Code ( (Unknown Language)):
    1. #include <stdlib.h>
     
Loading...