kingsor120 发表于 2012-12-20 21:37:21

请教"傻孩子“菜单问题

AVR自学中,请教个菜单问题,谢谢~
我打算做一个智能闹钟,预计三层菜单。主页面显示时间,温度什么的。
最后一层为闹钟,时间,温度报警什么的调节用的
以前用普通的函数写过一次感觉写的太复杂不好改动,现在想按照你的菜单模式写个,最近看了几天你写的菜单,在这想请教你几个问题
1:最后的菜单,比如调整时间的函数里面我要用到这几个按键调整时间,怎样和控制菜单进出的功能分开呢?想用WHILE和BREAK控制可以不?
2:我以前做的闹钟只有时间,现在想加上星期设定,比如只星期1,3,5闹钟开这个能否提供个思路?
3:我看里面菜单的介绍最开始进去程序的时候都是菜单页面,我要开机固定显示时间页面,按下确定后进入菜单控制,这个按键一个咋样进入呢?感觉把固定显示页面作为最上层菜单好像不行,
是否可以用WHILE显示时间页面判断确定按键来调用菜单选择函数呢?

以上,谢谢~

kingsor120 发表于 2012-12-20 21:41:16

l另外请教我用的是19264的屏
struct MenuItem
{
unsigned char MenuCount;                 //当前层节点数
unsigned char *DisplayString;         //菜单标题
void (*Subs)();                                   //节点函数
struct MenuItem *ChildrenMenus; //子节点
struct MenuItem *ParentMenus;         //父节点
};
显示菜单要用中文的,我单独写了显示菜单一列的函数后unsigned char *DisplayString;         //菜单标题
这里应该怎样调用呢?这个指针怎样调用到菜单中显示的这一列呢

HeP028 发表于 2012-12-20 22:41:02

void DisplayMenu(void)
{
       unsigned char i = 0x00;
       MaxItems = MenuPoint.MenuConut;
       DisplayPoint = DisplayStart;
       
       for(i = 0;((i < LCDMaxdisplayLine) && (DisplayPoint < MaxItems);i++)
       {
                     if (DisplayPoint == UserChoose)
                   {
                             LCDWriteoneChar(0,i,0x7e);
                   }
                   LCDWriteString(1,i,MenuPoint.DisplayString);
       }
}其实你只要看懂这个就知道什么调用了。
我也在弄这个东西,不过不名原因的报错,以前用51抑制过,但是奈何51的RAM太小,把结构体什么的都放在ROM1操作就跑飞了。
刚接触AVR。不知道是不是规则什么问题,老报错的

Gorgon_Meducer 发表于 2012-12-21 18:06:37

HeP028 发表于 2012-12-20 22:41 static/image/common/back.gif
其实你只要看懂这个就知道什么调用了。
我也在弄这个东西,不过不名原因的报错,以前用51抑制过,但是奈何5 ...

具体什么错误?

Gorgon_Meducer 发表于 2012-12-21 18:11:18

1、最后的菜单,比如调整时间的函数里面我要用到这几个按键调整时间,怎样和控制菜单进出的功能分开呢?想用WHILE和BREAK控制可以不?
-> 在Subs指向的处理函数里面做就可以了。可以用while和break实现。

2、我以前做的闹钟只有时间,现在想加上星期设定,比如只星期1,3,5闹钟开这个能否提供个思路?
-> 这个只是一个算法问题吧?闹钟的选项里面增加一个星期的byte,bit0~bit6表示星期1到星期天,bit7你自己留着用作特殊功能吧,比如表示临时有效和具体星期无关

3、我看里面菜单的介绍最开始进去程序的时候都是菜单页面,我要开机固定显示时间页面,按下确定后进入菜单控制,这个按键一个咋样进入呢?感觉把固定显示页面作为最上层菜单好像不行,
是否可以用WHILE显示时间页面判断确定按键来调用菜单选择函数呢?
-> 你的思路可行。

总结:你其实已经有解决方案的,要相信自己,不要迷信权威。

kingsor120 发表于 2012-12-21 22:52:26

Gorgon_Meducer 发表于 2012-12-21 18:11 static/image/common/back.gif
1、最后的菜单,比如调整时间的函数里面我要用到这几个按键调整时间,怎样和控制菜单进出的功能分开呢?想 ...

感谢回复

今天我把这个写出来了
用的WHILE控制时间显示,遇到ENTER进入菜单,能进入菜单主页面,但进去后按键不能用了,也退不出来

后来把主页面取消了只写了菜单,能正常操作,在最底层的SUBS中判断ESC后退出,但进去后老是延时,要按很多次靠运气才能退出哦(按键是中断判断的,应该无问题,别的程序能正常运行)
现在只是能进入最底层和退出、虽然有时候要按几下才能退出来),还不知道在里面其他按键能用不,有空在试下

