jay054 发表于 2009-10-29 23:14:01

一个关于菜单的程序

#include <reg52.h>
#include <intrins.h>
void (*current_operation_index)();//
#define uchar unsigned char
#define uint unsigned int
uchar code datas1[] = {"彭勋"};
uchar code datas2[] = {"马鹏辉"};
uchar code datas3[] = {"河南"};
uchar code datas4[] = {"湘潭"};
uchar code datas5[] = {"返回"};
uchar code datas6[] = {"湖工"};
uchar code datas7[] = {"请稍等"};
uchar func_index;
unsigned char k;
unsigned char keycodetable[]={0xee,0xde,0xbe,0x7e,
         0xed,0xdd,0xbd,0x7d,
         0xeb,0xdb,0xbb,0x7b};
int i;
sbit dula = P2^6;
sbit wela = P2^7;
//SCM12864-05端口定义
#define LCD_DATA P0 //数据口
sbit RS = P3^5; //并行的指令/数据选择信号, H数据, L命令
sbit RW = P3^6; //并行读写选择信号, H读, L写
sbit E = P3^4; //并行使能端, H有效, L无效
sbit PSB = P3^7; //并/串接口选择, H并,L串
sbit RET = P3^3; //复位, L有效
///12864读写和初始化////////
//延时约2us
void delayUs()
{
    _nop_();_nop_();
}
//延时 a * 1ms
void delayMs(uint a)
{
    uint i, j;
    for(i = a; i > 0; i--)
      for(j = 100; j > 0; j--);
}
//检测LCD是否处于忙状态, 若忙返回1, 空闲返回0
bit checkBusy()
{
    bit busy;
    RS = 0;
    RW = 1;
    E = 1;
    delayUs();
    busy = (bit)(LCD_DATA&0x80);
    E = 0;
    return busy;
}
//等待LCD到空闲
void wait()
{
    while(checkBusy());
}
//写命令
void WriteCmd(uchar cmd)
{
    wait();
    RS = 0;
    RW = 0;
    E = 0;
    delayUs();
    LCD_DATA = cmd;
    delayUs();
    E = 1;
    delayUs();
    E = 0;
}
//写数据
void WriteData(uchar dat)
{
    wait();
    RS = 1;
    RW = 0;
    E = 0;
    delayUs();
    LCD_DATA = dat;
    delayUs();
    E = 1;
    delayUs();
    E = 0;
}
//初始化LCD
void init()
{
    PSB = 1; //并口方式
    WriteCmd(0x30); //基本指令, 扩充指令为34H
    delayMs(10);
    WriteCmd(0x0c); //显示开, 关光标
    delayMs(10);
    WriteCmd(0x01); //清屏
    delayMs(10);
}
void WriteString(uchar * str)
{
    uchar i = 0;
    while(str != '\0')
    {
      WriteData(str);
    }
}
//////反白函数//////////////////////

//第一.三行反白,传递函数的不同
LcdFill_Leve1(uint c,uint d,uint e)
{ unsigned char x,y,a,b,ii;
   for(ii=0;ii<8;ii+=8)
      {for(y=0;y<0x10;y++)//行地址
      {for(x=0;x<8;x++)
            { //下刘行是使第一行反白
      WriteCmd(0x36); //扩充指令 绘图显示
               WriteCmd(y+0x80);    //行地址
               WriteCmd(x+0x80+ii);    //列地址
      WriteData(c);
      WriteData(c);
      WriteCmd(0x30); ///可以不要下两行,效果稍差
   //下刘行是使第三行不反白
       WriteCmd(0x36); //扩充指令 绘图显示
               WriteCmd(y+0x80);    //行地址
               WriteCmd(x+0x80+8);    //列地址
      WriteData(d);
      WriteData(d);
      WriteCmd(0x30);
    }
    }
   }
    //下面的三个for 是使2,4不反白
for(ii=0;ii<9;ii+=8)
   for(a=0x10;a<0x20;a++)
    for(b=0;b<8;b++)
      {
               WriteCmd(0x36); //扩充指令 绘图显示
               WriteCmd(a+0x80);    //行地址
               WriteCmd(b+0x80+ii);    //列地址
      WriteData(e);
      WriteData(e);
               WriteCmd(0x30);
      }
}

