本帖最后由 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)
|