C语言的封装与嵌入式开发的完美结合① 封装C语言接口在esp8266上对 smartConfig 二次封装。(附带demo)
Posted on 2018-05-19 16:04 CoreHouse 阅读(330) 评论(0) 收藏 举报一、前言;
敲写
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); //启动定时器
}
四、效果图;
- Demo下载:https://github.com/xuhongv/StudyInEsp8266/tree/master/20_SmartConfigInterface
- ESP8266学习之旅代码汇总,欢迎star:https://github.com/xuhongv/StudyInEsp8266
- ESP32学习之旅代码汇总,欢迎star:https://github.com/xuhongv/StudyInEsp32
- 小徐QQ交流群:434878850
 
                    
                     
                    
                 
                    
                 
 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号