//第二.四行反白         
LcdFill_Leve2(uint k,uint j,uint h)
{ unsigned char x,y,a,b,ii;
   for(ii=0;ii<9;ii+=8)
   for(y=0;y<0x10;y++)//行地址
   for(x=0;x<8;x++)
            {
      WriteCmd(0x36); //扩充指令 绘图显示
               WriteCmd(y+0x80);    //行地址
               WriteCmd(x+0x80+ii);    //列地址
      WriteData(k);
      WriteData(k);
      WriteCmd(0x30);
       }
   for(ii=0;ii<8;ii+=8)
      for(a=0x10;a<0x20;a++)
      
      for(b=0;b<8;b++)
      {
      WriteCmd(0x36); //扩充指令 绘图显示
               WriteCmd(a+0x80);    //行地址
               WriteCmd(b+0x80+ii);    //列地址
      WriteData(j);
      WriteData(j);
      WriteCmd(0x30);
      WriteCmd(0x36); //扩充指令 绘图显示
               WriteCmd(a+0x80);    //行地址
               WriteCmd(b+0x88);    //列地址
      WriteData(h);
      WriteData(h);
      WriteCmd(0x30);
      }
}                     

/**************************************显示函数*****************************************/
void fun0()   
{
   void init();
   WriteCmd(0x80);
    WriteString(datas1);
   WriteCmd(0x90);
    WriteString(datas2);
   WriteCmd(0x88);
    WriteString(datas5);
   LcdFill_Leve1(0xff,0,0);
}
void fun1()   
{
    void init();
WriteCmd(0x01);
   WriteCmd(0x80);
    WriteString(datas6);
   WriteCmd(0x90);
   WriteString(datas4);
   WriteCmd(0x88);
    WriteString(datas5);
   LcdFill_Leve1(0xff,0,0);
}
void fun2()   
{
    void init();
WriteCmd(0x01);
   WriteCmd(0x80);
    WriteString(datas6);
   WriteCmd(0x90);
   WriteString(datas4);
   WriteCmd(0x88);
   WriteString(datas5);
   LcdFill_Leve2(0,0xff,0);
}void fun3()   
{
    void init();
WriteCmd(0x01);
   WriteCmd(0x80);
    WriteString(datas6);
   WriteCmd(0x90);
    WriteString(datas4);
   WriteCmd(0x88);
WriteString(datas5);
   LcdFill_Leve1(0,0xff,0);
}
void fun4()   
{
   void init();
   WriteCmd(0x01);
   WriteCmd(0x80);
    WriteString(datas1);
   WriteCmd(0x90);
    WriteString(datas2);
   WriteCmd(0x88);
   WriteString(datas5);
   LcdFill_Leve2(0,0xff,0);
}
void fun5()   
{
   void init();
   WriteCmd(0x01);
   WriteCmd(0x80);
    WriteString(datas6);
   WriteCmd(0x90);
    WriteString(datas3);
   WriteCmd(0x88);
    WriteString(datas5);
   LcdFill_Leve1(0xff,0,0);
}
void fun6()   
{
void init();
WriteCmd(0x01);
   WriteCmd(0x80);
    WriteString(datas6);
   WriteCmd(0x90);
   WriteString(datas3);
   WriteCmd(0x88);
    WriteString(datas5);
   LcdFill_Leve2(0,0xff,0);
}
void fun7()   
{
    void init();
WriteCmd(0x01);
   WriteCmd(0x80);
    WriteString(datas6);
   WriteCmd(0x90);
   WriteString(datas3);
   WriteCmd(0x88);
    WriteString(datas5);
   LcdFill_Leve1(0,0xff,0);
}
void fun8()   
{
   void init();
   WriteCmd(0x01);
   WriteCmd(0x80);
    WriteString(datas1);
   WriteCmd(0x90);
    WriteString(datas2);
   WriteCmd(0x88);
    WriteString(datas5);
   LcdFill_Leve1(0,0xff,0);
}
void dengdai()
{
void init();
   WriteCmd(0x01);
   WriteCmd(0x90);
   WriteString(datas7);
   LcdFill_Leve1(0xff,0,0);
   delayMs(1000);
}
                  
