物联笔记-2

这次主要是对第二次课程对按键程序结构的一个梳理,以面向对象的思路去划分层次结构。

优点:程序逻辑清晰,易于理解,易于扩展,方便维护

缺点:相比普通写法比较占空间,对于一些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,可有效提高程序可靠性,同时把按键的注册移动到了按键管理中的初始化中,不放在按键实例初始化,按键实例初始化只针对硬件初始化,在按键管理初始化中去注册按键同时调用按键实例初始化,更直观的看出一共注册了哪些按键,方便管理,这样实现起来虽然繁琐了一点,但是干下次做项目的时候就这样应用了,最后感谢韦老师醍醐灌顶,在巨人肩膀上行走的感觉很棒!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值