C语言的封装与嵌入式开发的完美结合① 封装C语言接口在esp8266上对 smartConfig 二
2019-07-13 09:00发布
生成海报
一、前言;
敲写C语言
这么久,看见乐鑫的代码很多都是有回调函数,这个和面向对象编程有很多相似的地方,这种回调函数在面向对象语言比如Java
中称之为接口;很多小伙伴不理解这个是怎么做到的,其实这个也是非常简单的,下面我将由浅到深给大家剖析整个过程。
玩了这么久的乐鑫的wi-fi
芯片,昨晚看到官方微信公告已经把esp32
和亚马逊平台完美对接了!恭喜!我下面也要好好学习esp32
了!
二、[ 抛砖 ]:我们从一个简单的例子做起;
一 : 实现的目的:输入2个数字,随时等待我想要结果时候,我就取出来,而且要求是通过回调方法拿到!
二 : 实现的好处:随心所欲想要结果,而且可以在回调方法中做其他的操作!也符合代码整洁之道
,如果底层逻辑够复杂的话,可以减少一个主文件的代码之绒!大大地提高了开发效率!
三 实现的过程如下:
#ifndef CACULATE_H_INCLUDED
#define CACULATE_H_INCLUDED
void Caculate_Add(int a ,int b);
void Caculate_Get_Result();
typedef void (*Caculate_CallBack)(int pdata);
void registerCaculateCallBack(Caculate_CallBack callBack);
#endif // CACULATE_H_INCLUDED
#include
#include
#include "Caculate.h"
int result = 0 ;
Caculate_CallBack mCallBack ;
void Caculate_Add(int a ,int b){
result =a + b;
}
void registerCaculateCallBack(Caculate_CallBack tempCallBack){
mCallBack = tempCallBack;
}
void Caculate_Get_Result(){
mCallBack(result);
}
#include
#include
#include "Caculate.h"
void funCaculateCallBack(int pResult){
printf("funCaculateCallBack: %d
",pResult);
}
int main(){
registerCaculateCallBack(funCaculateCallBack);
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);
}
四、效果图;
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