平时常看csdn,但是从来没有自己写过。正好这几天需要用单片机做一个简易的ui界面,于是自己写了一个轻量级的ui框架。发个csdn分享给大家,欢迎大家拍砖!
言归正传,介绍一下这个UI框架。这个框架是纯c语言实现的,所以你可以移植到任何一个可以用c语言编程的单片机上。可以实现复杂的页面级联,参数调节,程序入口等等。
框架元素
一个页面有n个item组成,每个item的功能可以是参数调节器、页面入口、函数入口,三者之一。
当item作为页面的入口时,点击item可以转到item所指向的页面,在新页面,再点击新的item再次进入所指向的子页面,提供了back()函数,用来返回上一个页面,通过多次调用back()函数可以返回到主界面,这一功能通过栈实现。
当item作为函数的入口时,点击item可以执行item所指向的函数。
当item作为参数调节器时,item会显示参数的名称与值。提供了choose_or_cancel()函数,可以选择参数和取消选择,在选择参数之后调用up()与down()可以使参数增加或减少,增量在数据结构中定义,用户可以在初始化的时候定义增量的大小。
因为是轻量级的交互界面,所以显示信息是以列表的形式展现。
大概是这样(用户可以通过重写程序中item_content的内容自定义显示的格式):
因为界面比较简单,所以移植时,只需要实现一个在屏幕中显示文字的函数和屏幕清屏的函数就行了。
上图所示的一个界面中有4个item组成,这四个item组成了一个page,实际使用中一个page的最大item数可以在宏定义中设置,根据屏幕大小而定。
关于page和item的 数据结构。
//item作为参数调节器的数据结构
typedef struct Value
{
unsigned char type;//参数类型 取值:INT FLOAT 在头文件中有定义
void *value;//变量地址
float increasement;//参数调节float增量
int increasement_int;//参数调节int增量
}Value;
struct PageStruct;
typedef struct Item
{
char name[NAME_SIZE];
//item的id
unsigned char id;
//pointer:
//定义指向的是什么类型 取值: VALUE FUNCTION PAGE
//分别表示:item作为参数调节器、item作为函数入口、item作为page入口
unsigned char pointer;
union{
Value data;
void (*fun)();
struct PageStruct *point_page;
}func;
}Item;
//页面数据结构
typedef Item *Items[ITEM_NUM];//item指针数组
struct PageStruct{
char name[NAME_SIZE];
Items list;//存储page内的所有item
unsigned char count;//page现有的item个数
};
用户接口
用户操作ui界面主要通过以下几个函数
void up();//上
void down();//下
void enter();//进入
void choose_or_cancel();//确认/取消
void back();//返回
void UI_TASK(); //UI任务
任务 用户可以在单片机按键检测程序内加入这些函数实现用按键操作ui界面,或者在串口收发程序中,根据接收的数据调用指定函数实现串口操作ui界面。将UI_TASK()函数放在while循环或者定时器中,ui界面即可工作。在用户没有输入操作时,UI_TASK()只运行极少的标志位判断程序。同时当没有切换页面的操作时,屏幕不会全部刷新,而是根据用户的操作,只刷新部分屏幕。
页面的定义与初始化函数
页面的定义与初始化函数
//参数一 页面 参数二 页面标题
void init_page(Page *,char *name);//初始化页面
void page_add_item(Page *,Item *);//给页面添加item
void set_base_page(Page *);//设置主页
1
2
3
4
item的定义与初始化函数
//初始化一个item为float型参数调节器 value:变量 incres:调节增量 name:参数名称
void set_item_value_float(Item *item,float *value,float incres,char *name);
//初始化一个item为int型参数调节器 value:变量 incres:调节增量 name:参数名称
void set_item_value_int(Item *item,int *value,int incres,char *name);
//初始化一个item为程序入口 参数二 function:程序入口地址 参数三 name:item显示的名称
void set_item_function(Item *item,FUNC funciton,char *name);
//初始化一个item为页面入口 参数二 page:页面的地址 参数三 name:item显示的名称
void set_item_indexpage(Item *item,Page *page,char *name);
1
2
3
4
5
6
7
8
对于每个item显示的内容与格式用户也可以通过重现此函数实现:
当前展示的是我写的一个默认的函数,可以通过修改里面的程序实现个性化。
char *item_content(Item *item)
{
static char content[12];
if(item->pointer!=VALUE) sprintf(content,"%d. %s",item->id+1,item->name);
else if(item->func.data.type==INT) sprintf(content,"%s:%d",item->name,*((int*)item->func.data.value));
else if(item->func.data.type==FLOAT) sprintf(content,"%s:%.2f",item->name,*((float*)item->func.data.value));
return content;
}
1
2
3
4
5
6
7
8
程序示例
Page page1;
Page page2;
Page page3;
Item item1,item2,item3,item4,item5,item6,item7,item8;
int sss;
void init_ui()
{
set_show_area(0,0,120,188);//设置显示区域
init_page(&page1,"menu");//初始化页面
//初始化页面的item
set_item_indexpage(&item1,&page2,"item1");//初始化item1 指向page2 名称item1
set_item_indexpage(&item2,NULL,"item2");
set_item_indexpage(&item3,NULL,"item3");
set_item_indexpage(&item4,NULL,"item4");
set_item_indexpage(&item5,NULL,"item5");
set_item_indexpage(&item6,NULL,"item6");
//给page添加item选项
page_add_item(&page1,&item1);
page_add_item(&page1,&item2);
page_add_item(&page1,&item3);
page_add_item(&page1,&item4);
page_add_item(&page1,&item5);
page_add_item(&page1,&item6);
set_base_page(&page1);//设置主页
init_page(&page2,"page2"); //初始化页面2
set_item_indexpage(&item7,&page3,"item7");
page_add_item(&page2,&item7);
init_page(&page3,"page3");//页面3
//初始化item8 int型参数调节器 调节变量sss 调节增量1 名称num
set_item_value_int(&item8,&sss,1,"num");
page_add_item(&page3,&item8);//将item8 添加到page3中
}
————————————————
版权声明:本文为CSDN博主「xjx哈哈哈」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42523725/article/details/106738070
简单效果展示
代码开源
源码下载.
链接:https://pan.baidu.com/s/1AimPGUIOO3qGmjyNqnzhfw
提取码:dr4i
平时常看csdn,但是从来没有自己写过。正好这几天需要用单片机做一个简易的ui界面,于是自己写了一个轻量级的ui框架。发个csdn分享给大家,欢迎大家拍砖!
言归正传,介绍一下这个UI框架。这个框架是纯c语言实现的,所以你可以移植到任何一个可以用c语言编程的单片机上。可以实现复杂的页面级联,参数调节,程序入口等等。
框架元素
一个页面有n个item组成,每个item的功能可以是参数调节器、页面入口、函数入口,三者之一。
当item作为页面的入口时,点击item可以转到item所指向的页面,在新页面,再点击新的item再次进入所指向的子页面,提供了back()函数,用来返回上一个页面,通过多次调用back()函数可以返回到主界面,这一功能通过栈实现。
当item作为函数的入口时,点击item可以执行item所指向的函数。
当item作为参数调节器时,item会显示参数的名称与值。提供了choose_or_cancel()函数,可以选择参数和取消选择,在选择参数之后调用up()与down()可以使参数增加或减少,增量在数据结构中定义,用户可以在初始化的时候定义增量的大小。
因为是轻量级的交互界面,所以显示信息是以列表的形式展现。
大概是这样(用户可以通过重写程序中item_content的内容自定义显示的格式):
因为界面比较简单,所以移植时,只需要实现一个在屏幕中显示文字的函数和屏幕清屏的函数就行了。
上图所示的一个界面中有4个item组成,这四个item组成了一个page,实际使用中一个page的最大item数可以在宏定义中设置,根据屏幕大小而定。
关于page和item的 数据结构。
//item作为参数调节器的数据结构
typedef struct Value
{
unsigned char type;//参数类型 取值:INT FLOAT 在头文件中有定义
void *value;//变量地址
float increasement;//参数调节float增量
int increasement_int;//参数调节int增量
}Value;
struct PageStruct;
typedef struct Item
{
char name[NAME_SIZE];
//item的id
unsigned char id;
//pointer:
//定义指向的是什么类型 取值: VALUE FUNCTION PAGE
//分别表示:item作为参数调节器、item作为函数入口、item作为page入口
unsigned char pointer;
union{
Value data;
void (*fun)();
struct PageStruct *point_page;
}func;
}Item;
//页面数据结构
typedef Item *Items[ITEM_NUM];//item指针数组
struct PageStruct{
char name[NAME_SIZE];
Items list;//存储page内的所有item
unsigned char count;//page现有的item个数
};
用户接口
用户操作ui界面主要通过以下几个函数
void up();//上
void down();//下
void enter();//进入
void choose_or_cancel();//确认/取消
void back();//返回
void UI_TASK(); //UI任务
任务 用户可以在单片机按键检测程序内加入这些函数实现用按键操作ui界面,或者在串口收发程序中,根据接收的数据调用指定函数实现串口操作ui界面。将UI_TASK()函数放在while循环或者定时器中,ui界面即可工作。在用户没有输入操作时,UI_TASK()只运行极少的标志位判断程序。同时当没有切换页面的操作时,屏幕不会全部刷新,而是根据用户的操作,只刷新部分屏幕。
页面的定义与初始化函数
页面的定义与初始化函数
//参数一 页面 参数二 页面标题
void init_page(Page *,char *name);//初始化页面
void page_add_item(Page *,Item *);//给页面添加item
void set_base_page(Page *);//设置主页
1
2
3
4
item的定义与初始化函数
//初始化一个item为float型参数调节器 value:变量 incres:调节增量 name:参数名称
void set_item_value_float(Item *item,float *value,float incres,char *name);
//初始化一个item为int型参数调节器 value:变量 incres:调节增量 name:参数名称
void set_item_value_int(Item *item,int *value,int incres,char *name);
//初始化一个item为程序入口 参数二 function:程序入口地址 参数三 name:item显示的名称
void set_item_function(Item *item,FUNC funciton,char *name);
//初始化一个item为页面入口 参数二 page:页面的地址 参数三 name:item显示的名称
void set_item_indexpage(Item *item,Page *page,char *name);
1
2
3
4
5
6
7
8
对于每个item显示的内容与格式用户也可以通过重现此函数实现:
当前展示的是我写的一个默认的函数,可以通过修改里面的程序实现个性化。
char *item_content(Item *item)
{
static char content[12];
if(item->pointer!=VALUE) sprintf(content,"%d. %s",item->id+1,item->name);
else if(item->func.data.type==INT) sprintf(content,"%s:%d",item->name,*((int*)item->func.data.value));
else if(item->func.data.type==FLOAT) sprintf(content,"%s:%.2f",item->name,*((float*)item->func.data.value));
return content;
}
1
2
3
4
5
6
7
8
程序示例
Page page1;
Page page2;
Page page3;
Item item1,item2,item3,item4,item5,item6,item7,item8;
int sss;
void init_ui()
{
set_show_area(0,0,120,188);//设置显示区域
init_page(&page1,"menu");//初始化页面
//初始化页面的item
set_item_indexpage(&item1,&page2,"item1");//初始化item1 指向page2 名称item1
set_item_indexpage(&item2,NULL,"item2");
set_item_indexpage(&item3,NULL,"item3");
set_item_indexpage(&item4,NULL,"item4");
set_item_indexpage(&item5,NULL,"item5");
set_item_indexpage(&item6,NULL,"item6");
//给page添加item选项
page_add_item(&page1,&item1);
page_add_item(&page1,&item2);
page_add_item(&page1,&item3);
page_add_item(&page1,&item4);
page_add_item(&page1,&item5);
page_add_item(&page1,&item6);
set_base_page(&page1);//设置主页
init_page(&page2,"page2"); //初始化页面2
set_item_indexpage(&item7,&page3,"item7");
page_add_item(&page2,&item7);
init_page(&page3,"page3");//页面3
//初始化item8 int型参数调节器 调节变量sss 调节增量1 名称num
set_item_value_int(&item8,&sss,1,"num");
page_add_item(&page3,&item8);//将item8 添加到page3中
}
————————————————
版权声明:本文为CSDN博主「xjx哈哈哈」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42523725/article/details/106738070
简单效果展示
代码开源
源码下载.
链接:https://pan.baidu.com/s/1AimPGUIOO3qGmjyNqnzhfw
提取码:dr4i
举报