Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

lcd menu

Status
Not open for further replies.
This code wont work:

Code:
  //--- main loop
  do {
    if(Button(&PORTA,2, 1, 0)) {
             MainMenu();
             }
    else {
            read_temp();
          }
    } while (1);

Change it to :
Code:
  //--- main loop
  do {
    if(KeyPORT == ENTER) {
             MainMenu();
             }
    else {
            read_temp();
          }
    } while (1);

I say it wont work because its always high since pulled high so you have to check for low. Did you change the definition to:

#define KeyPORT (~((PORTA>>2)&0x0F))
 
Last edited:
This is how I would normally turn an led on via a switch.

When first turned on "Waiting" is displayed when switch 1(RA2) is pressed "LED ON" is displayed and the LED is turned on, when switch 2 (RA3) is pressed "LED OFF" is displayed and the LED is turned off.

This is all the code I am using, any other include files must be automatically selected by mikroc and I cannot see what it is.

Code:
// LCD connections definitions
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD connections definitions

void main() {
  CMCON  |= 7;                       // Disable Comparators

  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Turn cursor off
  Lcd_Out(1, 3, "Waiting");
  do {
  if (Button(&PORTA, 2, 1, 0)) {  // Detect logical one to zero
     Delay_ms(100);
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Out(1,1, "LED ON");
     TRISA.F6 = 0;
     PORTA.F6 = 1;
  }
  if (Button(&PORTA, 3, 1, 0)) {  // Detect logical one to zero
     Delay_ms(100);
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Out(1,1, "LED OFF");
     TRISA.F6 = 0;
     PORTA.F6 = 0;
  }
  } while (1);
}
 
here is teh equavalent code but written the way you have shown me, but it does not recognise switch presses:

Code:
#define KeyPORT ((PORTA>>2)&0x0F)

#define ON   2
#define OFF  3

// LCD connections definitions
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD connections definitions

unsigned char WaitForInput(void){
	unsigned char temp1;	//TEMP DATA HOLDER
	unsigned char done = 0; //DONE Var will determine if done

	while(!done){				  //while done == 0
		if(KeyPORT>0){			  //if KeyPORT aka PORTB&0x0F.. the &0x0f will make sure we
						  //return the lower part of port only RB0 to RB3
			temp1 = KeyPORT;	  //Place the lower part of port into temp variable
			while(KeyPORT==temp1);    //Like a debounce for button press
			done = 0xFF;		  //Set DONE Var so we know we are complete
		}
	}
	return temp1;				  //Return our temp1 var
}

void main() {
  CMCON  |= 7;                       // Disable Comparators
  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
  Lcd_Out(1, 3, "Waiting");
  do {
  //--- main loop
   switch(WaitForInput()){
		case ON:
                     Delay_ms(100);
                     Lcd_Cmd(_LCD_CLEAR);
                     Lcd_Out(1,1, "LED ON");
                     TRISA.F6 = 0;
                     PORTA.F6 = 1;
			break;
		case OFF:
                     Delay_ms(100);
                     Lcd_Cmd(_LCD_CLEAR);
                     Lcd_Out(1,1, "LED OFF");
                     TRISA.F6 = 0;
                     PORTA.F6 = 0;
			break;
	}
	} while (1);
}
 
oops forgot about the define, now change to
#define KeyPORT (~((PORTA>>2)&0x0F))
in my example script aswell but wit the same result
 
Last edited:
Im downloading MikroC now to try it out but try this for now:
Code:
#define KeyPORT (~((PORTA>>2)&0x0F))

#define ON   1
#define OFF  2

// LCD connections definitions
s
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD connections definitions

unsigned char WaitForInput(void){
	unsigned char temp1;	//TEMP DATA HOLDER
	unsigned char done = 0; //DONE Var will determine if done

	while(!done){				  //while done == 0
		if(KeyPORT>0){			  //if KeyPORT aka PORTB&0x0F.. the &0x0f will make sure we
						  //return the lower part of port only RB0 to RB3
			temp1 = KeyPORT;	  //Place the lower part of port into temp variable
			while(KeyPORT==temp1);    //Like a debounce for button press
			done = 0xFF;		  //Set DONE Var so we know we are complete
		}
	}
	return temp1;				  //Return our temp1 var
}

