1

关于投票
EDN51静态菜单编写

点击下载

这个是静态的菜单,现在准备做个电子温度闹钟,用动态的。

如果只是控制的法,静态的已经够用了。

程序中存在些不如意的地方,希望和大家一起交流。

#include<at89x52.h>
#include <intrins.h>

 

# define uchar unsigned char

# define uint unsigned int

unsigned char Func_Index=0;     //存放当前的菜单索引

 

void (*Func_Ptr)();    //定义按键功能指针
////////////////////////////////////////////定义状态
void State0();
void State1();
void State2();
void State3();
void State4();
void State5();
void State6();
void State7();
void State8();
void State9();
void State10();

//定义按键
sbit k1=P2^0;
sbit k2=P2^3;
sbit k3=P2^4;
sbit k4=P2^5;
sbit k5=P2^6;
sbit k6=P2^7;
sbit k7=P1^5;
sbit k8=P1^6;


unsigned char key;

 

/************定义结构的类型**********/
typedef struct
{
    uchar  Index;               //当前的状态索引号   存储以后用来查询
 uchar  Gore;              //返回待机键状态索引号
 uchar  Right;               //右键状态索引号
    uchar  Up;                  //向上键状态索引号
 uchar  Down;               //向下键状态索引号
 uchar  Enter;                //确定键状态索引号
 uchar  Left;                //向左键状态索引号
    uchar  Goback1;             //返回上一级键状态索引号
 void   (*Operate)();     //当前状态应执行的操作
}   StateTab;

/**********结构数组*************/
StateTab code Menu_Tab[11]=
{
  { 0, 0, 0, 1, 2, 3, 0, 0,(*State0)},   // 待机
                               //           

  { 1, 0, 1, 1, 1, 1, 1, 1,(*State1)},   //           查看温度及报警范围设置
          //

  { 2, 0, 2, 2, 2, 2, 2, 2,(*State2)},   // 查看闹铃设置
          //          

  { 3, 0, 3, 6, 4, 7, 3, 3,(*State3)},   //    主菜单 时间
          // 

  { 4, 0, 4, 3, 5, 8, 4, 4,(*State4)},   //       主菜单 闹铃
          // 

  { 5, 0, 5, 4, 6, 9, 5, 5,(*State5)},   //     主菜单 温度
          // 

  { 6, 0, 6, 5, 3,10, 6, 6,(*State6)},   //  主菜单扩展
          //        
         
  { 7, 0, 7, 7, 7, 3, 7, 3,(*State7)},    //      时间调整
          //   
         
  { 8, 0, 8, 8, 8, 4, 8, 4,(*State8)},   //    闹铃设置   
          //     
         
  { 9, 0, 9, 9, 9, 5, 9, 5,(*State9)},   //    温度报警设置       
          //  
         
  {10, 0,10,10,10, 5,10, 5,(*State10)},   //    扩展设置


};


////////////////////////////////////////////////////////////////////
# define LCD_DB        P0

  sbit         LCD_RS=P1^0;

  sbit         LCD_RW=P1^1;

  sbit         LCD_E=P1^2;

 

/******定义函数****************/

void MenuOperate(uchar key);

void keyscan(); 


void LCD_init(void);//初始化函数

void LCD_write_command(uchar command);//写指令函数

void LCD_write_data(uchar dat);//写数据函数

void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-16),y(1-2)

void delay_n40us(uint n);//延时函数

 

void Printx(uchar x, uchar y,unsigned char *str);

void GotoXY(unsigned char x, unsigned char y);

//*******初始化函数***************

void LCD_init(void)

{

    delay_n40us(10000);

    LCD_write_command(0x38);//设置8位格式,2行,5x7

    LCD_write_command(0x38);//设置8位格式,2行,5x7

    LCD_write_command(0x38);//设置8位格式,2行,5x7

   
 LCD_write_command(0x02);//整体显示,关光标,不闪烁

 LCD_write_command(0x0C);//清除屏幕显示

    LCD_write_command(0x06);//设定输入方式,增量不移位

}

//********************************

//********写指令函数************

void LCD_write_command(uchar dat)

{
   
    LCD_E = 0;
 
 LCD_RS=0;//指令

    LCD_RW=0;//写入

    LCD_DB=dat;
 
 LCD_E=1;//允许

 delay_n40us(10);//实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。

    LCD_E = 0;
}

//////////////////////////////////////////

///////////////////写数据函数/////////////////////

void LCD_write_data(uchar dat)

{

     LCD_E = 0;    

  LCD_RS=1;//数据

     LCD_RW=0;//写入

     LCD_DB=dat;
 
  LCD_E=1;//允许

     delay_n40us(10);
    
  LCD_E = 0;
}

///////////////////////////////////

//////////////////显示一个字符函数////////////

void LCD_disp_char(uchar x,uchar y,uchar dat)

{
      uchar address;

     if(y==1)

              address="0x80"+x;

     else

              address="0xc0"+x;

     LCD_write_command(address);
   
     LCD_write_data(dat);
}

//////////////////////////////延时/////////////////////

