zcllom 发表于 2008-12-12 13:19:24

再挖一个仿真+两条有价值回复献给此地:单片机+LCD显示菜单(C源程序+proteus仿真) (众

http://cache.amobbs.com/bbs_upload782111/files_11/ourdev_539717.JPG

 (原文件名:ourmenu.JPG) 

zcllom 发表于 2008-12-12 13:23:30

先把原帖原话发出来,免得大家又要去注册,又要回复,忙的不亦乐乎。

完整的源代码+proteus仿真随后传上来

一个简单却实用的菜单程序



如果编写简单的程序的话这个菜单函数就可以不用看了,但是当你编写到复杂的程序的时候就可能就会为人机界面和各个函数直接的连接而烦恼了,这个菜单函数就是用来解决这个问题,虽然没有UCGUI厉害,但是我觉得代码在2000行一下的话用起来还是不错的选择的.虽说简单但是用到了结构体大部分的知识了,希望c语言不太好的朋友自己补习一下好了.



主要程序:



CODE:



#define Null 0





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

* 函数声明 * 

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

void ShowMenu(void);

void Menu_Change(unsigned char KeyNum);



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

* 按键功能键宏定义 * 

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

#define UP     '3'

#define Down '7'

#define Esc   'B'

#define Enter 'F'

#define Reset '0'





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

* 目录结构体定义 * 

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

struct MenuItem

{ 

unsigned char MenuCount;   //当前层节点数

unsigned char *DisplayString; //菜单标题

void (*Subs)();     //节点函数

struct MenuItem *ChildrenMenus; //子节点

struct MenuItem *ParentMenus; //父节点

}; 



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

* 调用子函数区 * 

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

void NullSubs(void) 

{ 

}

//----------------------以下为例子,请根据实际情况修改---------------------------



void TimeSet(void)

{

put_s("TimeSet");

}



void DateSet(void)

{

put_s("DateSet");

}



void AlertSet (void)

{

put_s("AlertSet");

}

//------------------------------------------------------------------------------

zcllom 发表于 2008-12-12 13:24:28

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

* 结构体区 * 

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

//----------------------以下为例子,请根据实际情况修改---------------------------

struct MenuItem TimeMenu;

struct MenuItem FlashMenu;

struct MenuItem VoiceMenu;

struct MenuItem RobotMenu;

struct MenuItem MainMenu;



struct MenuItem TimeMenu=

{ //MenuCount   DisplayString   Subs   ChildrenMenus ParentMenus

{4,   "1.Time Set",   TimeSet,   Null,   MainMenu},

{4,   "2.Date Set",   DateSet,   Null,   MainMenu},

{4,   "3.AlertSet",   AlertSet,   Null,   MainMenu},

{4,     "4.Back",     NullSubs,   MainMenu,   MainMenu},

}; 



struct MenuItem FlashMenu=

{ //MenuCount   DisplayString   Subs   ChildrenMenus ParentMenus

{5,   "1.Flash Record",   NullSubs,   Null,   MainMenu},

{5,   "2.Play",     NullSubs,   Null,   MainMenu},

{5,   "3.Pause",     NullSubs,   Null,   MainMenu},

{5,     "4.Flash Delete",   NullSubs,   Null,   MainMenu},

{5,   "5.Back",   NullSubs,   MainMenu,   MainMenu},

}; 



struct MenuItem VoiceMenu=

{ //MenuCount   DisplayString   Subs   ChildrenMenus ParentMenus

{5,   "1.Voice Record" , NullSubs,   Null,   MainMenu},

{5,   "2.Play",     NullSubs,   Null,   MainMenu},

{5,   "3.Pause",       NullSubs,   Null,   MainMenu},

{5,     "4.Voice Delete",   NullSubs,   Null,   MainMenu},

  {5,   "5.Back",   NullSubs,   MainMenu,   MainMenu},

}; 



struct MenuItem RobotMenu=

{ //MenuCount   DisplayString   Subs   ChildrenMenus ParentMenus

{5,   "1.Turn Left",   NullSubs,   Null,   MainMenu},

{5,   "2.Turn Right",   NullSubs,   Null,   MainMenu},

{5,   "3.Go Ahead",   NullSubs,   Null,   MainMenu},

{5,     "4.Go Back",   NullSubs,   Null,   MainMenu},

{5,   "5.Back",   NullSubs,   MainMenu,   MainMenu},

}; 





struct MenuItem MainMenu=

{ //MenuCount   DisplayString   Subs   ChildrenMenus ParentMenus

{5,   "1.Time Set" ,   NullSubs,   TimeMenu,   Null},

{5,   "2.Voice Center",   NullSubs,   VoiceMenu,   Null},

{5,   "3.Robot Control",   NullSubs,   RobotMenu,   Null},

{5,     "4.Flash Option",   NullSubs,   FlashMenu,   Null},

  {5,   "5.Back",   NullSubs,   MainMenu,   MainMenu},

}; 

//------------------------------------------------------------------------------

zcllom 发表于 2008-12-12 13:24:57

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

* 全局变量声明区 * 

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

struct MenuItem (*MenuPoint) = MainMenu; //结构体指针,指向结构体后由内部函数指针指向功能函数

unsigned char DisplayStart = 0; //显示时的第一个菜单项

unsigned char UserChoose = 0;   //用户所选菜单项

unsigned char DisplayPoint = 0; //显示指针

unsigned MaxItems;       //同级最大菜单数

unsigned char ShowCount=2; //同屏显示菜单数





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

*显示函数区 * 

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

void ShowMenu(void) 

{

  unsigned char n;

MaxItems = MenuPoint.MenuCount;//定义最大同级菜单

DisplayPoint = DisplayStart;

for(n=0;DisplayPoint<MaxItems&&n<ShowCount;n++) 

  {if(DisplayPoint==UserChoose)

  LCD_write_string(0,n,"->");

  LCD_write_string(2,n,MenuPoint.DisplayString);

  

  }



}



void Menu_Change(unsigned char KeyNum)

{

if(KeyNum)

{

  switch(KeyNum) 

  {     

      case UP: 

    UserChoose --; 

    if (UserChoose ==255)

    { 

      UserChoose = 0;//上翻截至,如果要回滚赋值MaxItems-1

    } 

    break; 

    case Esc: 

    if (MenuPoint.ParentMenus != Null) 

    { 

      MenuPoint = MenuPoint.ParentMenus; 

    UserChoose = 0; 

    DisplayStart = 0; 

    } 

    break; 

    case Down: 

    UserChoose ++; 

    if (UserChoose == MaxItems) 

    { 

      UserChoose = MaxItems-1;//下翻截至,如要回滚赋值为0 

    } 

    break; 

    case Enter: 

    if (MenuPoint.Subs != NullSubs) 

    { 

      (*MenuPoint.Subs)(); 

    } 

    else if (MenuPoint.ChildrenMenus != Null) 

    { 

      MenuPoint = MenuPoint.ChildrenMenus; 

      UserChoose = 0; 

      DisplayStart = 0; 

    } 

    break; 

    case Reset: 

      MenuPoint = MainMenu; 

    UserChoose = 0; 

    DisplayStart = 0; 

    break; 

    default:break;

  }

  if (UserChoose%ShowCount==0)       //一屏只能显示ShowCount行

  DisplayStart = UserChoose;

  else if(UserChoose==1||UserChoose== 3)

    DisplayStart = UserChoose-1;   //实现滚屏的关键   

  LCD_write_command(0x01);     //液晶清屏,根据不同液晶函数自行修改

  delay_nms(5);       //液晶为慢速器件

  ShowMenu(); 

}

}

bad_fpga 发表于 2008-12-12 13:27:07

睡醒顶一下

zcllom 发表于 2008-12-12 13:28:04

再来把那两条MVP回复发出来,不知道为什么,那位版版只顾着把资料发上来,对后面的回复却没有作答



回复之一:

工程里的KEY.H有逻辑错误,我看到的是

unsigned char get_key(void)

{

   unsigned char i;

   static unsigned char j;//按键记录

   

   i=key_read();

   if(i==0x00)    //无有效按键按下

   {

       j=0x00;    //清除按键记录

       return 0x00; //程序退出

   }

   if(j==0) //为新按键

   {    

       j=i;    //保存本次结果

       delay_nms(10); //延时去抖动

       i=key_read();

       if(i==j)

           return i;

   }

   return 0x00;

}



修改一下



unsigned char get_key(void)

{

   unsigned char i;

   static unsigned char j;//按键记录

   

   i=key_read();

   if(i==0x00)    //无有效按键按下

   {

       j=0x00;    //清除按键记录

       return 0x00; //程序退出

   }

   if(j!=i) //为新按键

   {    

       j=i;    //保存本次结果

       delay_nms(10); //延时去抖动

       i=key_read();

       if(i==j)

           return i;

   }

   return 0x00;

}



这样就行了

zcllom 发表于 2008-12-12 13:31:23

回复之二:



试过了,很好用。先谢了!

不过!!!

问题来了,一个指针在ICC中貌似没有办法设为空指针,一个函数指针也没法设置为空?



还有个问题,对于结构体数组的初始化来说,在定义时初始化最方便,直接把一大堆数据和指针赋值就好。可是,我在第一个主菜单的初始化中要用到在下面定义的结构体,于是,我把下面结构体的定义放到了上面,可是同时这个结构体又得用到主菜单这个结构体...于是初始化出问题了...

像这种初始化时需要相互指来指去的结构体初始化很麻烦啊!?

===================================================================

这个问题,我也想请教一下ourAVR里的高人,呵呵。



好了,这里先把完整程序+Proteus仿真传上来:



点击此处下载 ourdev_539737.rar(文件大小:97K) (原文件名:menu.rar)



本程序,支持滚屏,同级任意多任务,非树形菜单结构.

zcllom 发表于 2008-12-12 13:33:10

看来大家都午休了,自己顶一下

abcdezh 发表于 2008-12-12 13:43:30

顶顶

sol84 发表于 2008-12-12 16:01:39

mark

eduhf_123 发表于 2008-12-12 22:42:38

MARK

wisebaby 发表于 2008-12-30 09:57:22

MARK.

yxyaf 发表于 2009-1-3 20:19:12

下了,谢谢了

zlf777zhao 发表于 2009-1-5 11:54:31

不错

ivws 发表于 2009-1-5 12:03:32

不错

zsenbao 发表于 2009-1-6 11:43:21

不错,顶一下

pk666666 发表于 2009-1-9 20:57:28

帮顶

laotong 发表于 2009-3-4 07:43:37

mark

wajlh 发表于 2009-3-4 10:45:58

make

jishanlaike 发表于 2009-3-5 10:00:52

拜读了lz的大文,收获不小

但我对本文中.c和.h文件的组织感到有些疑惑不解。

书上说:
      .h文件应该包含:宏定义,函数声明等
      还要加上#ifndef~~~~~防止重定义
可本文中,.h文件中却有函数定义,而且函数声明也没有#ifndef~~~~~~~~`
这种组织结构合适吗???

还有一点:
    菜单返回时,没有返回到原来选中的父菜单,能够在结构体中的“共享区”(也就是每个结构体的第一个元素)设置标志,以供返回,否则都设成本机菜单数,有些浪费
第三点疑问:
    lz的“空结构体”使用null代替,而nullsubs这个空函数能否也省去定义,也用null呢??
我对c的比较少,

不要见笑~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~

hibond 发表于 2009-3-5 11:53:54

好像以前有人在论坛发过类似的东东
菜单数组是不是应该存在flash里?

cgbabc 发表于 2009-3-5 13:35:14

支持呀

yaohong200312 发表于 2009-3-5 20:09:59

正好想编一个菜单程序,参考一下先

jlw112 发表于 2009-3-5 21:58:17

记号

broadwood 发表于 2009-3-26 21:38:42

mark

hapzgc 发表于 2009-4-19 16:35:50

新手,学习了,慢慢研究

END12345678 发表于 2009-4-19 18:58:21

学习了,慢慢研究

dachun 发表于 2009-5-13 13:12:05

mark!

houzengmin 发表于 2009-5-13 22:17:47

mark!

GESHW 发表于 2009-5-15 09:01:56

mark!慢慢学习

iiset 发表于 2009-5-15 19:13:19

mark

hshl168 发表于 2009-5-17 09:38:42

lz好啊,这个菜单调用子函数后退步出来啊    请教怎么改!!!谢谢!!!

zsl602 发表于 2009-5-17 15:19:53

不错,可以好好学习一下。

longquan 发表于 2009-5-17 16:34:35

ding顶

seckuola 发表于 2009-5-17 19:35:55

MARK

ts10606 发表于 2009-5-17 20:37:34

mark

dongdaxing 发表于 2009-5-17 21:27:25

不顶不行

elecfun 发表于 2009-5-17 21:52:57

的确,不顶不行

xczxwy 发表于 2009-5-17 22:58:08

深夜轻轻地顶一下~~

feiyang007 发表于 2009-5-18 00:06:05

早上好!!顶一个

weimenlove 发表于 2009-5-19 11:43:28

Mark

mojinpan 发表于 2009-5-19 12:51:29

无意中看到这个帖子感觉很眼熟,后来才发现这个是我写的程序,抱歉,写得非常不好,这是07年6月单片机刚入门的时候和伙伴一起写的,当时是参照傻孩子的程序思路写的,不过还是写的比较差。我现在指出一下上面的不足之处:
1:如 19楼 jishanlaike所说的头文件应该是只声明不定义的,当时写的程序太少,没有注意到这点,
2:key.h这个函数写的不好,如果现在让我再写我肯定是用状态机来写了,还有,里面的那个10ms的延时是绝对不允许的,非常大的浪费,而且和实际的应用或者液晶等其他器件显示器件打架。不过值得说明的是,这个key.h功能是没有错的,后面那部分是为了实现按键锁定(长按时单次返回)和去抖动用的,比较不好理解,大家多看几次就明白了。
3:结构体写的有点啰嗦了,其实种菜单函数只要记录以下几个关键点就可以了:层数,同层最大条目数,当前条目数。
4:程序写得可移植性差了写,应该把驱动层和应用层区分开来,并定义好API接口,这样才方便复用,重复利用才是这个菜单的真正目的。
大概的构思如下:
应用层----------》具体项目需要用的功能,比如温度的采集,距离的测试结果处理等等
|
|
|
系统应用层:菜单函数,绘图函数,汉字处理函数,延时处理函数,按键处理函数,液晶处理函数等等,一些公用的,基本的应用。
|
|
|
底层驱动层:按键扫描函数,液晶驱动函数,串口驱动函数,IIC驱动函数等,这些都是和硬件直接大交道的函数了。

如果项目比较大的,可以考虑加入操作系统,那么整个结构就应该是:应用层----系统应用层----系统层----底层驱动层

现在工作比较忙了,暂时没有时间写这样的程序了,如果有的话我想再次写的时候会比这个好很多很多,^_^

vv3g 发表于 2009-6-13 23:55:40

关于菜单的真不错,呵呵

vv3g 发表于 2009-6-14 12:27:11

我借宝地为论坛做那么九九牛一毛贡献,这个key.h,在某个按键一直按下去的时候,只执行一次,若要某个按键一直按下去连续执行某个动作的话可以这样:
unsigned char get_key(void)
{
   unsigned char i;
   static unsigned char j;//按键记录
   
   i=key_read();
   if(i==0x00)    //无有效按键按下
   {
       j=0x00;    //清除按键记录
       return 0x00; //程序退出
   }
   //if(j!=i) //为新按键
   else//只要是有效按键
   {   
       j=i;    //保存本次结果
       //delay_nms(10); //延时去抖动
       delay_nms(100); //延时加长一点
       i=key_read();
       if(i==j)
         return i;
   }
   return 0x00;
}
这个论坛太好了,我在别的论坛从来不发言的,呵呵

fq1888 发表于 2009-8-31 00:20:10

Mark,好帖~!

snail0204 发表于 2009-8-31 08:12:26

mark

ksniper 发表于 2009-9-3 10:39:34

这个要好好研究下

dragonantao 发表于 2009-9-4 13:45:31

太强大了!!什么时候我才能达到那水平啊!

584388726 发表于 2009-9-15 20:59:24

正在学习液晶,谢了

ztrdiydz 发表于 2009-9-18 18:52:30

这个要好好研究下

fy024 发表于 2009-9-19 10:18:40

mark

cgbabc 发表于 2009-9-19 10:27:45

学习

cgbabc 发表于 2009-9-19 10:35:54

支持

yanrz 发表于 2009-9-26 21:54:33

不错,学习了!呵呵,哪天有空也玩玩才行!

mayitbey 发表于 2009-9-27 16:14:48

学习了,很不错的例子,谢谢分享,等我的这个搞好,也和大家交流一下,呵呵。

lffpga 发表于 2009-10-12 23:05:52

学习,谢谢。

yzlyear 发表于 2009-10-16 10:40:52

学习

jiangyimfs 发表于 2009-10-25 19:56:20

学习一下。。。。

pidaneng 发表于 2009-11-6 22:12:04

学习了,慢慢研究

maxiao5231 发表于 2009-11-6 22:19:00

mark

richey07 发表于 2009-11-12 23:50:21

mark

kele2009 发表于 2009-12-10 18:24:09

make

arduino 发表于 2009-12-10 18:26:31

不错

start00 发表于 2009-12-10 19:29:35

谢谢

stefgq 发表于 2009-12-10 22:26:25

学习

zhangzheyuanxp 发表于 2009-12-28 21:26:56

谢谢

wanglihang 发表于 2009-12-30 20:08:35

好好,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

wuxinping 发表于 2010-2-9 11:55:41

回复【5楼】zcllom 星罗棋布
-----------------------------------------------------------------------

THANKS VERY MUCH !

jiangping_hbhm 发表于 2010-2-12 13:19:24

mark

daylittle 发表于 2010-3-9 17:28:44

回复【3楼】zcllom 星罗棋布
-----------------------------------------------------------------------

不错,我正在找此方面的资料

magicom 发表于 2010-3-9 17:35:05

回复【楼主位】zcllom 星罗棋布
-----------------------------------------------------------------------

先下来看看

daylittle 发表于 2010-3-11 15:35:56

回复【楼主位】zcllom 星罗棋布
-----------------------------------------------------------------------

我也刚刚自己参照着别人的程序编写了一个用PROTEUS仿真的LCD12864显示的程序,只有显示功能没有按键

daylittle 发表于 2010-3-11 15:46:30

回复【楼主位】zcllom 星罗棋布
-----------------------------------------------------------------------
源程序如下:
/***********************
端口定义如下:
PD为数据端口
PC1控制CS1(left)
PC2控制CS2
PC3控制RS
PC4控制RW
PC5控制E
PC6控制RST(复位端口)
*************************/
#include<iom16v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
/*******命令字定义*************/
#define Disp_On 0x3f
#define Disp_Off0x3e
#define Col_Add0x40
#define Page_Add0xb8
#define Start_Line 0xc0
#pragma data:code
const uchar nan[]={
/*-------南---------*/
/*------- 宋体12;此字体下对应的点阵为:宽x高=16x16------*/
0x14,0x24,0x44,0x84,0x64,0x1C,0x20,0x18,0x0F,0xE8,0x08,0x08,0x28,0x18,0x08,0x00,
0x20,0x10,0x4C,0x43,0x43,0x2C,0x20,0x10,0x0C,0x03,0x06,0x18,0x30,0x60,0x20,0x00



};

/*************************
1、 函数功能:时间延时函数
    入口参数:ms
    出口参数:
*************************/
void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
   for(j=0;j<1141;j++);
}

