ESP8266例程解析④softAPToNet

代码分析

  1. 初始化分区

  2. 初始化串口(串口1 串口2都为57600) 初始化串口(串口1 串口2都为57600)

  3. 打印sdk版本

  4. 按键初始化(简短的单按钮初始化 长按 短按 按键驱动程序初始化 IO口初始化)
    4.1 按键回调函数(长按函数 短按函数 内含提示灯)
    4.2 长按函数为空
    4.3短按函数为
    4.3.1 WiFi准备(设置模式,ssid password 加密模式 信标间隔时槽 通道号(即通频带) 最大连接数 隐藏ssid 保存到flash)
    4.3.2 TCP准备端口8266(分配空间 设置类型为TCP协议 本地端口 注册连接成功回调函数(server_listen)和重新连接回调函数(server_recon))创建 TCP server,建立侦听 设置超时断开时间
    4.3.2 .1注册连接成功回调函数(server_listen)入口 用户tcp类型地址
    4.3.2 .1.1 回调函数 接收(用cJSON解析接收的包 判断包是否为空 创建对象 给对象传递数据 打印对象 1. 如果为空 创建对象 提示json错误 2.不为空 创建对象 继承WiFi ssid password state(为0(成功连接到指定的WiFi 检测是否有IP,有代表连接成功) 为1表示连接AP) 打印信息)AP和WiFi区别是IP地址
    4.3.2 .1.2发送(设置为station模式 发送信息) 断开
    4.3.2 .2重新连接回调函数(server_recon) 返回错误代码和类型

  5. 设置ESP8266 station 上电是否自动连接已记录的AP(路由),默认为自动连接

  6. 设置为无睡眠模式

  7. 定时器回调函数 检查WIFI状态,用IO口的灯变化显示出WiFi状态打印sdk版本 按键初始化定时器回调函数 检查WIFI状态,用IO口的灯变化显示出WiFi状态

代码

user_main.c
#include "driver/uart.h"  //串口0需要的头文件
#include "osapi.h"  //串口1需要的头文件
#include "user_interface.h" //WIFI连接需要的头文件
#include "espconn.h"//TCP连接需要的头文件
#include "mem.h" //系统操作需要的头文件
#include "gpio.h"  //端口控制需要的头文件
#include "cJSON.h"
#include "hal_key.h"

struct espconn user_tcp_espconn;
os_timer_t checkTimer_wifistate;

//按键定义
#define GPIO_KEY_NUM                            1
#define KEY_0_IO_MUX                            PERIPHS_IO_MUX_MTMS_U
#define KEY_0_IO_NUM                            14
#define KEY_0_IO_FUNC                           FUNC_GPIO14

LOCAL key_typedef_t * singleKey[GPIO_KEY_NUM]; 
LOCAL keys_typedef_t keys; 

bool isConnected = false;

void Check_WifiState(void)//检查WIFI状态
 {

	uint8 status = wifi_station_get_connect_status();//查询ESP8266 WIFI  station 接口连接AP的状态 

	if (status == STATION_GOT_IP)//检测是否连接AP并且返回信息
	 {
		GPIO_OUTPUT_SET(GPIO_ID_PIN(15), 0);  //设置IO口输出电平
		GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1);
		wifi_set_opmode(0x01);   //WIFI模式为station
	} 
	else 
	{
		GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0); //GPIO15 低电平输出
		GPIO_OUTPUT_SET(GPIO_ID_PIN(15), 1); //GPIO15 低电平输出
	}
}

void wifiStationConnect(char *ssid, char *psw)//WiFi重新连接
 {
	os_printf(" wifiStationConnect name:%s \n", ssid);
	os_printf(" wifiStationConnect psw :%s \n", psw);
	struct station_config stationConf;
	os_strcpy(stationConf.ssid, ssid);	  //路由器的用户名
	os_strcpy(stationConf.password, psw); //路由器的密码
	wifi_station_set_config(&stationConf); //设置WiFi station接口配置,并保存到 flash
	wifi_station_connect(); //连接路由器

}