星期的问题我也是这样想的,8个位,7个用来判断星期1-7的开关,最后一位用来控制闹钟总开关。开关,星期天,星期六。。。星期一(8位)
我现在是没好办法怎么拆分到屏上单个控制开关,以及后面咋样组合回去存到EEPROM里面去(这个有空的话就指点下吧,最主要还是问菜单的)

kingsor120 发表于 2012-12-21 22:55:36

HeP028 发表于 2012-12-20 22:41 static/image/common/back.gif
其实你只要看懂这个就知道什么调用了。
我也在弄这个东西,不过不名原因的报错,以前用51抑制过,但是奈何5 ...

菜单我基本看懂了
今天写出来3层菜单,进出都正常,但加上主页面后进出按键有问题,按键老是不能用,主页面进菜单后退不出来,按键失灵

Gorgon_Meducer 发表于 2012-12-22 01:06:46

kingsor120 发表于 2012-12-21 22:52 static/image/common/back.gif
感谢回复

今天我把这个写出来了


用键盘缓冲区可以彻底解决你这个问题。

kingsor120 发表于 2012-12-22 17:44:03

Gorgon_Meducer 发表于 2012-12-22 01:06 static/image/common/back.gif
用键盘缓冲区可以彻底解决你这个问题。

今天把设置星期的弄好了,没想的那么难,{:smile:}
键盘缓冲,,没用过
我用的马老师按键的状态机不知道能行不,改天看下怎么弄

在请教个问题
比如我设置的unsigned char   a;要求要在0,8之间变动,上面的简单大于8就等于0.,小位数怎么解决呢,如果小于0的时候等于8的话不行,应该会到255吧?
设置成无符号的应该可以用,但我所有的函数都是有符号的,请问这个能咋样解决呢

还有就是我用19264写的菜单,菜单项字数不统一现在要写个写字句函数,用的是把菜单内容取字模放在N个数组里。最后来判断写那个数组里的字,现在遇到个难题我判断不出来这个数组里有多少个字
我用的方法是一个字一个字往下些的循环,需要判断出来数组中包含几个字,今天试了用sizeof,/0来判断数组个数都失败。。。。。

Gorgon_Meducer 发表于 2012-12-22 23:02:49

本帖最后由 Gorgon_Meducer 于 2012-12-22 23:06 编辑

kingsor120 发表于 2012-12-22 17:44 static/image/common/back.gif
今天把设置星期的弄好了,没想的那么难,
键盘缓冲,,没用过
我用的马老师按键的状态机不知道 ...

1、马老师的按键状态机是用来做按键处理的,我说的键盘缓冲区是将处理获得的按键保存下来的,两回事。
2、在0~8之间取值?

a = (a % 9);
a = a < 0 ? (a + 9) : a;

3、最后一个问题完全不明白你在说什么。你用了只有你自己能明白的术语。

cumt_123456 发表于 2012-12-24 08:57:09

Gorgon_Meducer 发表于 2012-12-22 23:02 static/image/common/back.gif
1、马老师的按键状态机是用来做按键处理的,我说的键盘缓冲区是将处理获得的按键保存下来的,两回事。
2 ...

有个疑问,谢谢。

a = a < 0 ? (a + 9) : a;
这里为什么还需要判断a的正负呢?

Gorgon_Meducer 发表于 2012-12-24 13:55:03

cumt_123456 发表于 2012-12-24 08:57 static/image/common/back.gif
有个疑问,谢谢。

a = a < 0 ? (a + 9) : a;


如果a是有符号的数,比如-1,你试试看?

kingsor120 发表于 2012-12-24 17:56:18

Gorgon_Meducer 发表于 2012-12-22 23:02 static/image/common/back.gif
1、马老师的按键状态机是用来做按键处理的,我说的键盘缓冲区是将处理获得的按键保存下来的,两回事。
2 ...

我表达的不清楚吧,我最后问的就是
比如在一个菜单页面有3个菜单项:

调整时间    取字模后放在const unsigned char tzsj[]={.........}       一个4个字,数组内应该128个元素

取消          取字模后放在const unsigned char qx[]={.........}       一个2个字,数组内应该64个元素

主页面      取字模后放在const unsigned char zym[]={.........}       一个3个字,数组内应该96个元素

我现在要写一个总的函数 put1616(x坐标,y坐标,数组名),要求不管数组里是几个字都能用的,就是数组里有3个字就显示3个,4个字就显示4个
我在里面用了个for(i=0;i<x;i++)       x为数组内汉字的个数,比如写“调整时间”4个字,X=4循环4次,如果是3个字就循环写3次
我现在的困难就是给定一个数组我找不到办法判定里面有几个字