typedef struct
   {
uchar current;
uchar up;
uchar down;
uchar enter;
void (*current_operation)();
} key_table;
key_table code table=
{
   {0,8,4,1,(*fun0)}, //0//第一层,显示[彭勋],马鹏辉,返回
{1,3,2,1,(*fun1)},//1-0按回车,进第二层,显示[湖工],湘潭,返回

{2,1,3,2,(*fun2)},//4-1向下,显示湖工,[湘潭],返回

{3,2,1,0,(*fun3)},//7-4向下,显示湖工,湘潭,[返回]
      
{4,0,8,5,(*fun4)},//12-0 >down>显示彭勋,[马鹏辉],返回
{5,7,6,5,(*fun5)},//13-12 >enter>[河南],湖工,返回

                        
{6,5,7,6,(*fun6)},//16-13 >down>河南,[湖工],返回
{7,6,5,4,(*fun7)},//19-16 >down>河南,湖工,[返回]

{8,4,0,8,(*fun8)},//22-19 >down>彭勋,马鹏辉,[返回]
                        
};
///----------------------------------
delay00(int x)
{
int i;
while(x--)
{
for(i=20;i>0;i--)
{};
}
}
//--------------------------------------------------
///-------------------------------------------
unsigned int readkey(void)
{ bit mark;
unsigned char keycode,key1;
P2=0XF0;
while(P2!=0XF0)
{ delay00(50);
    if(P2!=0XF0){key1=P2;
               P2=0X0F;
               keycode=key1|P2;
               P2=0Xf0;
               mark=1;
   }   
}
if(mark){for(i=0;i<12;i++)
   if(keycode==keycodetable)return (i);
   
       }
else return(0xff);
}
void main(void)
{ void init();
   while(1)
{

               
/*******************find index****************************/
switch(readkey())
{
case 0x1:
   func_index=table.up;    //向上翻
   break;
case 0x5:
             dengdai();
             func_index=table.enter;//回车
   WriteCmd(0x01);
   break;
case 0x9:
   func_index=table.down;//向下翻
   break;
default:   
   break;
         }
      
            

      current_operation_index=table.current_operation;
   
   (*current_operation_index)();//执行当前操作函数
}
}

jay054 发表于 2009-10-29 23:17:27

这个程序是在网上找到的,但一直看不懂.请哪位高手看一下.帮忙看一下.


{0,8,4,1,(*fun0)}, //0//第一层,显示[彭勋],马鹏辉,返回
{1,3,2,1,(*fun1)},//1-0按回车,进第二层,显示[湖工],湘潭,返回

{2,1,3,2,(*fun2)},//4-1向下,显示湖工,[湘潭],返回

{3,2,1,0,(*fun3)},//7-4向下,显示湖工,湘潭,[返回]
      
{4,0,8,5,(*fun4)},//12-0 >down>显示彭勋,[马鹏辉],返回
{5,7,6,5,(*fun5)},//13-12 >enter>[河南],湖工,返回

                        
{6,5,7,6,(*fun6)},//16-13 >down>河南,[湖工],返回
{7,6,5,4,(*fun7)},//19-16 >down>河南,湖工,[返回]

{8,4,0,8,(*fun8)},//22-19 >down>彭勋,马鹏辉,[返回]

这些是什么意思啊,程序是怎么走的啊.主程序里也看不懂.希望高手们能看看,帮忙说一下,谢谢了

jay054 发表于 2009-10-31 10:37:55

今天终于看懂了.只要看前面的序号就行了.

kongjie07 发表于 2010-11-25 22:54:21

顶!

liaogang1314 发表于 2010-11-26 08:29:39

这个代码不行的 每移动一下都是整屏刷新!

tangshanqiang 发表于 2010-11-26 08:49:43

楼上发一个吧,我也想做一个呢

haydon123 发表于 2011-4-21 18:55:54

代码不行也顶

cumtgao 发表于 2011-5-12 14:00:42

看看

ARMXIN 发表于 2011-5-12 14:09:07

不会先标记

cumtgao 发表于 2011-5-13 10:10:42

晕 代码好像有问题。。。。

wang_2008 发表于 2012-2-28 17:38:59

M
页: [1]
查看完整版本: 一个关于菜单的程序