struct holding LCD menu items -> errors?

Discussion in 'Embedded Systems and Microcontrollers' started by geotech1, May 18, 2013.

  1. geotech1

    Thread Starter New Member

    May 18, 2013
    4
    0
    Hi everyone, my name is James, this is my first post on this forum. I am here because i have been driven nuts
    trying to find why my pic project has stopped working! I am trying to implement a simple menu on an LCD, 3 push buttons, PIC16F1507, Hi-Tech C, MPLAB v8.84. I have declared an array of structs, each element holds a struct that contains a text string and an int, each time a menu button is pressed it displays the text string and int value of the next element in the array, looping back to the begining of the array when it reaches the end. There is also a plus and minus buttons that allow the int value in the selected struct to be incremented or decremented.
    This worked fine for a while, but after i changed some other unrelated code, it has ceased to display the contents of the struct. I cannot for the life of me figure out why. I have wondered if there may be an issue with the struct spanning across memory page boundries? BTW I have RTFM and STFW, but it seems on this occasion Google is not my friend :(
    Here's the key parts of my code, if anyone can spot the problem, i will be so very grateful.

    MAIN.C

    Code ( (Unknown Language)):
    1. //****************************Global Variables**********************//
    2. struct aMenu {
    3.   unsigned char label[11];
    4.   unsigned int val;
    5. }menu[3] = {{"Speed    \0", 25}, {"Threshold\0", 5}, {"unused   \0", 20}};
    6.  
    7. void main()
    8. {
    9.  
    10. /*********************** Button Event Handlers ********************/
    11. if(ButtonEvent && B1_flag) //////////////////////// Down Handler
    12. {
    13.  menu[MenuIndex].val--;
    14.  lcd_goto(LINE2+12);
    15.  LCDWriteInt(menu[MenuIndex].val, 3);
    16.  ButtonEvent = FALSE;
    17. }
    18. if(ButtonEvent && B2_flag) /////////////////////// Up Handler
    19. {
    20.  menu[MenuIndex].val++;
    21.  lcd_goto(LINE2+12);
    22.  LCDWriteInt(menu[MenuIndex].val, 3);
    23.  ButtonEvent = FALSE;
    24. }
    25. if(ButtonEvent && B3_flag) /////////////////////// Menu Handler
    26. {
    27.  MenuIndex++;
    28.  if(MenuIndex > 2) MenuIndex = 0;
    29.  lcd_clear();
    30.  lcd_goto(LINE1);
    31.  lcd_puts("Adjustment Menu");
    32.  lcd_goto(LINE2);
    33.  lcd_puts(menu[MenuIndex].label);
    34.  lcd_goto(LINE2+12);
    35.  LCDWriteInt(menu[MenuIndex].val, 3);
    36.  ButtonEvent = FALSE;
    37. }
    38. }// end main
    LCD.C

    Code ( (Unknown Language)):
    1. /* write a byte to the LCD in 4 bit mode */
    2. void
    3. lcd_write(unsigned char c)
    4. {
    5.  if(c & 0x80) LCD_D7=1; else LCD_D7=0;
    6.  if(c & 0x40) LCD_D6=1; else LCD_D6=0;
    7.  if(c & 0x20) LCD_D5=1; else LCD_D5=0;
    8.  if(c & 0x10) LCD_D4=1; else LCD_D4=0;
    9.  LCD_STROBE;
    10.  if(c & 0x08) LCD_D7=1; else LCD_D7=0;
    11.  if(c & 0x04) LCD_D6=1; else LCD_D6=0;
    12.  if(c & 0x02) LCD_D5=1; else LCD_D5=0;
    13.  if(c & 0x01) LCD_D4=1; else LCD_D4=0;
    14.  LCD_STROBE;
    15.  __delay_us(40);
    16. }
    17. /* Clear and home the LCD */
    18. void
    19. lcd_clear(void)
    20. {
    21.  LCD_RS = 0;
    22.  lcd_write(0x1);
    23.  __delay_ms(2);
    24. }
    25. /* write a string of chars to the LCD */
    26. void
    27. lcd_puts(const char * s)
    28. {
    29.  LCD_RS = 1; // write characters
    30.  while(*s) lcd_write(*s++);
    31. }
    32. /* write one character to the LCD */
    33. void
    34. lcd_putch(unsigned char c)
    35. {
    36.  LCD_RS = 1; // write characters
    37.  lcd_write(c);
    38. }
    39.  
    40. /* Go to the specified position*/
    41. void
    42. lcd_goto(unsigned char pos)
    43. {
    44.  LCD_RS = 0;
    45.  lcd_write(pos);
    46. }
    47.  
    48. /* initialise the LCD - put into 4 bit mode */
    49. void
    50. lcd_init(void)
    51. {
    52.  LCD_RS = 0; // write control bytes
    53.  __delay_ms(15);// power on delay
    54.  LCD_D4 = 1; // init!
    55.  LCD_D5 = 1; //
    56.  LCD_STROBE;
    57.  __delay_ms(5);
    58.  LCD_STROBE; // init!
    59.  __delay_us(100);
    60.  LCD_STROBE; // init!
    61.  __delay_ms(5);
    62.  
    63.  LCD_D4 = 0; // set 4 bit mode
    64.  LCD_STROBE;
    65.  __delay_us(40);
    66.  
    67.  lcd_write(0x28);// 4 bit mode, 1/16 duty, 5x8 font, 2lines
    68.  lcd_write(0x0C);// display on
    69.  lcd_write(0x06);// entry mode advance cursor
    70.  lcd_write(0x01);// clear display and reset cursor
    71. }
    72. void LCDWriteInt(int val,unsigned int field_length)
    73. {
    74.  /***************************************************************
    75.  This function writes a integer type value to LCD module
    76.  Arguments:
    77.  1)int val : Value to print
    78.  2)unsigned int field_length :total length of field in which the value is printed
    79.  must be between 1-5 if it is -1 the field length is no of digits in the val
    80.  ****************************************************************/
    81. LCD_RS = 1; // write characters
    82.  char str[5]={0,0,0,0,0};
    83.  int i=4,j=0;
    84.  while(val)
    85.  {
    86.  str[i]=val%10;
    87.  val=val/10;
    88.  i--;
    89.  }
    90.  if(field_length==-1)
    91.   while(str[j]==0) j++;
    92.  else
    93.   j=5-field_length;
    94.  if(val<0) lcd_write('-');
    95.  for(i=j;i<5;i++)
    96.  {
    97.  lcd_write(48+str[i]);
    98.  }
    99. }
    100. [/i][/i]


    Kind Regards, J.
     
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Oh dear, that sounds serious!

    Does it display anything at all?

    Hi James! Welcome to the forums!
     
    Last edited: May 18, 2013
  3. Brownout

    Well-Known Member

    Jan 10, 2012
    2,375
    998
    My guess is none of the code is being executed. I don't see where BX_flag is being set (X= 1, 2, 3). So, I'm going to assume for now that's the problem, as I don't really see anything else.

    I'm also assuming that you're testining your hardware with working code to insure it is OK.
     
  4. geotech1

    Thread Starter New Member

    May 18, 2013
    4
    0
    Hi guys, Thanks for taking a look at my post. I have omitted some portions of the code that i know for sure are working OK - i.e the button debounce section that sets the Bx flag, and the ADC stuff for example. The menuIndex int rolls round 0,1,2 and back to zero as it should, the display shows on line1 "Adjustment Menu", everything else works as it should, just none of the contents of the struct are displayed. They used to be! Sometimes a char or two of junk is displayed.

    I noticed the problem earlier in development and thought i'd fixed it. Originally the struct was declared globally after a small number of other variables and all was well until i added some more code and more variables. Then the LCD output of the structure contents started to play up, so i moved the struct declaration to be first declaration in the list. After the struct was declared as the first item in the variable declarations it worked again. Now i've added more code and variables, it's failed again. Declaring it after a bunch of other stuff (ints, chars & bits) made the ouput to the LCD fail. This is why i am wondering if its a memory issue???

    Has anyone got a suggestion for how to go about investigating what this problem is??? I am stumped :confused:

    Many Thanks, J.
     
  5. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    ICSP is shorthand for In Circuit Serial Programming and debugging!

    How well does HTC play inside MPLAB? These things can be simple to track down when I used C18 inside MPLAB and a PICkit 2 or 3 to single step code inside the target from the IDE and see what is going on (and going wrong).

    Occasionally I have to make a buffer or pointer a global so it is still readable in the watch window but that's minor.
     
  6. Brownout

    Well-Known Member

    Jan 10, 2012
    2,375
    998
    What is the value of "LINE2?" If you've messed that up, it would cause what you're seeing.
     
  7. geotech1

    Thread Starter New Member

    May 18, 2013
    4
    0
    Haven't modified anything in LCD.C for a long time. When checking that the menuIndex int was behaving correctly I output it on line 2, it displayed fine.
     
  8. Brownout

    Well-Known Member

    Jan 10, 2012
    2,375
    998
    Still, you should know the value.
     
  9. Brownout

    Well-Known Member

    Jan 10, 2012
    2,375
    998
    I just ran the following code on my PIC18F45K20, compiled with c18. It uses your struct and displays it just fine. I displayed the struct on line 1 of the LCD.

    Code ( (Unknown Language)):
    1.  
    2. //****************************Global Variables**********************//
    3. struct aMenu
    4. { unsigned char label[11];
    5. unsigned int val; }menu[3] = {{"Speed \0", 25}, {"Threshold\0", 5}, {"unused \0", 20}};
    6.  
    7.  
    8. void main(void){
    9.   char istringconvert[16];
    10.   int menu_indx = 1;
    11.  
    12.   //initialize the LCD
    13.   LCD_init();
    14.  
    15.   WriteStringXldc(menu[menu_indx].label);
    16.   itoa(menu[menu_indx].val, istringconvert, 10);
    17.   WriteStringXldc(istringconvert);
    18.   while(1);
    19.   }
    20.  
     
    Last edited: May 18, 2013
  10. geotech1

    Thread Starter New Member

    May 18, 2013
    4
    0
    Thank you for taking the time to test that. This is a very strange problem! Last night I replaced the structure with a const char * array[] to hold the strings, and an unsigned int[] to hold the values. Worked fine! Would still like to use the structure as it makes the code so much simpler.
     
  11. Brownout

    Well-Known Member

    Jan 10, 2012
    2,375
    998
    I had weird problems like this because in my program, I had #include <xlcd.h> and also had my custom #include "LCD.h" file too. When I got rid of the <xlcd.h> in all my code, wierd problems like this cleared up.
     
Loading...