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.