现在我菜单写好了,想的功能基本都能时间,主页面与菜单能正常进出,菜单下翻正常,但上翻的话到最顶层后在往上翻的话就会出现白屏(上面都不显示)最后我改成到最顶的菜单项后固定显示了

另外你说的用按键缓冲的我没做出来,我用的是建一个数组,有按键后就挨个放数组里面,最后掉出来,比如按下1,存放在数组中,最后掉出来的值就会一直是1,持续保持1的结果,请问这样才能按下1后只执行一次1的动作呢?   最后我换了个方式,虽然我所提到的按键延时的问题解决了,不过还想学下这个缓冲的,谢谢~



kingsor120 发表于 2012-12-24 17:58:55

Gorgon_Meducer 发表于 2012-12-24 13:55 static/image/common/back.gif
如果a是有符号的数,比如-1,你试试看?

现在我的问题是设置的是无符号的,因为我后面的函数什么的都是设置的无符号的。
我还是用的如果a<0,那么a=9,但达不到预期效果,我想应该是到0后在减就跑到255去了吧

Gorgon_Meducer 发表于 2012-12-24 22:56:58

kingsor120 发表于 2012-12-24 17:58 static/image/common/back.gif
现在我的问题是设置的是无符号的,因为我后面的函数什么的都是设置的无符号的。
我还是用的如果a ...

如果是无符号数,反而简单了,直接对针对0进行判断就可以了。比如要从a身上减去某一个数字,假设是b,
你可以先判断b是否比a大,如果大,则用(b-a)来获取结果,并对结果取余。

至于键盘缓冲区,你先学习一下队列这个数据结构,然后你就懂了。

Gorgon_Meducer 发表于 2012-12-24 23:11:15

kingsor120 发表于 2012-12-24 17:56 static/image/common/back.gif
我表达的不清楚吧,我最后问的就是
比如在一个菜单页面有3个菜单项:



至于put1616这个函数,我觉得你不必钻牛角尖,老老实实传递一个参数表示当前子模最大字数到put1616就可以了。
根据需要,你可以把这个信息保存在菜单结构里面——有一个经验希望你能早日体会到:
嵌入式系统是专用的计算机系统。这里专用是非常重要的,意味着你在嵌入式系统里面追求通用是不符合嵌入式系统
的基本初衷的——你能做到的是在不增加额外或过多成本(时间成本、人工成本、系统复杂度成本)的情况下在有需求
的场合在一定范围内实现通用。

说回这个例子,你也许可以将字模的最大字数保存到菜单结构中,这虽然会让你的代码略显不通用,但在你的应用范围
内是恰到好处的——因为你已经决定用“小字库”技术,而不是通用字库,所以,保存这个信息在菜单项结构或者菜单结构
中是适当的。

你可以简单的记住:嵌入式系统里面只有专用,和一定范围内的通用。而这个范围,一定是严格定义的。

cumt_123456 发表于 2012-12-24 23:20:53

Gorgon_Meducer 发表于 2012-12-24 13:55 static/image/common/back.gif
如果a是有符号的数,比如-1,你试试看?

我的C不好,也没验证。先求教,-1%9等于多少呢?(-1)%(-9)、1%(-9)呢?谢啦

Gorgon_Meducer 发表于 2012-12-24 23:44:24

cumt_123456 发表于 2012-12-24 23:20 static/image/common/back.gif
我的C不好,也没验证。先求教,-1%9等于多少呢?(-1)%(-9)、1%(-9)呢?谢啦 ...

http://www.amobbs.com/thread-5510725-1-1.html

kingsor120 发表于 2012-12-25 21:32:34

Gorgon_Meducer 发表于 2012-12-24 23:11 static/image/common/back.gif
至于put1616这个函数,我觉得你不必钻牛角尖,老老实实传递一个参数表示当前子模最大字数到put1616就可以 ...

你的意思是在字库后面加个字数定义吗?
就是比如   调整时间   ztsj[]={4 .............};用最前面的4表示该数组工有4个字,最后FOR循环中用4来限定该数组写4个字?

我以为能有办法直接判断出数组中有多少元素呢,我下了你的工程库里面有这句   sizeof(a)/sizeof(a)    请教这个的作用的是什么,?我以为是判断数组元素个数的,但我试了下对我的字库数组用这个最后结果是2 ? 现在就差这个问题解决我的预期效果就达成了。。。。。

我下你的工程模版里面打开工程后看到很多文件不全呢?比如12864.h什么的好多工程里面能看到,但实际文件夹里面没有C和H文件,请问是你没上传还是我下载的地址不对啊?
能否给个下载地址,谢谢~

