这次主要是对第二次课程对按键程序结构的一个梳理,以面向对象的思路去划分层次结构。
优点:程序逻辑清晰,易于理解,易于扩展,方便维护
缺点:相比普通写法比较占空间,对于一些flash很小的单片机,像STM8L101,传统51之类的可能不太适用
不过我还是挺喜欢这种高端大气上档次的方式哈哈
按键举例(在原示例基础上部分调整)
//按键结构
typedef struct key
{
char* key_name;
void (*init)(void* para);
void (*read)(void* para);
}key,*pkey;
//按键链表
typedef struct key_list
{
struct key_list* prev;
struct key_list* next;
struct key* k;
}
//插入按键
void klist_insert(struct key* k)
{
...
}
//删除按键
void klist_delete(struct key* k)
{
...
}
//查询按键
key* klist_search(char* key_name)
{
...
return k;
}
//按键初始化
void kilst_init(void)
{
...遍历...
key* k = iterater..
k->init(NULL);
}
在key_manage.c 中(按键管理文件)
//定义按键初始化函数
void key_init(void)
{
int i= 0;
register_key(k1);
register_key(k2);
register_key(k3);
//kilst_init(); 注册中初始化
}
//根据名称获取按键
key* get_key(char* key_name)
{
return klist_search(key_name);
}
//按键注册列表
void register_key(key* k)
{
k->init(k); //在注册时候直接初始化
klist_insert(k)
}
//按键移除列表
void remove_key(key* k)
{
k->deinit(k); //移除的时候恢复
klist_delete(k);
}
在具体的key.c中(按键实例文件)
static key k1 = {"k1", init_key1, read_key1 };
static key k2 = {"k2", init_key2, read_key2 };
static key k3 = {"k3", init_key3, read_key3 };
//按键初始化 以k1举例,k2 k3类似
void init_key1(void* para)
{
GPIOA->IDR = ...
}
//按键值获取
void read_key1(void* para)
{
int ret = 0;
#ifdef USE_INT //如果使用中断检测按键
if(ret = pop_kvalue(&k1))
...
else
...
#else
if(GPIOA->IDR == ...)
...
else
...
#endif
return ret;
}
#ifdef USE_INT //如果使用中断检测按键
void EXTI1_IRQHandler(void)
{
if(GPIOA->IDR...)
{
...
push_kvalue(&k1, value)
}
}
int buf_kvlaue[128];
void push_kvalue(key* k, int vlaue)
{
buf_kvlaue[...] = value;
}
int pop_kvalue(key* k)
{
return ...buf_kvalue[...]...;
}
#endif
在main.c中
void main()
{
key* k;
int value;
//按键初始化
key_init();
//根据名称获取对应按键
k = get_key("k1");
while(1)
{
//获取按键值
value = k->read(k);
//判断执行
switch(value)
{
case ... : ...; break;
case ... : ...; break;
case ... : ...; break;
default: break;
}
}
}
我在原有基础上,将原有的按键数组改成了按键链表,增加了按键的添加和删除操作,在按键管理文件中,增加按键的注册和移除,实际使用起来更加灵活,在按键值获取过程中,完善了一按键的缓存,中断push入缓存,read的时候从缓存中pop,可有效提高程序可靠性,同时把按键的注册移动到了按键管理中的初始化中,不放在按键实例初始化,按键实例初始化只针对硬件初始化,在按键管理初始化中去注册按键同时调用按键实例初始化,更直观的看出一共注册了哪些按键,方便管理,这样实现起来虽然繁琐了一点,但是干下次做项目的时候就这样应用了,最后感谢韦老师醍醐灌顶,在巨人肩膀上行走的感觉很棒!