CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

cursor scroll down menu

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








cursor scroll down menu
PostPosted: Sun Sep 20, 2009 11:15 am     Reply with quote

This is partly based on the
http://www.ccsinfo.com/forum/viewtopic.php?t=40225
topic.

I want to scroll down threw four line lcd selection on 2x16 display where "+" sign is used as pointing sign of for the active selection.

+ line
line
line

Ideas ?
Guest








PostPosted: Sun Sep 20, 2009 12:38 pm     Reply with quote

I write some basic code for choosing between menus.
MM stands for Main Menu and _sub is sub menu of main menu.

How to implement this into keypad scanning and into scroll down menu ?

Code:
static enum states{
   MMLine3,
   MMLine2
   MMLine1,
};

enum events{
   MMLine3_sub,
   MMLine2_sub
   MMLine1_sub,
};


static unsigned char state;

static void MMLine3_EventHandler(unsigned char event);
static void MMLine2_EventHandler(unsigned char event);
static void MMLine1_EventHandler(unsigned char event);

static void ChangeState(unsigned char newState)
{
   state=newState;
}


static void MMLine3_EventHandler(unsigned char event)
{
   switch(event)
   {
      case MMLine3_sub:
         break;
      case MMLine2_sub:
         break;
      case MMLine1_sub:
         ChangeState(MMLine1);
         break;
   }
}

static void MMLine2_EventHandler(unsigned char event)
{
   switch(event)
   {
      case MMLine3_sub:
         break;
      case MMLine2_sub:
         break;
      case MMLine1_sub:
         break;
   }
}

static void MMLine1_EventHandler(unsigned char event)
{
   switch(event)
   {
      case MMLine3_sub:
         break;
      case MMLine2_sub:
         break;
      case MMLine1_sub:
         break;
   }
}

//--- main thing
void GlobalEventHandler(unsigned char event)
{
   switch(state)
   {
      case MMLine3: MMLine3_EventHandler(event);
         break;
      case MMLine2: MMLine2_EventHandler(event);
         break;
      case MMLine1: MMLine1_EventHandler(event);
         break;
   }
}
PicByte
Guest







PostPosted: Wed Oct 14, 2009 7:06 am     Reply with quote

This is the full code for menu tree.
It has 3 main menu's and 2 sub menu's in each main menu.

My question is how to convert this code so that it can read key press from the 3x4 keypad ?

Code:
-------------------------
#include <18f4550.h>
#device adc=10
#fuses NOLVP, NOWDT, XT
#use delay(clock=4000000)
#include <lcd.c>

#define UP     0xB0
#define DOWN   0x70
#define ENTER  0xD0
#define MENU   0xF0
#define CANCEL 0xE0

#define ALL_MENU     10
enum ids{_BEGIN,_,_MAIN1,_SUBMENU_1A,_SUBMENU_1B,_MAIN2,_SUBMENU_2A,_SUBMENU_2B,_MAIN3,_SUBMENU_3A,_SUBMENU_3B,};
struct TypeMenu {
             int8 MenuID;
             int8 SubMenu;
             char MenuName[16];//17
            };
 
int8 ContainMenu, STATE = _BEGIN, PAGE = 0, LEVEL[7], LevelPtr=0;
Boolean  AccessENTER = TRUE, AccessCANCEL=TRUE;

//-------------------------------------------
const struct TypeMenu MenuOfTuan[ALL_MENU] 
   ={{_,_BEGIN,""},
   {_MAIN1,_BEGIN,"main1"},
   {_SUBMENU_1A,_MAIN1,"subMenu_1a"},
   {_SUBMENU_1B,_MAIN1,"subMenu_1b"},
   {_MAIN2,_BEGIN,"main2"},
   {_SUBMENU_2A,_MAIN2,"subMenu_2a"},
   {_SUBMENU_2B,_MAIN2,"subMenu_2b"},
   {_MAIN3,_BEGIN,"main3"},
   {_SUBMENU_3A,_MAIN3,"subMenu_3a"},
   {_SUBMENU_3B,_MAIN3,"subMenu_3b"},
   };struct typeMenu MenuPointer[2];

//---------------------------------------
unsigned char SelectFrom(int8 from) {
   int8 i, NumMenu = 0,k=0, i0;               
   for(i=0; i<ALL_MENU; i++) {
     if(MenuOfTuan[i].SubMenu == STATE) {
        if(NumMenu == 0) i0 = i;
           NumMenu++;
        if(NumMenu>from && k < 2) {
           MenuPointer[k] = MenuOfTuan[i];
           k++;
           }
         if(k == 1) MenuPointer[1] = MenuOfTuan[i0];
             }                                   
          }
          return NumMenu;
 }
