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.
that is all the code so far as I have not tried to combine it with my other code yet because I am just trying the menu on its own, I can post the other code if that is what you mean?

I have 3 switches atm wanting to use 4th as a cancel button

menu/enter - RA2
up - RA3
down - RA4
 
ok .. so you have LCD code to show data on lcd already? Like normal text?

Ok um... in code the buttons are lined up like

PORTA = BINARY 0000-0000

Pressing:
RA2 would result in : 0000-0100
RA3 would result in : 0000-1000
RA4 would result in : 0001-0000

This means we have to change the code to accommodate using the upper byte as well...

um.... something like...

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

This way if PORTA = 0000-0100 (aka RA2 pressed)
it will come up as 0000-0001 since we right shift 2 times
 
Last edited:
Yes I already have lcd working wih normal text.


Here is how i think it should be implemented with my ds1820 code:

Code:
#define KeyPORT ((PORTB>>2)&0x0F)
#define KeyDIR  TRISB

#define ENTER 2
#define UP    3
#define DOWN  4

#define LCD_LINE
#define LCD_DATA
#define LCD_STR
// 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 rom char MainMenuLIST[2][16] = {
{"Option 1"},
{"Option 2"}
};

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
}
// String array to store temperature value to display
char *temp = "000.00";

// Temperature Resolution : No. of bits in temp value = 9
const unsigned short TEMP_RES = 9;

// Variable to store temperature register value
unsigned temp_value;

void Display_Temperature(unsigned int temp2write) {
  const unsigned short RES_SHIFT = TEMP_RES - 8;

  // Variable to store Integer value of temperature
  char temp_whole;

  // Variable to store Fraction value of temperature
  unsigned int temp_fraction;

  // check if temperature is negative
  if (temp2write & 0x8000) {
     temp[0] = '-';
     // Negative temp values are stored in 2's complement form
     temp2write = ~temp2write + 1;
     }

  // Get temp_whole by dividing by 2 (DS1820 9-bit resolution with
  // 0.5 Centigrade step )
  temp_whole = temp2write >> RES_SHIFT ;

  // convert temp_whole to characters
  if (temp_whole/100)
  // 48 is the decimal character code value for displaying 0 on LCD
     temp[0] = temp_whole/100  + 48;
  else
     temp[0] = '0';

  temp[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
  temp[2] =  temp_whole%10     + 48;             // Extract ones digit

  // extract temp_fraction and convert it to unsigned int
  temp_fraction  = temp2write << (4-RES_SHIFT);
  temp_fraction &= 0x000F;
  temp_fraction *= 625;

  // convert temp_fraction to characters
  temp[4] =  temp_fraction/1000    + 48;         // Extract tens digit
  temp[5] = (temp_fraction/100)%10 + 48;         // Extract ones digit

  // print temperature on LCD
  Lcd_Out(2, 5, temp);
}
unsigned int digit;

void read_temp() {
   //--- perform temperature reading
    Ow_Reset(&PORTB, 5);      // Onewire reset signal
    Ow_Write(&PORTB, 5, 0xCC);   // Issue command SKIP_ROM
    Ow_Write(&PORTB, 5, 0x44);   // Issue command CONVERT_T
    Delay_ms(600);
    // If this delay is less than 500ms, you will see the first reading on LCD
    //85C which is (if you remember from my article on DS1820)
    //a power-on-reset value.

    Ow_Reset(&PORTB, 5);
    Ow_Write(&PORTB, 5, 0xCC);    // Issue command SKIP_ROM
    Ow_Write(&PORTB, 5, 0xBE);    // Issue command READ_SCRATCHPAD

    // Read Byte 0 from Scratchpad
    temp_value =  Ow_Read(&PORTB, 5);
    // Then read Byte 1 from Scratchpad and shift 8 bit left and add the Byte 0
    temp_value = (Ow_Read(&PORTB, 5) << 8) + temp_value;

    //--- Format and display result on Lcd
    Display_Temperature(temp_value);
}

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++){
        LCD_LINE(x+1);

		if(x == POS)
			LCD_DATA('>',1);
		else
			LCD_DATA(' ',1);

        LCD_STR(MainMenuLIST[x]);
	}

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

	switch(ITEM){
		case 0:
			//Code to toggle C or F
			break;
		case 1:
			//Code to jump to new menu system
			break;
	}

	//Bring our title back.. cuz we are done with the menu...
    LCD_LINE(1);
    LCD_STR((unsigned rom char*)"  AtomSoftTech  ");

}

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,5,message1);             // Write message1 in 1st row
  Lcd_Out(2,4,message2);             // Write message1 in 2nd row
  Delay_ms(2000);
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Out(1, 3, "Temperature:   ");
  // Print degree character, 'C' for Centigrades
  Lcd_Chr(2,11,223);
 // different LCD displays have different char code for degree
 // if you see greek alpha letter try typing 178 instead of 223

  Lcd_Chr(2,12,'C');
  digit = 0;
  //--- main loop
  do {
    if(Button(&PORTA,2, 1, 0)) {
             MainMenu();
             }
    else {
            read_temp();
          }
    } while (1);
}

I know that the MainMenu items will not display anything this way but before I get that far I get an error when compilieing because of the array. I am using microc compiler
 
yes that has solved the error now I can compile the code but i still need to know how LCD_STR() works in comparison to my lcd_out();
 
