C语言的封装与嵌入式开发的完美结合① 封装C语言接口在esp8266上对 smartConfig 二次封装。(附带demo)

一、前言;

     敲写C语言这么久,看见乐鑫的代码很多都是有回调函数,这个和面向对象编程有很多相似的地方,这种回调函数在面向对象语言比如Java中称之为接口;很多小伙伴不理解这个是怎么做到的,其实这个也是非常简单的,下面我将由浅到深给大家剖析整个过程。


玩了这么久的乐鑫的wi-fi芯片,昨晚看到官方微信公告已经把esp32和亚马逊平台完美对接了!恭喜!我下面也要好好学习esp32了!


二、[ 抛砖 ]:我们从一个简单的例子做起;


: 实现的目的:输入2个数字,随时等待我想要结果时候,我就取出来,而且要求是通过回调方法拿到!


二 : 实现的好处:随心所欲想要结果,而且可以在回调方法中做其他的操作!也符合代码整洁之道,如果底层逻辑够复杂的话,可以减少一个主文件的代码之绒!大大地提高了开发效率!


这里写图片描述


实现的过程如下:

  • 首先编写头文件,声明一个回调函数,作为介质传递:
#ifndef CACULATE_H_INCLUDED
#define CACULATE_H_INCLUDED


//初始化需要相加的2个数传值
void Caculate_Add(int a ,int b);

//调用返回2个数相加的数值,并且在回调函数中回调
void Caculate_Get_Result();

//声明一个回调函数类型,形参是 int
typedef void (*Caculate_CallBack)(int pdata);

//注册回调函数
void registerCaculateCallBack(Caculate_CallBack callBack);


#endif // CACULATE_H_INCLUDED

  • 编写驱动文件,so easy
#include <stdio.h>
#include <stdlib.h>
#include "Caculate.h"


int result = 0 ;
//回调函数声明,注意不用初始化赋值
Caculate_CallBack mCallBack ;

//2个数的逻辑处理函数
void Caculate_Add(int a ,int b){
    result =a + b;
}

void registerCaculateCallBack(Caculate_CallBack tempCallBack){
    //从主文件中赋值此给驱动文件的回调函数
    mCallBack = tempCallBack;
}

//开始调用
void Caculate_Get_Result(){
     //来时回调
     mCallBack(result);
}

  • 看看我们的主文件吧:
#include <stdio.h>
#include <stdlib.h>
#include "Caculate.h"

//回调函数
void funCaculateCallBack(int pResult){
     //do your things
     printf("funCaculateCallBack: %d \n",pResult);
}


int main(){

    //注册回调函数
    registerCaculateCallBack(funCaculateCallBack);
    //2个数添加操作
    Caculate_Add(5,9);
    //触发回调
    Caculate_Get_Result();

    return 0;
}

  • 看看结果?是不是完美调用了吖?

这里写图片描述


三、[ 引玉 ]:对官方的smartConfig二次封装;


  • 熟悉esp8266 的同学们都知道,其的smartConfig是没有连接失败的回调的,需要自己去判断是否成功配网!那么现在我们上面的原理,来完善下这个不足地方!

    • 第一步:编写一个头文件;

    • 这里我们定义一个结构体,方便我们核对校验码!

#ifndef MSMARTCONFIG_H_INCLUDED
#define MSMARTCONFIG_H_INCLUDED

typedef enum {
    xSmartConfig_Status_Succeed = 0, //连接成功
    xSmartConfig_Status_Failed = 1,  //连接失败
    xSmartConfig_Status_Get_Pas = 3, //成功得到手机发来的网关的帐号和密码信息
    xSmartConfig_Status_Connectting_GateWay = 4,  //正在连接网关
    xSmartConfig_Status_Connectting_Early = 5,  //未开始连接
} xSmartConfig_Status_Code;

typedef void (*xSmartConfig_CallBack)(xSmartConfig_Status_Code statusCode);

//开始一键配网
void xSmartConfig_Start();
//注册回调函数
void register_xSmartConfigCallBack(xSmartConfig_CallBack callBack);

#endif

  • 第二步:看看我们的驱动文件怎么实现?

    首先我们这个先拿到回调函数,和上面一样,等待触发事件了,我们就调用此回调函数即可,这个就可以在主文件实现同步啦!


    ①:需要注意的是,配网失败的处理,我这个用一个定时器不断地获取ip,如果超过60s,还是没有获取到ip,那么我们就回调说配网失败啦! 下面计时的35,实际计算就是60s左右的!


    ②:配网失败,记得要关闭定时器哦!


int flag = 0;
os_timer_t mTimerXSmartConfig;
xSmartConfig_CallBack statusCodeDriver;
struct station_config *sta_conf;
void ICACHE_FLASH_ATTR smartconfig_done(sc_status status, void *pdata) {

    switch (status) {

    case SC_STATUS_FIND_CHANNEL:
        statusCodeDriver(xSmartConfig_Status_Get_Pas);
        break;

    case SC_STATUS_GETTING_SSID_PSWD:
        statusCodeDriver(xSmartConfig_Status_Get_Pas);
        break;

    case SC_STATUS_LINK:
        os_strcpy(&sta_conf, &pdata);
        wifi_station_set_config(sta_conf);
        wifi_station_disconnect();
        wifi_station_connect();
        statusCodeDriver(xSmartConfig_Status_Connectting_GateWay);
        break;

    case SC_STATUS_LINK_OVER:
        if (pdata != NULL) {
            statusCodeDriver(xSmartConfig_Status_Succeed);
            flag = 40;
        }
        smartconfig_stop();
        break;
    }

}

//注册回调函数
void register_xSmartConfigCallBack(xSmartConfig_CallBack tempCallBack) {
    statusCodeDriver = tempCallBack;
}

//定時器回调函数
void Check_WifiState() {

    flag++;
    if (flag > 35) {
        struct ip_info ipConfig;
        wifi_get_ip_info(STATION_IF, &ipConfig);
        u8 getState = wifi_station_get_connect_status();
        if (!(getState == STATION_GOT_IP && ipConfig.ip.addr != 0)) {
            statusCodeDriver(xSmartConfig_Status_Failed);
        }
        os_timer_disarm(&mTimerXSmartConfig); //启动定时器前先取消定时器定时
    }

}

//开始一键配网
void xSmartConfig_Start() {

    statusCodeDriver(xSmartConfig_Status_Connectting_Early);

    smartconfig_set_type(SC_TYPE_ESPTOUCH);
    wifi_set_opmode(STATION_MODE);
    smartconfig_start(smartconfig_done);

    os_timer_disarm(&mTimerXSmartConfig); //启动定时器前先取消定时器定时
    os_timer_setfn(&mTimerXSmartConfig, (os_timer_func_t *) Check_WifiState,
    NULL); //设置定时器回调函数
    os_timer_arm(&mTimerXSmartConfig, 2000, 1); //启动定时器

}

四、效果图;

这里写图片描述


猜你喜欢

转载自blog.csdn.net/xh870189248/article/details/80375188