|
回复 24楼 zhaojun_xf 的帖子
楼主,我调单级菜单很久了,程序正常调通了,但显示和反白显示都正常,但是却不能正常滚动、、、、真的快要崩溃了。我急需楼主你给我指点迷津,麻烦你了!现在我把我的菜单函数和按键函数贴出来,希望楼主你帮帮我看看
键盘扫描如下:
/*************************************************
MCU:***********LAUNCHPAD(MSP430G2553)************
MODULE:********KEY_OPER.c************************
FUNCTION:*******独立键盘,完成相应功能************
DESIGNER:*******张涟棋****************************
DATE:***********2012-10-10************************
*************************************************/
/******************定义全局变量******************/
unsigned char test;
//unsigned char Key_ValF=0,Key_ci=0;
#define uint8 unsigned int
unsigned char key_flag; //按键是否已放开:1--是,0--否
//功能键定义区
#define KV_NO 0 // 无
# define UP 1
# define Down 2
# define Enter 3
# define Esc 4
void delay_Nms(unsigned int n)//延时
{
unsigned int i;
unsigned int j;
for(i = n;i > 0;i--)
for(j = 100;j > 0;j--)
_NOP();
}
void KEY_Port_Init()
{
P1DIR &= ~(BIT1+BIT2+BIT3+BIT4+BIT5);//12345输入方向
P1REN |= BIT1+BIT2+BIT3+BIT4+BIT5;//12345上下拉电阻使能
P1IE |= BIT1+BIT2+BIT3+BIT4+BIT5;//12345使能中断
P1IES |= (BIT1+BIT2+BIT3+BIT4+BIT5);//12345上升沿触发
}
/**************************************************************************************
* FunctionName : Menu_KeySan()
* Description : 获取按键值
* EntryParameter : None
* ReturnValue : 返回按键值
**************************************************************************************/
/*uint8 Menu_KeySan(void)
{
uint8 key = KV_NO;
key = test; // 获取按键
if (key != KV_NO)
{
//BuzzerSound(1); // 有键按下,响一声
while(key != KV_NO) // 等待按键释放
{
key_flag = 1; // 设置key_Flag标识;
}
}
return key;
}*/
#pragma vector =PORT1_VECTOR
__interrupt void P1port()
{
unsigned char Key_Num;
Key_Num = P1IFG;
switch(Key_Num)//判断哪一位按键触发的中断
{
case BIT1:test=0; delay_Nms(10);break;//do {P1OUT &=~BIT0;}while(!(P1IN&BIT1));break;//检测松手P1.1
case BIT2:test=1; delay_Nms(10);break;//do {P1OUT &=~BIT0;}while(!(P1IN&BIT2));break;//P1.2
case BIT3:test=2; delay_Nms(10);break;//do {P1OUT |=BIT0;}while(!(P1IN&BIT3));break;//P1.3
case BIT4:test=3; delay_Nms(10);break;//do {P1OUT &=~BIT0;}while(!(P1IN&BIT4));break;//P1.4
case BIT5:test=4; delay_Nms(10); break;//do {P1OUT &=~BIT0;}while(!(P1IN&BIT5));break;//P1.5
}
/*for (i=test*2;i>0;i--)//仅仅检测键盘使用,调其他程序屏蔽此段
{
P1OUT ^=BIT6;//
delay_Nms(500);
}*/
delay_Nms(5);
P1IFG=0;
//Key_ValF=1;
//Key_ci++;
key_flag = 1;
}
菜单实现如下:
#define uchar unsigned char
#define M_MENU_NUM 8
#define PAGE_DISP_NUM 4
uchar key_val;
// 按键值定义
#define KV_NO 0 // 无
#define KV_UP 1 // 上
#define KV_DN 2 // 下
#define KV_MD 3 // 中
#define KV_LF 4 // 左
#define KV_RT 5 // 右
typedef struct _MENU_PRMT
{
uchar Cursor; // 光标值(当前光标位置)
uchar PageNo; // 菜单页(显示开始项)
uchar Index; // 菜单索引(当前选择的菜单项)
uchar DispNum; // 显示项数(每页可以现在菜单项)
uchar MaxPage; // 最大页数(最大有多少种显示页)
} MENU_PRMT;
MENU_PRMT MenuPrmt;//extern
/**************************************************************************************
* FunctionName : Menu_Null()
* Description : 空函数
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void Menu_Null(void)
{
;
}
// 菜单执行
typedef struct _MENU_TABLE
{
uchar *MenuItem; // 菜单项目名称
void (*ItemHook)(void); // 要运行的菜单函数
}MENU_TABLE;
MENU_TABLE MMenu[M_MENU_NUM] = // 管理菜单
{
{"1.时间设定 ", Menu_Null}, // 时钟设置
{"2.系统参数 ", Menu_Null}, // 参数设置
{"3.教学参数 ", Menu_Null}, // 教学参数
{"4.下载参数 ", Menu_Null}, // 下载参数
{"5.清除存储 ", Menu_Null}, // 清除存储
{"6.校对速度 ", Menu_Null}, // 速度校对
{"7.退出管理 ", Menu_Null}, // 退出管理
{"8.其他设置 ", Menu_Null}, // 其他设置
};
/**************************************************************************************
* FunctionName : AppMenuPrmtInit()
* Description : 初始化菜单参数
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void AppMenuPrmtInit(void)
{
MenuPrmt.Cursor = 0; // 光标清零
MenuPrmt.PageNo = 0; // 页清零
MenuPrmt.Index = 0; // 索引清零
}
/**************************************************************************************
* FunctionName : App_MenuSet()
* Description : 设置菜单显示
* EntryParameter : num - 页菜单显示项,page - 最多页数
* ReturnValue : None
**************************************************************************************/
void App_MenuSet(uint8 num, uint8 page)
{
MenuPrmt.DispNum = num; // 页最多显示项目数
MenuPrmt.MaxPage = page; // 最多页数
}
/**************************************************************************************
* FunctionName : App_MenuDisplay()
* Description : 显示菜单
* EntryParameter : page - 显示页,dispNum - 每一页的显示项,cursor - 光标位置
* ReturnValue : None
**************************************************************************************/
void App_MenuDisplay(MENU_TABLE *menu, uint8 page, uint8 dispNum, uint8 cursor)
{
uchar i;
for (i=0 ; i
if (cursor == i)
{
photodisplay(2, i+1, 5); // 反白显示菜单项
}
else
{
LCD_12864_string( i+1,3, menu[page+i-1].MenuItem); // 显示菜单项
}
}
}
/**************************************************************************************
* FunctionName : App_MenuMove()
* Description : 菜单移动
* EntryParameter : None
* ReturnValue : 有确认返回0,否则返回1
**************************************************************************************/
uint8 App_MenuMove(uint8 key)
{
uint8 rValue = 1;
switch (key)
{
case KV_UP: // 向上
{
if (MenuPrmt.Cursor != 0) // 光标不在顶端
{
MenuPrmt.Cursor--; // 光标上移
}
else // 光标在顶端
{
if (MenuPrmt.PageNo != 0) // 页面没有到最小
{
MenuPrmt.PageNo--; // 向上翻
}
else
{
MenuPrmt.Cursor = MenuPrmt.DispNum-1; // 光标到底
MenuPrmt.PageNo = MenuPrmt.MaxPage-1; // 最后页
}
}
break;
}
case KV_DN: // 向下
{
if (MenuPrmt.Cursor < MenuPrmt.DispNum-1) // 光标没有到底,移动光标
{
MenuPrmt.Cursor++; // 光标向下移动
}
else // 光标到底
{
if (MenuPrmt.PageNo < MenuPrmt.MaxPage-1) // 页面没有到底,页面移动
{
MenuPrmt.PageNo++; // 下翻一页
}
else // 页面和光标都到底,返回开始页
{
MenuPrmt.Cursor = 0;
MenuPrmt.PageNo = 0;
}
}
break;
}
case KV_MD: // 确认
{
MenuPrmt.Index = MenuPrmt.Cursor + MenuPrmt.PageNo; // 计算执行项的索引
rValue = 0;
break;
}
default:break;
}
return rValue; // 返回执行索引
}
/**************************************************************************************
* FunctionName : App_ManageMenu()
* Description : 管理菜单
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void App_ManageMenu(void)
{
LCD_12864_string(1, 1, " -= 管理系统 =- "); // 菜单标题显示
App_MenuSet(PAGE_DISP_NUM,M_MENU_NUM-PAGE_DISP_NUM+1); // 页显示3项,7个菜单项5页显示
App_MenuDisplay(MMenu, MenuPrmt.PageNo, MenuPrmt.DispNum, MenuPrmt.Cursor); // 显示菜单项
//if (test != KV_NO) // 有按键
if(key_flag==1)
{
{
if (App_MenuMove(test) == 0x00) // 菜单移动
{
Clear_GDRAM(); // 清屏
MMenu[MenuPrmt.Index].ItemHook(); // 执行相应项
}
key_flag=0;
test = KV_NO; // 清除按键值
}
}
} |
|