void main() {
  CMCON  |= 7;                       // Disable Comparators
  TRISA = (0x0F<<2);                 // [b]RA5,RA4,RA3,RA2 are set to input[/b]
  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
  Lcd_Out(1, 3, "Waiting");
  do {
  //--- main loop
   switch(WaitForInput()){
		case ON:
                     Delay_ms(100);
                     Lcd_Cmd(_LCD_CLEAR);
                     Lcd_Out(1,1, "LED ON");
                     TRISA.F6 = 0;
                     PORTA.F6 = 1;
			break;
		case OFF:
                     Delay_ms(100);
                     Lcd_Cmd(_LCD_CLEAR);
                     Lcd_Out(1,1, "LED OFF");
                     TRISA.F6 = 0;
                     PORTA.F6 = 0;
			break;
	}
	} while (1);
}
 
Ok thanks I gess you use a different compiler? Your suggestion did the same as what my code did, just displays waiting.
 
This works nice:
Code:
#define ON   2
#define OFF  3

unsigned char WaitForInput(void){
    unsigned char done = 0;           //DONE Var will determine if done and hold key

    while(!done){        	      //while done == 0
      if (Button(&PORTA, ON, 1, 0))   //Is On button pressed (LOW)
          done = ON;                  //If So set done to ON
      if (Button(&PORTA, OFF, 1, 0))  //Is Off button pressed (LOW)
          done = OFF;                 //If so set done to OFF
    }
    return done;		      //Return our done/key var
}

void main() {
  CMCON  |= 7;                        // Disable Comparators
  TRISA = (0x0F<<2);                  // [b]RA5,RA4,RA3,RA2 are set to input[/b]

  do {
  //--- main loop
   switch(WaitForInput()){
		case ON:
                     Delay_ms(100);
                     TRISA.F6 = 0;
                     PORTA.F6 = 1;
			break;
		case OFF:
                     Delay_ms(100);
                     TRISA.F6 = 0;
                     PORTA.F6 = 0;
			break;
	}
	} while (1);
}
 
Last edited:
This also works well:
Code:
unsigned char WaitForInput(void){
    unsigned char done = 0;           //DONE Var will determine if done and hold key

    while(!done){        	      //while done == 0
      if (Button(&PORTA, ON, 1, 0))   //Is On button pressed (LOW)
          return ON;                  //If So set done to ON
      if (Button(&PORTA, OFF, 1, 0))  //Is Off button pressed (LOW)
          return OFF;                 //If so set done to OFF
    }
}
 
Last edited:
I thought I would add the array to the script and thought that the following should still loop through the menu:

Code:
#define MENU   2
#define UP  3
#define DOWN  4
// LCD connections definitions
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD connections definitions

 unsigned char MainMenuLIST[3][16] = {
{"Option 1"},
{"Option 2"},
{"Option 3"}
};

unsigned char WaitForInput(void){
	unsigned char done = 0; //DONE Var will determine if done and hold key

	while(!done){				  //while done == 0
    if (Button(&PORTA, MENU, 1, 0))
          done = MENU;
    if (Button(&PORTA, UP, 1, 0))
          done = UP;
    if (Button(&PORTA, DOWN, 1, 0))
          done = DOWN;
	}
	return done;				  //Return our done/key var
}

void main() {
  unsigned char POS = 0;
  unsigned char x;
  CMCON  |= 7;                       // Disable Comparators
  TRISA = (0x0F<<2);                 // RA5,RA4,RA3,RA2 are set to input
  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
  Lcd_Out(1, 3, "Waiting");
  
  do {

  //--- main loop
   switch(WaitForInput()){
		case MENU:
                     Delay_ms(100);
                     Lcd_Cmd(_LCD_CLEAR);
                     for(x=0;x<2;x++){
                       if(x == POS)
                       Lcd_Out((x+1),2,">");
                     else
			Lcd_Out((x+1),2," ");

                     Lcd_Out((x+1),2,MainMenuLIST[x]);
                     }
                     break;
                case UP:
                     if(POS>0){
               	     POS--;
                     }
                     break;
		case DOWN:
		     if(POS<1){
		     POS++;
                     }
		break;
	}
	} while (1);
}

This scrip displays "Waiting" when MENU is pressed it displays "Option 1" on line 1 and "Option 2" on line 2 however there is no "<" on the screen and pressing UP and DOWN do nothing and I never see option 3.

I would of expected this to:

Waiting
Press MENU
>Option 1
Option 2
press DOWN
>Option 2
Option 3
press DOWN
Option 2
>Option 3
 