/*******************
2、函数功能:写命令
   入口参数:cmd
   出口参数:
*********************/
void write_com(uchar cmd)
{
PORTC&=~BIT(3);//RS=0
PORTC&=~BIT(4);//RW=0
PORTD=cmd;
delay(1);
PORTC|=BIT(5);//E=1
delay(1);
PORTC&=~BIT(5);//E=0
}
/*************************
3、函数功能:写数据
   入口参数:dat
   出口参数:
************************/
void write_dat(uchar dat)
{
PORTC|=BIT(3);//RS=1
PORTC&=~BIT(4);//RW=0
PORTD=dat;
delay(1);
PORTC|=BIT(5);//E=1
delay(1);
PORTC&=~BIT(5);//E=0
}
/**********************
4、函数功能:清除LCD内存程序
    入口参数:pag,col,hz
    出口参数:
***********************/
void clr_scr()
{
   uchar j,k;
   PORTC|=BIT(1);//CS=1,开右半屏
   PORTC|=BIT(2);//cs=2,开左半屏
   write_com(Page_Add+0);
   write_com(Col_Add+0);
   for(k=0;k<8;k++)
   {
    write_com(Page_Add+k);
        for(j=0;j<64;j++)
          write_dat(0x00);
   }
   PORTC&=~BIT(1);//CS1=0
   PORTC&=~BIT(2);//CS2=0
}
/**********************************
5、 函数功能:指定位置显示16*16的程序
    入口参数:pag,col,hz
    出口参数:
************************************/
void hz_disp16(uchar pag,uchar col,const uchar *hz)
{
uchar j=0,i=0;
for(j=0;j<2;j++)
    {
       write_com(Page_Add+pag+j);
       write_com(Col_Add+col);
       for(i=0;i<16;i++)
             write_dat(hz);
        }
}
/*************************************
6、函数功能:指定位置显示8*16的程序
    入口参数:pag,col,hz
    出口参数:
***************************************/
void hz_disp8(uchar pag,uchar col,const uchar *hz)
{
uchar j=0,i=0;
for(j=0;j<2;j++)
    {
       write_com(Page_Add+pag+j);
       write_com(Col_Add+col);
       for(i=0;i<8;i++)
             write_dat(hz);
        }
}
/*******************************************
7、函数功能:LCD初始化程序
    入口参数:
        出口参数:
**********************************************/
void init_lcd()
{
delay(10);
PORTC&=~BIT(1);
PORTC&=~BIT(2);
delay(1);
write_com(Disp_Off);
write_com(Page_Add+0);
write_com(Start_Line+0);
write_com(Col_Add+0);
write_com(Disp_On);
}
void main()
{
DDRD=0XFF;
DDRC|=BIT(1);//PC从1~6均设为输入
DDRC|=BIT(2);
DDRC|=BIT(3);
DDRC|=BIT(4);
DDRC|=BIT(5);
DDRC|=BIT(6);
PORTD=0XFF;
PORTC=0XFF;

init_lcd();
clr_scr();
PORTC|=BIT(1);
PORTC&=~BIT(2);
while(1)
{
PORTC|=BIT(2);
PORTC&=~BIT(1);
delay(1);
hz_disp16(2,32,nan);
delay(2);
}

}