void ICACHE_FLASH_ATTR server_recv(void *arg, char *pdata, unsigned short len)  //注册 TCP 连接成功建立后的回调函数接收
{
    //判断是否为json数据
	cJSON *root = cJSON_Parse(pdata);//解析数据  返回一个解析成功的值  调用cJSON.c库
	if (!root) 
	{
		os_printf("Error before: [%s]\n", cJSON_GetErrorPtr());/*用于分析失败的分析。这将返回指向分析错误的指针。你可能需要找几个字符来解释它。当cjson_parse()返回0时定义。当cjson_parse()成功时为0。*/
		cJSON * Result = cJSON_CreateObject();/*这些调用创建适当类型的CJSON项。 创造对象分配空间 大小为6 范围为0到6 */  
		cJSON_AddNumberToObject(Result, "status", 3);//添加数字到对象   对象  名字  数字
		cJSON_AddStringToObject(Result, "msg", "json error!");//添加字符串到对象   对象  名字  字符串
		char *succeedData = cJSON_Print(Result);//将CJSON项/实体/结构呈现为文本。
		char data[1024];
		os_sprintf(data, "%s", succeedData);    //打印Result
		espconn_send((struct espconn *) arg, data, strlen(data));//通过WIFI发送数据
		return;
	} 
	else
	 {
		char *ssid, *psw;
		int state;
		//解析字段
		cJSON *ssid_json = cJSON_GetObjectItem(root, "ssid");
		cJSON *psw_json = cJSON_GetObjectItem(root, "psw");
		cJSON *state_json = cJSON_GetObjectItem(root, "state");
	
		state = state_json->valueint;
		//对state 进行剖析
		switch (state) 
		{	//当前wifi的连接情况查询
		case 0://成功连接到指定的WiFi
			if (STATION_GOT_IP == wifi_station_get_connect_status()) 
			{

				cJSON * Result = cJSON_CreateObject();
				cJSON_AddNumberToObject(Result, "status", 0);
				cJSON_AddStringToObject(Result, "msg", "connect succeed!");
				char *succeedData = cJSON_Print(Result);
				char data[1024];
				os_sprintf(data, "%s", succeedData);
				espconn_send((struct espconn *) arg, data, strlen(data));
				isConnected = true;
			} 
			else
			 {
				//未连接到指定的WiFi
				cJSON * Result = cJSON_CreateObject();
				cJSON_AddNumberToObject(Result, "status", 1);
				cJSON_AddStringToObject(Result, "msg", "connect fail!");
				char *succeedData = cJSON_Print(Result);
				char data[1024];
				os_sprintf(data, "%s", succeedData);
				espconn_send((struct espconn *) arg, data, strlen(data));
			}

			break;

			//1表示连接AP
		case 1:

			if (ssid_json && psw_json) 
			{
				ssid = ssid_json->valuestring;
				psw = psw_json->valuestring;
				wifiStationConnect(ssid, psw);//WiFi重新连接
			} 
			else {
				os_printf(" width null! \n");
			}

			cJSON_Delete(root);//释放内存
			cJSON * Result = cJSON_CreateObject();//构造json
			cJSON_AddNumberToObject(Result, "status", 2);
			cJSON_AddStringToObject(Result, "msg", "AP connectting!");
			char *succeedData = cJSON_Print(Result);
			char data[1024];
			os_sprintf(data, "%s", succeedData);
			espconn_send((struct espconn *) arg, data, strlen(data));

			break;

		}

	}
}

void ICACHE_FLASH_ATTR server_sent(void *arg)  //注册 TCP 连接成功建立后的回调函数发送
{
	os_printf("send data succeed!\r");
	if (isConnected) 
	{
		wifi_set_opmode(0x01); //设置为STATION模式
	}
}

void ICACHE_FLASH_ATTR server_discon(void *arg) //注册 TCP 连接成功建立后的回调函数断开
 {
	os_printf("conect diable! \r");
}

void ICACHE_FLASH_ATTR server_listen(void *arg) //注册 TCP 连接成功建立后的回调函数
{
	struct espconn *pespconn = arg;
	espconn_regist_recvcb(pespconn, server_recv); //接收
	espconn_regist_sentcb(pespconn, server_sent); //发送
	espconn_regist_disconcb(pespconn, server_discon); //断开
}

void ICACHE_FLASH_ATTR server_recon(void *arg, sint8 err) //注册 TCP 连接发生异常断开时的回调函数,可以在回调函数中进行重连
{
	os_printf("连接错误,错误代码为:%d\r\n", err); //%d,用来输出十进制整数
}

void Inter213_InitTCP(uint32_t Local_port) 
{
	user_tcp_espconn.proto.tcp = (esp_tcp *) os_zalloc(sizeof(esp_tcp)); //分配空间
	user_tcp_espconn.type = ESPCONN_TCP; //设置类型为TCP协议
	user_tcp_espconn.proto.tcp->local_port = Local_port; //本地端口

	//注册连接成功回调函数和重新连接回调函数
	espconn_regist_connectcb(&user_tcp_espconn, server_listen); //注册 TCP 连接成功建立后的回调函数
	espconn_regist_reconcb(&user_tcp_espconn, server_recon); //注册 TCP 连接发生异常断开时的回调函数,可以在回调函数中进行重连
	espconn_accept(&user_tcp_espconn); //创建 TCP server,建立侦听
	espconn_regist_time(&user_tcp_espconn, 180, 0); //设置超时断开时间 单位:秒,最大值:7200 秒
	//如果超时时间设置为 0,ESP8266 TCP server 将始终不会断开已经不与它通信的 TCP client,不建议这样使用。

}

void WIFI_Init()
 {
	struct softap_config apConfig;
	wifi_set_opmode(0x03);    //设置为station+soft-AP模式,保存到 flash
	apConfig.ssid_len = 10;						//设置ssid长度
	os_strcpy(apConfig.ssid, "xaiofang");	    //设置ssid名字
	os_strcpy(apConfig.password, "12345678");	//设置密码
	apConfig.authmode = 3;                      //设置加密模式
	apConfig.beacon_interval = 100;            //信标间隔时槽100 ~ 60000 ms
	apConfig.channel = 1;                      //通道号1 ~ 13
	apConfig.max_connection = 4;               //最大连接数
	apConfig.ssid_hidden = 0;                  //隐藏SSID

	wifi_softap_set_config(&apConfig);		//设置 WiFi soft-AP 接口配置,并保存到 flash
}