I have just changed
Code:
for(x=0;x<2;x++){
                       if(x == POS)
                       Lcd_Out((x+1),2,">");
                     else
			Lcd_Out((x+1),2," ");

                     Lcd_Out((x+1),2,MainMenuLIST[x]);
                     }

to

Code:
for(x=0;x<2;x++){
                       if(x == POS)
                       Lcd_Out((x+1),1,">");
                     else
			Lcd_Out((x+1),1," ");

                     Lcd_Out((x+1),2,MainMenuLIST[x]);
                     }

and it now displays:
>Option 1
Option 2

however the UP and DOWN switches still do nothing
 
The following works as expected but only for options 1 and 2, option 3 is still never shown:

Code:
#define MENU   2
#define UP  3
#define DOWN  4
// LCD connections definitions
sbit LCD_RS at RA0_bit;
sbit LCD_EN at RA1_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD connections definitions

 unsigned char MainMenuLIST[3][16] = {
{"Option 1"},
{"Option 2"},
{"Option 3"}
};

unsigned char WaitForInput(void){
	unsigned char done = 0; //DONE Var will determine if done and hold key

	while(!done){				  //while done == 0
    if (Button(&PORTA, MENU, 1, 0))
          done = MENU;
    if (Button(&PORTA, UP, 1, 0))
          done = UP;
    if (Button(&PORTA, DOWN, 1, 0))
          done = DOWN;
	}
	return done;				  //Return our done/key var
}

void MainMenu(void){
unsigned char POS = 0; 	//Used for cursor ONLY!
unsigned char done = 0;
unsigned char x;
unsigned char ITEM=0;

Lcd_Cmd(_LCD_CLEAR);

while(!done){
	for(x=0;x<2;x++){

		if(x == POS)
   Lcd_Out((x+1),1,">");
		else
   Lcd_Out((x+1),1," ");

        Lcd_Out((x+1),2,MainMenuLIST[x]);
	}

	switch(WaitForInput()){
		case UP:
			if(POS>0){
				POS--;
				ITEM--;
			}
			break;
		case DOWN:
			if(POS<1){
				POS++;
				ITEM++;
			}
			break;
		case MENU:
			done = 0xFF;
			break;
	}
}
	// ITEM contains what item is selected
	// POS isnt used incase larger then 2 menu...

	switch(ITEM){
		case 0:
		Lcd_Cmd(_LCD_CLEAR);
                Lcd_Out(1, 3, "temp   ");
                Delay_ms(2000);
			break;
		case 1:
                Lcd_Cmd(_LCD_CLEAR);
                Lcd_Out(1, 3, "Time");
                Delay_ms(2000);
			break;
	}

	//Bring our title back.. cuz we are done with the menu...


}

void main() {
  unsigned char POS = 0;
  unsigned char x;
  CMCON  |= 7;                       // Disable Comparators
  TRISA = (0x0F<<2);                 // RA5,RA4,RA3,RA2 are set to input
  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
  Lcd_Out(1, 3, "Waiting");
      do {
 switch(WaitForInput()){
		case MENU:
		Delay_ms(100);
		MainMenu();
		break;
		}

} while (1);
}
 
look at my other menu... you need a starting point aka a page reference... check this post in 1 minute for code below

EDIT: TRY THIS:
Code:
void MainMenu(void){
unsigned char POS = 0; 	//Used for cursor ONLY!
unsigned char done = 0;
unsigned char x;
unsigned char ITEM=0;
unsigned char PAGE=0;

Lcd_Cmd(_LCD_CLEAR);

while(!done){
	for(x=0;x<2;x++){

		if(x == POS)
   Lcd_Out((x+1),1,">");
		else
   Lcd_Out((x+1),1," ");

        Lcd_Out((x+1),2,MainMenuLIST[(x+PAGE)]);
	}

	switch(WaitForInput()){
		case UP:
			if(POS>0){
				POS--;
				ITEM--;
			} else {
        if(PAGE != 0) PAGE--;
      }
			break;
		case DOWN:
			if(POS<1){
				POS++;
				ITEM++;
			} else {
        PAGE++;
      }
			break;
		case MENU:
			done = 0xFF;
			break;
	}
}
	// ITEM contains what item is selected
	// POS isnt used incase larger then 2 menu...
[B]  ITEM+=PAGE;[/B]
	switch(ITEM){
		case 0:
                Delay_ms(2000);
			break;
		case 1:
                Delay_ms(2000);
			break;
	}

	//Bring our title back.. cuz we are done with the menu...


}

Try it now heh i forgot to add the 1 line:
ITEM+=PAGE;
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top