-
Timer.c
/***********************************************
**** LAUNCH PAD 学习之LCD菜单 ***
**** MCU: msp430g2452 ***
**** 作者: 常见泽 ***
**** ***
**** ***
**** 2012.06.22.21:08 ***
**** 实验现象:LCD 2012年6月22日 ***
****
通过KEY 短按一下 进入下一个菜单,共四个菜单,长按选择菜单,执行相应的动作
***
**** P1.0~P1.7接LCD数据口 P2.0 P2.1 en rs ***
***********************************************/
#include <msp430g2452.h>
#include"Key.h"
#include"lcd1602.h"
#include"timer.h"
volatile unsigned int time_10ms_ok = 0;
struct MenuItem MainMenu[4] = //结构体主菜单
{
{4,"0.LED1.ON ",NextMenu,&Null},
{4,"1.LED1.OFF",NextMenu,&Null},
{4,"2.LED2.ON ",NextMenu,&Null},
{4,"3.LED2.OFF",NextMenu,&Null},
};
struct MenuItem NextMenu[4] = //子菜单
{
{4,"0.LED1_ON_ok? ",&Null,MainMenu},
{4,"1.LED1_OFF_ok?",&Null,MainMenu},
{4,"2.LED2_ON_ok? ",&Null,MainMenu},
{4,"3.LED2_OFF_ok?",&Null,MainMenu},
};
struct MenuItem (*MenuPoint) = MainMenu;
//*------------------------------------------------------------------------------
//*显示函数
//*------------------------------------------------------------------------------
void ShowMenu(void)
{
unsigned char i = 0;
MaxItems = MenuPoint[0].MenuCount; //获取当前菜单的条目数
DisplayPoint = DisplayStart; //显示菜单的编号
if( MaxItems > LCD1602_Max_Display_Line ) //如果大于能显示的菜单数做处理
{
for ( i = 0;i < LCD1602_Max_Display_Line;i++ )
{
LCD1602wRITESTring( i,1,MenuPoint[DisplayPoint].DisplayString );//2行分别显示两个菜单
//string(x,y,*date) x=0 第一行 Y为横轴位置
if ((DisplayPoint) == (UserChoose))
{
LCD1602SetAddr(0,0,0x7e); //写小箭头
}
else
{
LCD1602SetAddr(i,0,' '); //写空格
}
DisplayPoint += 1; //字符串偏移量+1
if ((DisplayPoint) == (MaxItems))
{
DisplayPoint = 0;
}
}// end of for(^)
}
}
void ExcuteMenu(void)
{
unsigned char GetKeyNum;
if (time_10ms_ok)
{ //确定有功能按键被按下的情况下才执行其功能
time_10ms_ok = 0;
GetKeyNum = key_driver();
if((GetKeyNum == 1)||(GetKeyNum == 2))
{
//ShowMenu();
//P2OUT |= BIT3; //LED1_on
switch (GetKeyNum)
{
case S_key://短按键
UserChoose++;
if (UserChoose == MaxItems)
{
UserChoose = 0;//当用户的选择数大于最大菜单数量,则选定的清零到第一个
}
GetKeyNum=0;
break;
case L_key: //长按键
if (MenuPoint[UserChoose].ChildrenMenus != &Null)
{
MenuPoint = MenuPoint[UserChoose].ChildrenMenus; //指向子菜单
SavePoint = UserChoose; //显示菜单的编号
UserChoose = 0;
DisplayStart = 0;
}
else if (MenuPoint[UserChoose].ParentMenus != &Null)
{
MenuPoint = MenuPoint[UserChoose].ParentMenus; //指向父菜单
UserChoose = 0;
DisplayStart= SavePoint-1;
UserChoose = SavePoint; //恢复先前的菜单
}
GetKeyNum=0;
break;
default: break;
}
//*--------------------------------------------------------------------
//*菜单循环处理
if ((UserChoose < DisplayStart) || (UserChoose >= (DisplayStart + 1 )))
{
DisplayStart = UserChoose;
}
write_com(0x01);
delay_nms(3);
ShowMenu();
}
}
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= 0xff; //P1.0为输出
P2DIR |= (BIT0|BIT1|BIT2|BIT3|BIT4);
P2OUT &= (~(BIT0|BIT1|BIT2|BIT3|BIT4));
CCR0 = 10000;
TACTL = TASSEL_2 + MC_1+TACLR; // MCLK,upmode
CCTL0 = CCIE; // 允许中断
_EINT();
init_LCD(); //液晶显示初始化
ShowMenu(); //显示菜单
while(1)
{
ExcuteMenu();
}
}
#pragma vector= TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
//P1OUT ^= 0x01; // Toggle P1.0
time_10ms_ok=1;
CCTL0 &= ~CCIFG;
//TAIFG = 0;
}