|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
cursor scroll down menu |
Posted: Sun Sep 20, 2009 11:15 am |
|
|
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
|
|
Posted: Sun Sep 20, 2009 12:38 pm |
|
|
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
|
|
Posted: Wed Oct 14, 2009 7:06 am |
|
|
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
|
|
Posted: Wed Oct 14, 2009 3:53 pm |
|
|
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
|
|
Posted: Fri Oct 16, 2009 3:55 am |
|
|
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
|
|
Posted: Fri Oct 16, 2009 4:35 am |
|
|
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
|
|
Posted: Sat Oct 24, 2009 8:17 am |
|
|
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.
|
|
|
|
|
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
|