daylittle 发表于 2010-3-11 15:49:15

喜欢显示什么字可以在自已设置

daylittle 发表于 2010-3-11 15:51:14

本人刚刚学习,感觉楼主的程序看着有点麻烦

daylittle 发表于 2010-3-11 15:52:16

本来想把原理图给贴上去 可怎么也不能粘贴成功!

daylittle 发表于 2010-3-11 15:54:33

请注意本人使用的是ATMEGA16而不是89C51

chahu1227 发表于 2010-4-22 15:17:25

mark

hongyancl 发表于 2010-4-22 15:19:43

回复【楼主位】zcllom 星罗棋布
-----------------------------------------------------------------------

ddddddddd

flypig8321 发表于 2010-4-25 20:29:44

下了,谢谢了

aqibluesky 发表于 2010-6-1 13:49:39

学习一下结构体~~~~~~~~~

wanglituan 发表于 2010-6-2 00:03:10

谢谢

491739176 发表于 2010-6-4 10:37:23

非常好,谢谢

Gloriousle 发表于 2010-11-30 12:15:02

mark

pch888 发表于 2010-12-4 13:15:05

mark

zxs2000 发表于 2010-12-4 17:05:46

学习

lzrcm89 发表于 2010-12-4 19:34:03

学习了./emotion/em003.gif

ljt8015 发表于 2010-12-4 21:04:24

仿真文件呢?

shzdxx 发表于 2010-12-4 22:20:34

mark

love_zjb 发表于 2010-12-4 22:57:13

mark

boyazy 发表于 2010-12-5 00:13:01

mark

keilc 发表于 2011-3-8 10:11:39

mark!!!!!!!!!!!!!!

cumtgao 发表于 2011-3-10 08:30:29

ding!!!!!!!!!!!!!!!!

ljt8015 发表于 2011-3-10 08:44:55

mark!~

xintaisniper 发表于 2011-3-10 09:23:20

太好啦,又学了不少东西

bbsview 发表于 2011-3-10 15:23:26

好资料,收藏先

unic 发表于 2011-3-10 16:08:47

mark

522yt 发表于 2011-3-20 23:23:21

顶一下,不过结构体应该放入flash区。不然。占内存太大。

nbc327 发表于 2011-3-27 01:22:05

看看!

jadeyang 发表于 2011-3-29 20:47:29

mark
页: [1] 2
查看完整版本: 再挖一个仿真+两条有价值回复献给此地:单片机+LCD显示菜单(C源程序+proteus仿真) (众