void delay_n40us(uint n)

{   
       uint i;

      uchar j;           

        for(i=n;i>0;i--)

           for(j=0;j<15;j++)
            ;         

}                                        

//////////////////////////////////////
//////////////////////////坐标//////////////////////////////
void GotoXY(unsigned char x, unsigned char y)
{
 uchar address;

     if(y==0)

              address="0x80"+x;

     else

              address="0xc0"+x;

     LCD_write_command(address);
}

//将字符输出到液晶显示
void Printx(uchar x, uchar y,unsigned char *str)

    GotoXY(x,y);
 while(*str!='\0')
 
  { LCD_write_data(*str);
  
 str++;
  }  

}

/////////////////////////////////////////////////////////////////////////状态///////////////////////////////////////////////////////////////////////////////
void State0()
{     
   Printx(0,0,"time            ");
   Printx(0,1,"                ");
   delay_n40us(1000); 
}

void State1()
{      
 Printx(0,0,"tempalarm       ");
 Printx(0,1,"                ");
  delay_n40us(1000);
 
}

void State2()

  Printx(0,0,"timealarmrange  ");
  Printx(0,1,"                ");
  delay_n40us(1000);
 
  
}

void State3()

    Printx(0,0,"1:timeset     in");
 Printx(0,1,"2:timalarm      ");
 delay_n40us(2000);
}

void State4()

    Printx(0,0,"2:timalarm    in");
 Printx(0,1,"3:temalarm      ");
 delay_n40us(2000);

void State5()

   Printx(0,0,"3:temalarm    in");
   Printx(0,1,"4:kuozhan       ");
   delay_n40us(2000);
}

void State6()

   Printx(0,0,"4:kuozhan     in");
   Printx(0,1,"1:timeset       ");
   delay_n40us(2000);
}

void State7()
{   
  Printx(0,0,"jiztime         ");
  Printx(0,1,"                ");
  delay_n40us(2000);
}

void State8()

  Printx(0,0,"alarmtime       ");
  Printx(0,1,"                ");
  delay_n40us(1000);
}

void State9()

   Printx(0,0,"jizkuo          ");
   Printx(0,1,"                ");
    delay_n40us(1000);

void State10()
{
   Printx(0,0,"kuozhan         ");
   Printx(0,1,"                ");
    delay_n40us(1000);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/***********菜单操作函数*************/
void MenuOperate(uchar key)
{
     switch(key)
  {
      case  1:    //返回键
   {
      Func_Index=Menu_Tab[Func_Index].Gore;
      break;
   }

   case  2:    //右
   {
      Func_Index=Menu_Tab[Func_Index].Right;
      break;
   }

   case  3:    //Up键
   {
      Func_Index=Menu_Tab[Func_Index].Up;
      break;
   }

   case  4:    //下键
   {
      Func_Index=Menu_Tab[Func_Index].Down;
      break;
   }

   case  5:    //确定键
   {
      Func_Index=Menu_Tab[Func_Index].Enter;
      break;
   }

   case  6:       //左键
   {
      Func_Index=Menu_Tab[Func_Index].Left;
      break;
   }

   case  7:       //返回上一层键
   {
      Func_Index=Menu_Tab[Func_Index].Goback1;
      break;
   }

  // case  8:       //扩展键
  // {
  //    Func_Index1=Menu_Tab[Func_Index].Kuozhang;
  //    break;
  // }
   
  }

    
   Func_Ptr=Menu_Tab[Func_Index].Operate; //执行当前操作
    
  (*Func_Ptr)();
          
}
//////////////////////////////////键盘扫描////////////////////
void keyscan()
{
  if(k1==0)
    {delay_n40us(1000);
   if(k1==0)
   {
     key=1;
   }
 }
   if(k2==0)
    {delay_n40us(1000);
   if(k2==0)
   {
     key=2;
   }
 }
   if(k3==0)
    {delay_n40us(1000);
   if(k3==0)
   {
     key=3;
   }
 }
   if(k4==0)
    {delay_n40us(1000);
   if(k4==0)
   {
     key=4;
   }
 }
     if(k5==0)
    {delay_n40us(1000);
   if(k5==0)
   {
     key=5;
   }
 }
   if(k6==0)
    {delay_n40us(1000);
   if(k6==0)
   {
     key=6;
   }
 }
   if(k7==0)
   {delay_n40us(1000);
   if(k7==0)
   {
     key=7;
   }
 }
   if(k8==0)
   {delay_n40us(1000);
   if(k8==0)
   {
     key=8;
   }
 }
 
}

 

//////////////////////主函数////////////////////////
void main()
{   
   
  LCD_init();
 
  Printx(0,0,"welcome to");
  Printx(2,1,"jizzll'bolg");
  delay_n40us(100000);

    
  MenuOperate(0);
 
  while(1)
  {   
  keyscan();  
  MenuOperate(key);
  key="0";
  }

}

系统分类: 单片机
用户分类: 单片机
标签: 无标签
来源: 原创
发表评论 阅读全文(125) | 回复(4)
总共 , 当前 /