打印
[STM32F0]

【STM32F072-Discover】基于双向链表的菜单应用

[复制链接]
1701|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yklstudent|  楼主 | 2016-4-1 07:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 yklstudent 于 2016-4-5 22:32 编辑

【STM32F072-Discover】基于双向链表的菜单界面
占个坑先;
有幸收到21过年送的STM32F072-Discover开发板,但由于工作忙就一直没去捣鼓它;
最近工作刚忙好,所以就想写篇关于基于双向链表的菜单界面,平台就用STM32F072-Discover;
等代码整理好了节后上传;并上传视频效果图。过节三天准备捣鼓LCD界面菜单的,发现手头的LCD屏都是5V的,STM32F072没法直接用来驱动LCD,所以就先
暂时把此任务规划往后拖拖了;不过还是整理了一个VS2005平台运行的基于双向链表的界面菜单实例。
1、双向链表参考Linux下的,代码如下所示:
#include "Lib_List.h"

void INIT_LIST_HEAD(struct list_head *list)
{
    list->next = list;
    list->prev = list;
}

/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static void __list_add(struct list_head *new,
                  struct list_head *prev,
                  struct list_head *next)
{
    next->prev = new;
    new->next = next;
    new->prev = prev;
    prev->next = new;
}

/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
void list_add(struct list_head *new, struct list_head *head)
{
    __list_add(new, head, head->next);
}

/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
void list_add_tail(struct list_head *new, struct list_head *head)
{
    __list_add(new, head->prev, head);
}

/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static void __list_del(struct list_head * prev, struct list_head * next)
{
    next->prev = prev;
    prev->next = next;
}

/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
void list_del(struct list_head *entry)
{
    __list_del(entry->prev, entry->next);
    entry->next = LIST_POISON1;
    entry->prev = LIST_POISON2;
}


/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
int list_empty(const struct list_head *head)
{
    return head->next == head;
}


void __list_splice(struct list_head *list,
                 struct list_head *head)
{
    struct list_head *first = list->next;
    struct list_head *last = list->prev;
    struct list_head *at = head->next;

    first->prev = head;
    head->next = first;

    last->next = at;
    at->prev = last;
}

/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
void list_splice(struct list_head *list, struct list_head *head)
{
    if (!list_empty(list))
        __list_splice(list, head);
}

2、定义菜单结构体,如下所示:
typedef struct Menu sMenu_TypeDef;
struct Menu
{
        uint8_t usKty;
        uint8_t usLevel;
        uint8_t usEnterKey[8];
        uint8_t usUserKey[8];
        uint8_t usAdminKey[8];
        struct list_head *uspHList1;
        struct list_head *uspHList2;
        sList_TypeDef *uspList;
        /**/
        struct list_head *usHead;
        /*第1级菜单*/
        struct list_head usHead1;
        /*第1-1级菜单*/
        struct list_head usHead2;
        /*第1-2级菜单*/
        struct list_head usHead3;
        /*第1-3级菜单*/       
        struct list_head usHead4;
        /*第1-4级菜单*/       
        struct list_head usHead5;
        void (*pMenuInit)(sMenu_TypeDef* pMenu);
        void (*pReadKty)(sMenu_TypeDef* pMenu, uint8_t lubKey);
        void (*pExcuteUpMenu)(sMenu_TypeDef* pMenu);
        void (*pExcuteDnMenu)(sMenu_TypeDef* pMenu);
        uint8_t (*pExcuteCkMenu)(sMenu_TypeDef* pMenu);
        void (*pScheduleMenu)(sMenu_TypeDef* pMenu);
        void (*pTaskGUIExcu)(sMenu_TypeDef* pMenu);
};

3、此菜单结构基于4个按键,UP(向上按键,键盘W或者w表示)、DOWN(向下按键,键盘S或者s表示)、ESC(返回按键,键盘A或者a表示)和ENTER(确认按键,键盘D或者d表示);
4、此菜单一共分四层(演示只提供三层);
第一层菜单显示5个界面;其中第1-2、1-3、1-4个界面可以通过ENTER按键进入第二层菜单;
通过1-2界面进入的第二层菜单包含8个显示界面;
通过1-3界面进入的第二层菜单包含8个显示界面;
通过1-4界面进入的第二层菜单包含8个显示界面(此菜单项为用户设置输入密码,共包含两个用户权限:普通账户和管理员账户);
用户输入密码,获取相应权限后,进入相对于的第三层菜单;
第三层菜单主要用于用户需要更改的参数等功能。
5、具体代码实现各位可以具体阅读代码。
6、最后上传VS2005工程文件(包含全部源代码文件).
Ex_Proj6.rar (202.19 KB)
沙发
songchenping| | 2016-4-1 08:26 | 只看该作者
期待更新

使用特权

评论回复
板凳
菜鸟同学| | 2016-4-1 10:30 | 只看该作者
菜单界面为啥用双向链表,浪费了,而且不便于调试,好好想想。

使用特权

评论回复
地板
yklstudent|  楼主 | 2016-4-1 11:08 | 只看该作者
菜鸟同学 发表于 2016-4-1 10:30
菜单界面为啥用双向链表,浪费了,而且不便于调试,好好想想。

个人感觉完全没啥不好调试的;
个人反而感觉方便界面的增减与维护;
双向链表主要还是方便页面的上翻、下翻切换吧
个人也是第一次在菜单中采用双向链表

使用特权

评论回复
5
菜鸟同学| | 2016-4-1 11:12 | 只看该作者
你好好想想,你要完成这些功能,根本不需要双向链表,你可能背别人带错方向了。

使用特权

评论回复
6
yklstudent|  楼主 | 2016-4-1 11:17 | 只看该作者
菜鸟同学 发表于 2016-4-1 11:12
你好好想想,你要完成这些功能,根本不需要双向链表,你可能背别人带错方向了。 ...

当然条条大道通罗马;
见仁见智吧

使用特权

评论回复
7
lovecat2015| | 2016-4-1 20:18 | 只看该作者
072和030比的话优势在什么地方?

使用特权

评论回复
8
Ketose| | 2016-4-1 21:04 | 只看该作者
期待更新   

使用特权

评论回复
9
Ketose| | 2016-4-1 21:06 | 只看该作者
楼主F7是哪里送的?

使用特权

评论回复
10
yklstudent|  楼主 | 2016-4-2 16:31 | 只看该作者
Ketose 发表于 2016-4-1 21:06
楼主F7是哪里送的?

你哪里看到我有F7了???

使用特权

评论回复
11
yklstudent|  楼主 | 2016-4-2 16:33 | 只看该作者
lovecat2015 发表于 2016-4-1 20:18
072和030比的话优势在什么地方?

这个都是F0系列的,你需要比较什么?
两个芯片手册一对比下就可以知道了

使用特权

评论回复
12
yklstudent|  楼主 | 2016-4-6 09:26 | 只看该作者
代码已经上传。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

39

主题

3256

帖子

22

粉丝