Gorgon_Meducer 发表于 2012-12-25 21:46:20

kingsor120 发表于 2012-12-25 21:32 static/image/common/back.gif
你的意思是在字库后面加个字数定义吗?
就是比如   调整时间   ztsj[]={4 .............};用最前面的 ...

sizeof()在这个问题上是不起作用的。因为sizeof是一个伪运算符,它实际上在编译时刻将括号内所表示的元素
的大小转换成具体的常数——注意这个过程是发生在编译时刻而不是运行时刻,所以没有办法这么做。
我建议的修改方式是,在put1616这个函数增加一个参数。至于你如何组织小字库,是你自己设计的喜好问题。

kingsor120 发表于 2012-12-25 22:46:09

Gorgon_Meducer 发表于 2012-12-25 21:46 static/image/common/back.gif
sizeof()在这个问题上是不起作用的。因为sizeof是一个伪运算符,它实际上在编译时刻将括号内所表示的元素 ...

我歇这个函数的目的为为了配合你的菜单模板写的
是为了不管在那层菜单,菜单字数多少都能使用,如果函数中添加形参的话那调用的时候怎么加的进去呢
而且这个参数个项都不一样,那不是又得增加判断项目?

请指教
说道加参数我想起个问题:比如设置闹钟菜单里面我设置4个闹钟的话,函数内容应该都一样了唯一区别就是闹钟的时间存放位置不一样,比如我闹钟1存在EEPROM 中0X10开始的字节,闹钟2存0X20开始的位置。。。

最开始想的最笨的办法就是写4个函数分别调用,如果能解决你说的函数增加参数的话应该不错啊

Gorgon_Meducer 发表于 2012-12-25 23:26:57

kingsor120 发表于 2012-12-25 22:46 static/image/common/back.gif
我歇这个函数的目的为为了配合你的菜单模板写的
是为了不管在那层菜单,菜单字数多少都能使用,如果函数 ...

在你的菜单项里面增加这个参数来解决字库的问题。

至于你最后提出的问题,不知道你弄过.Net开发没有?在.Net开发里面,每一个控件都有一个
Tag属性……这个Tag属性实际上可以保存对任意对象的引用。对应到你这个例子,你完全可以
增加一个Tag指针(void *)然后将你要保存的特殊信息用指针指向它……

kingsor120 发表于 2012-12-25 23:33:41

Gorgon_Meducer 发表于 2012-12-25 23:26 static/image/common/back.gif
在你的菜单项里面增加这个参数来解决字库的问题。

至于你最后提出的问题,不知道你弄过.Net开发没有?在 ...

第一个问题明白了
就是在你的菜单模型里面增加一项,用来记录该菜单项的字数,

我是学教育的,现在是自学C和单片机。。。没听说过你说的那个,哎~

Gorgon_Meducer 发表于 2012-12-26 10:58:47

kingsor120 发表于 2012-12-25 23:33 static/image/common/back.gif
第一个问题明白了
就是在你的菜单模型里面增加一项,用来记录该菜单项的字数,



具体怎么做知道了么?就是在菜单项里面再增加一个Tag指针而已。

kingsor120 发表于 2012-12-26 21:19:16

Gorgon_Meducer 发表于 2012-12-26 10:58 static/image/common/back.gif
具体怎么做知道了么?就是在菜单项里面再增加一个Tag指针而已。

菜单项写不同字数那个搞定了
我在菜单里面加个一项表示该项菜单指数的变量

我说的那个4个那种设置想用通一函数那问题不这么怎么弄
我都不知道TAG指针是啥。。。呵呵

Gorgon_Meducer 发表于 2012-12-27 10:57:11

kingsor120 发表于 2012-12-26 21:19 static/image/common/back.gif
菜单项写不同字数那个搞定了
我在菜单里面加个一项表示该项菜单指数的变量



就是一个普通指针……或者你干脆用一个普通整形变量好了……你现在这个理解程度建议不要过早的进行通用化改造……
见得多了才会发现通用的部分。

kingsor120 发表于 2012-12-27 18:55:14

Gorgon_Meducer 发表于 2012-12-27 10:57 static/image/common/back.gif
就是一个普通指针……或者你干脆用一个普通整形变量好了……你现在这个理解程度建议不要过早的进行通用化 ...

我先试试看吧,谢谢

SUNZHILIANG 发表于 2013-2-2 19:57:06

什么样子的

beyond870215 发表于 2013-3-28 23:05:56

记号,有用

mafeimafei 发表于 2014-11-17 12:50:16

学习了。谢谢。
页: [1]
查看完整版本: 请教"傻孩子“菜单问题