Hi all, I recompiled after fixing a few bugs elsewhere in the program - they had to do with confusing similarly spelled variables that had different data types. The current discussion on coding styles was timely; I prefixed all my variables with their data type and resolved the problem in short order. Friendly regards, Patrick Murphy James Valley Colony Patrick Murphy wrote: > > Hi All, > I'm trying to set up a menu on my serial 4x20 LCD (from NetMedia) > and am wondering why my key press delay_ms(500) code isn't effective; > in other words, after a button is pressed, I'm expecting the delay to > take effect, but it doesn't; the program can loop hundreds of times > instead of only once during that button press. I added some counters > in-line to see this. I realize I am not otherwise debouncing the > buttons; I'm simply looking at the port and acting on the state of > the port; all PortD pins have external 10k pull-up resistors, so I'm > assuming any activity on PortD is initiated by button presses. > > Here is what the menu looks like: > > MAIN MENU > ->Run Automatically > Run Manually > Setup > > The bottom three lines of the LCD are menu items, and I'm reading > three buttons on PortD, called Next, Previous and Select in a > while loop. For example, when the Next button is pressed, the display > is supposed to be updated - the select arrow moved to the next menu > item or wrapped up to the first menu item. Monitoring the value of > NextCtr in a watch window, I see that if I press the Next button 5 > times in about 2 seconds, and then stop the ICD, the NextCtr reads > well over 1000; and the menu may or may not have been updated > correctly. > > Below is the code fragment. I'm working in PICC, (PCM compiler 3.092) > for the PIC16F877 using the MicroChip ICD. > > I am curious to know why the program can appear to bypass the delay > routine and welcome any suggestions to improve my menu code or design. > I think I am overlooking something basic, but I'm not sure what. > > Thanks in advance! > > Patrick Murphy > James Valley Colony > > long NextCtr, PrevCtr; > NextCtr = 0; // Count the number of times this portion of code is active. > PrevCtr = 0; // Also count in the Previous Button code. > > pspmode = 0; // Set up PortD > PORTD = 0xFF; // Make PORTD inputs > TRISD = 0xFF; > ArrowLine = 1; // Current LCD line counter > > // Loop while waiting for user input: Next, Previous, or Select buttons. > while(MenuState == MainMenu0) //Monitor lower 5 PortD inputs > { > PDButtons = PORTD; > PDButtons = ~PDButtons; // Invert so button pressed is now high > switch (PDButtons) > { > case 0x01: // Select Button Pressed: PortD0. Selected new menu. > porta1 = 1; // Porta1 LED for debugging. No delay necessary. > if (ArrowLine == 1) > MenuState = Automatic1; > else if (ArrowLine == 2) > MenuState = Manual2; > else if (ArrowLine == 3) > MenuState = Setup3; > break; > case 0x02: // Next Button Pressed: PortD1. Move arrow down or wrap. > porta2 = 1; // Porta2 LED for debugging. > NextCtr++; > if (ArrowLine < 3) > { > ArrowLine++; > } > else > { > ArrowLine = 1; > } > printf(ser_char, " "); > ser_lcd_cursor_pos(0, ArrowLine); // col, line > printf(ser_char, "->"); > ser_lcd_cursor_pos(0, ArrowLine); // col, line > delay_ms(500); > break; > case 0x04: // Previous Button Pressed: PortD2. Move arrow up or wrap. > porta3 = 1; > PrevCtr++; > if (ArrowLine > 1) > { > ArrowLine--; > } > else > { > ArrowLine = 3; > } > printf(ser_char, " "); > ser_lcd_cursor_pos(0, ArrowLine); // col, line > printf(ser_char, "->"); > ser_lcd_cursor_pos(0, ArrowLine); // col, line > delay_ms(500); > break; > case 0x08: // Up Button Pressed: PortD3. Not used in this menu. > porta5 = 1; > delay_ms(100); > break; > case 0x10: // Down Button Pressed: PortD4. Not used in this menu. > portb0 = 1; > delay_ms(100); > }// switch > porta1 = 0; Turn off debugging LED's > porta2 = 0; > porta3 = 0; > porta5 = 0; > portb0 = 0; > } // while(MenuState == MainMenu0) > > void delay_10us(byte t) > // provides delay of t * 10 usecs (4.0 MHz clock) > { > #asm > BCF STATUS, RP0 > DELAY_10US_1: > CLRWDT > NOP > NOP > NOP > NOP > NOP > NOP > DECFSZ t, F > GOTO DELAY_10US_1 > #endasm > } > > void delay_ms(long t) // delays t millisecs (4.0 MHz clock) > { > do > { > delay_10us(100); > } while(--t); > } > > -- > http://www.piclist.com hint: The PICList is archived three different > ways. See http://www.piclist.com/#archives for details. -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.