I have 2 LCD_STR

Code:
void LCD_STR(unsigned rom char *text){
    while(*text){
        LCD_DATA(*text++,1);
    }
}
void LCD_STR2(unsigned char *text){
    while(*text){
        LCD_DATA(*text++,1);
    }
}
 
Try this:

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

#define ENTER 1
#define UP    2
#define DOWN  4

#define LCD_LINE
#define LCD_DATA
#define LCD_STR
// 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[2][16] = {
{"Option 1"},
{"Option 2"}
};

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
}
// String array to store temperature value to display
char *temp = "000.00";

// Temperature Resolution : No. of bits in temp value = 9
const unsigned short TEMP_RES = 9;

// Variable to store temperature register value
unsigned temp_value;

void Display_Temperature(unsigned int temp2write) {
  const unsigned short RES_SHIFT = TEMP_RES - 8;

  // Variable to store Integer value of temperature
  char temp_whole;

  // Variable to store Fraction value of temperature
  unsigned int temp_fraction;

  // check if temperature is negative
  if (temp2write & 0x8000) {
     temp[0] = '-';
     // Negative temp values are stored in 2's complement form
     temp2write = ~temp2write + 1;
     }

  // Get temp_whole by dividing by 2 (DS1820 9-bit resolution with
  // 0.5 Centigrade step )
  temp_whole = temp2write >> RES_SHIFT ;

  // convert temp_whole to characters
  if (temp_whole/100)
  // 48 is the decimal character code value for displaying 0 on LCD
     temp[0] = temp_whole/100  + 48;
  else
     temp[0] = '0';

  temp[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
  temp[2] =  temp_whole%10     + 48;             // Extract ones digit

  // extract temp_fraction and convert it to unsigned int
  temp_fraction  = temp2write << (4-RES_SHIFT);
  temp_fraction &= 0x000F;
  temp_fraction *= 625;

  // convert temp_fraction to characters
  temp[4] =  temp_fraction/1000    + 48;         // Extract tens digit
  temp[5] = (temp_fraction/100)%10 + 48;         // Extract ones digit

  // print temperature on LCD
  Lcd_Out(2, 5, temp);
}
unsigned int digit;

void read_temp() {
   //--- perform temperature reading
    Ow_Reset(&PORTB, 5);      // Onewire reset signal
    Ow_Write(&PORTB, 5, 0xCC);   // Issue command SKIP_ROM
    Ow_Write(&PORTB, 5, 0x44);   // Issue command CONVERT_T
    Delay_ms(600);
    // If this delay is less than 500ms, you will see the first reading on LCD
    //85C which is (if you remember from my article on DS1820)
    //a power-on-reset value.

    Ow_Reset(&PORTB, 5);
    Ow_Write(&PORTB, 5, 0xCC);    // Issue command SKIP_ROM
    Ow_Write(&PORTB, 5, 0xBE);    // Issue command READ_SCRATCHPAD

    // Read Byte 0 from Scratchpad
    temp_value =  Ow_Read(&PORTB, 5);
    // Then read Byte 1 from Scratchpad and shift 8 bit left and add the Byte 0
    temp_value = (Ow_Read(&PORTB, 5) << 8) + temp_value;

    //--- Format and display result on Lcd
    Display_Temperature(temp_value);
}

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++){
        LCD_LINE(x+1);

		if(x == POS)
			LCD_DATA('>',1);
		else
			LCD_DATA(' ',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 ENTER:
			done = 0xFF;
			break;
	}
}
	// ITEM contains what item is selected
	// POS isnt used incase larger then 2 menu...

	switch(ITEM){
		case 0:
			//Code to toggle C or F
			break;
		case 1:
			//Code to jump to new menu system
			break;
	}

	//Bring our title back.. cuz we are done with the menu...
    Lcd_Out(1, 3, "Temperature:   ");

}

void main() {
  CMCON  |= 7;                       // Disable Comparators
  KeyDIR = (0x0F<<2);

  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Turn cursor off
  Lcd_Out(1,5,message1);             // Write message1 in 1st row
  Lcd_Out(2,4,message2);             // Write message1 in 2nd row
  Delay_ms(2000);
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Out(1, 3, "Temperature:   ");
  // Print degree character, 'C' for Centigrades
  Lcd_Chr(2,11,223);
  // different LCD displays have different char code for degree
  // if you see greek alpha letter try typing 178 instead of 223

  Lcd_Chr(2,12,'C');
  digit = 0;
  //--- main loop
  do {
      if(KeyPORT == ENTER) {
          MainMenu();
      } else {
          read_temp();
      }
    } while (1);
}
 
Are your buttons Pulled low? Aka a resistor tied to gnd and when you press button it pushes VDD to pin..

I finished my entire menu and its working perfect. Here is my complete code ... everything is in a ZIP so i dont have to upload like 6 files heh... you can learn more from see everything i got here:

**broken link removed**
 
no my buttons r tied high like this:

**broken link removed**

Thanks for your code I will take a look through it.
 
There the issue heh. Try changing that define to

#define KeyPORT (~((PORTA>>2)&0x0F))

the. ~. Symbol means opposite I think
 
Last edited:
still does not register any button press, I will take a look through your zip to try and work out where I went wrong
 
doesnt your code check for button press?

Code:
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
}
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top