void wifiConnectCb(uint8_t status)
 {

}

LOCAL void ICACHE_FLASH_ATTR keyLongPress(void)//长按按键
 {

}

LOCAL void ICACHE_FLASH_ATTR keyShortPress(void) //短按按键
{
	os_printf(" key short...\r\n");
	WIFI_Init();    //WIFI 准备
	Inter213_InitTCP(8266); //本地端口
}
//按键初始化
LOCAL void ICACHE_FLASH_ATTR keyInit(void)
 {
	singleKey[0] = keyInitOne(KEY_0_IO_NUM, KEY_0_IO_MUX, KEY_0_IO_FUNC,
			keyLongPress, keyShortPress);//简短的单按钮初始化 长按  短按
	keys.singleKey = singleKey;
	keyParaInit(&keys);//简短按钮驱动程序初始化

	PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); //GPIO12初始化(管脚功能选择)
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15); //GPIO15初始化(管脚功能选择)
}

void user_init()
 {
	uart_init(57600, 57600);		//设置串口0和串口1的波特率
	os_printf("-----SDK version:%s------\n", system_get_sdk_version());//打印版本号
	keyInit();  //按键准备
	
	wifi_station_set_auto_connect(1);//设置ESP8266 station 上电是否自动连接已记录的AP(路由),默认为自动连接1 0为不自动
	wifi_set_sleep_type(NONE_SLEEP_T);                     //set none sleep mode,默认为睡眠模式(modem-sleep参数为sleep_type)

	os_timer_disarm(&checkTimer_wifistate); //取消定时器定时
	os_timer_setfn(&checkTimer_wifistate, (os_timer_func_t *) Check_WifiState,
	NULL); //设置定时器回调函数   检查WIFI状态
	os_timer_arm(&checkTimer_wifistate, 1000, true); //启动定时器,单位:毫秒

}

void user_rf_pre_init() 
{

}

在这里插入图片描述

在这里插入图片描述

keyInitOne(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func, gokit_key_function long_press, gokit_key_function short_press)
/**
*@简短的单按钮初始化

*在这个函数中要完成单键初始化,这里需要结合ESP8266 GPIO寄存器描述文档来设置参数

*@param[in]gpio_id ESP8266 GPIO号码

*@param[in]gpio_name ESP8266 GPIO名称

*@param[in]gpio_func ESP8266 GPIO函数

*@param[in]long_press Long按回调函数地址

*@param[in]._press Short press状态回调函数地址

*@return单按钮结构指针

*/

/**
* @brief button driver initialization

* In the function to complete all the keys GPIO initialization, and open a timer to start the key state monitoring
* @param [in] keys Key Function Global structure pointer
* @return none
* /**

*@简短按钮驱动程序初始化
*在函数中完成所有密钥GPIO初始化,并打开定时器开始密钥状态监控。
*@param[in]keys键函数全局结构指针
*@无返回

*/
*/
void ICACHE_FLASH_ATTR keyParaInit(keys_typedef_t * keys)
{
    uint8 tem_i = 0; 
    
    if(NULL == keys)
    {
        return ;
         
    }
    
    //init key timer    准备按键定时器
    keys->key_timer_ms = KEY_TIMER_MS; 
    os_timer_disarm(&keys->key_timer); 
    os_timer_setfn(&keys->key_timer, (os_timer_func_t *)gokitKeyHandle, keys); //定时器回调函数
    
    keys->keyTotolNum = keyTotolNum;

    //Limit on the number keys (Allowable number: 0~12)  数字键的限制(0-12)
    if(KEY_MAX_NUMBER < keys->keyTotolNum) 
    {
        keys->keyTotolNum = KEY_MAX_NUMBER; 
    }
    
    //GPIO configured as a high level input mode  GPIO,配置为高级输入模式
    for(tem_i = 0; tem_i < keys->keyTotolNum; tem_i++) 
    {
        PIN_FUNC_SELECT(keys->singleKey[tem_i]->gpio_name, keys->singleKey[tem_i]->gpio_func); //管脚功能选择
        GPIO_OUTPUT_SET(GPIO_ID_PIN(keys->singleKey[tem_i]->gpio_id), 1); //设置GPIO属性
        PIN_PULLUP_EN(keys->singleKey[tem_i]->gpio_name); //管脚使能上拉
        GPIO_DIS_OUTPUT(GPIO_ID_PIN(keys->singleKey[tem_i]->gpio_id)); 
        
        os_printf("gpio_name %d \r\n", keys->singleKey[tem_i]->gpio_id); 
    }
    
    //key timer start   按键定时器启动
    os_timer_arm(&keys->key_timer, keys->key_timer_ms, 1); 
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
安卓APK:网络调试助手

猜你喜欢

转载自blog.csdn.net/qq_25205045/article/details/85331826