//----------------------------------------
int8 QueryLastMenu() {
   int8 i;                         
   for(i=0; i<ALL_MENU; i++) {     
   if(MenuOfTuan[i].MenuID == MenuPointer[0].SubMenu) 
     return MenuOfTuan[i].SubMenu;
   }
     return 0x00;
}

//----------------------------------------
short HasSubMenu() {
 char i;
  for(i=0; i<ALL_MENU; i++) {           
   if(STATE == MenuOfTuan[i].SubMenu) 
      return TRUE;                     
   }                                     
      return FALSE;                         
   }


//---------------------------------------
void ProcessMenu() {
   if(PAGE > ContainMenu-1) PAGE = 0;
   if(PAGE == 0xFF) PAGE = ContainMenu - 2;
      ContainMenu = SelectFrom(PAGE);

   printf(lcd_putc,"\f>%s",MenuPointer[0].MenuName);
   if(ContainMenu > 1)
     printf(lcd_putc,"\n %s",MenuPointer[1].MenuName);
 }


//--------------------------------------
void ProcessAction(long Key) {
 if(STATE == _BEGIN) AccessCANCEL = FALSE; 
  else  AccessCANCEL = TRUE;               
   switch(Key) {
       case ENTER:
       if(!AccessENTER) break;       
       LEVEL[LevelPtr] = PAGE;   
       LevelPtr++;               
       STATE = MenuPointer[0].MenuID;
       PAGE = 0;                 
       ContainMenu = SelectFrom(0);
       if(ContainMenu) {
          ProcessMenu();         
       }else {
          AccessENTER = FALSE;   
           switch(STATE){
                case _:             //Function for  here
                lcd_putc("\f");
                break;
               
                case _SUBMENU_1A:       //Function for subMenu_1a here
                lcd_putc("\fsubMenu_1a");
                break;
               
                case _SUBMENU_1B:       //Function for subMenu_1b here
                lcd_putc("\fsubMenu_1b");
                break;
               
                case _SUBMENU_2A:       //Function for subMenu_2a here
                lcd_putc("\fsubMenu_2a");
                break;
               
                case _SUBMENU_2B:       //Function for subMenu_2b here
                lcd_putc("\fsubMenu_2b");
                break;
               
                case _SUBMENU_3A:       //Function for subMenu_3a here
                lcd_putc("\fsubMenu_3a");
                break;
               
                case _SUBMENU_3B:       //Function for subMenu_3b here
                lcd_putc("\fsubMenu_3b");
                break;
              }
                       
              }
                break;
                   
                case UP:                   
                     if(!AccessENTER) break;
                     if(PAGE == 0) PAGE = ContainMenu;
                     PAGE --;               
                     ProcessMenu();
                     break;
                case DOWN:                 
                     if(!AccessENTER) break;
                     PAGE ++;               
                     ProcessMenu();
                     break;
                case CANCEL:                 
                     if(!AccessCANCEL) break;
                     if(LevelPtr) LevelPtr--;   
                     PAGE = LEVEL[LevelPtr];   
                     if(!HasSubMenu()) {       
                           AccessENTER = TRUE; 
                           STATE = MenuPointer[0].SubMenu;
                     } else {                   
                           STATE = QueryLastMenu();   
                        }
                        ContainMenu = SelectFrom(0);
                        ProcessMenu();         
                     break;
                  case MENU:
                     ContainMenu = SelectFrom(0);
                     ProcessMenu();
                     Break; 
               }
            }

//---------------------------------------
int8 keyscan() {
int8 inB, varRet;
inB = input_b()&0xF0;
 if(inB != 0xF0){
    varRet = inB;
    delay_ms(20);
    inB = input_b()&0xF0;
 if(inB == 0xF0) {
    return varRet;
 } else {
    return 0;
  }
  }
 }

//------------main----------------------------

void Main() {
int8 key;
set_tris_b(0xFF);
lcd_init();       
processAction(MENU);
while(1){
  key = keyscan(); 
  if(key) {         
     processAction(key);
  }
 }
}
//------------------ EOF ---------------------
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 14, 2009 3:53 pm     Reply with quote

Quote:

while(1){
key = keyscan();
if(key) {
processAction(key);
}

My question is how to convert this code so that it can read key press
from the 3x4 keypad ?

Look at how this CCS example file calls the kbd_getc() function.
It's similar to your code above.
Quote:
c:\program files\picc\examples\ex_lcdkb.c


The kbd_getc() function returns an ASCII byte, corresponding to the
key labels on the 4x3 keypad. Change the 'case' statements in
the ProcessAction() function, so they respond to the ASCII bytes
from kbd_getc().
PicByte
Guest







PostPosted: Fri Oct 16, 2009 3:55 am     Reply with quote

It's not my code i copy pasted from one lcd project.

My keypad is on port C and D and the control keys are 1,2,#,*.
1 and 2 = up/down
# = confirmation
* = cancel

I look at the example that you posted.
I understand what you writing, but i don't know which way is the best one.

In code is defined
#define UP 0xB0
#define DOWN 0x70
#define ENTER 0xD0
#define MENU 0xF0
#define CANCEL 0xE0

so i have to switch this with 1,2,#,*. and the only way to do this is to run the kbc_getc. OK. He is using keyscan routine to scan throwout switches and now we have to switch this with kbd_getc.

So i guess that you are planning to set something like this:

Code:
void ProcessAction(long Key) {
 if(STATE == _BEGIN) AccessCANCEL = FALSE;
  else  AccessCANCEL = TRUE;               
   switch(Key) {
      key=kbc_getc();
       case '#':
          if(!AccessENTER) break;       
          LEVEL[LevelPtr] = PAGE;   
          LevelPtr++;               
          STATE = MenuPointer[0].MenuID;
          PAGE = 0;                 
          ContainMenu = SelectFrom(0);
          if(ContainMenu) {
             ProcessMenu();         
          }else {
             AccessENTER = FALSE;   
              switch(STATE){
                case _:        eaDogM_WriteString("\f"); break;          //Function for  here
                case _SUBMENU_1A:eaDogM_WriteString("\fsubMenu_1a");break;    //Function for subMenu_1a here
                case _SUBMENU_1B:eaDogM_WriteString("\fsubMenu_1b");break;   //Function for subMenu_1b here
                case _SUBMENU_2A:eaDogM_WriteString("\fsubMenu_2a");break;   //Function for subMenu_2a here
                case _SUBMENU_2B:eaDogM_WriteString("\fsubMenu_2b");break;   //Function for subMenu_2b here
                case _SUBMENU_3A:eaDogM_WriteString("\fsubMenu_3a");break;    //Function for subMenu_3a here
                case _SUBMENU_3B:eaDogM_WriteString("\fsubMenu_3b");break;  //Function for subMenu_3b here
                       }
              }
                break;
                   
                case '1':                   
                     if(!AccessENTER) break;
                     if(PAGE == 0) PAGE = ContainMenu;
                     PAGE --;               
                     ProcessMenu();
                     break;
                case '2':                 
                     if(!AccessENTER) break;
                     PAGE ++;               
                     ProcessMenu();
                     break;
                case '*':                 
                     if(!AccessCANCEL) break;
                     if(LevelPtr) LevelPtr--;   
                     PAGE = LEVEL[LevelPtr];   
                     if(!HasSubMenu()) {       
                           AccessENTER = TRUE;
                           STATE = MenuPointer[0].SubMenu;
                     } else {                   
                           STATE = QueryLastMenu();   
                        }
                        ContainMenu = SelectFrom(0);
                        ProcessMenu();         
                     break;
                  case '#':
                     ContainMenu = SelectFrom(0);
                     ProcessMenu();
                     Break;
               }
            }



Wright | wrong | totally wrong :-) ?
PicByte
Guest







PostPosted: Fri Oct 16, 2009 4:35 am     Reply with quote

I removed the keyscan function from the main and left only the proccessAction(menu). On the display i get two garbage chars i first row.
NewOne
Guest







PostPosted: Sat Oct 24, 2009 8:17 am     Reply with quote

Hello,
I tested the code on my explorer16 board with pic24fj128.

This is what I get on the LCD:
>
main1

I changed the code to fit the switches on the demo board.
Code:

#define UP     PIN_D6
#define DOWN   PIN_D7
#define MENU   PIN_A7
.....
int8 keyscan() {
int8 inB, varRet;
inB = input_a()& MENU;
 if(inB != MENU){
    varRet = inB;
    delay_ms(20);
    inB = input_a()& MENU;
 if(inB == MENU) {
    return varRet;
 } else {
    return 0;
  }
  }
 }

But I can not scroll through menu.
Sad
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group