本文共 5125 字,大约阅读时间需要 17 分钟。
记一个惨痛教训,务必记得即时保存文件。(这次不是丢了,而是无法build)。切记,切记,eclipse修改后务必ctrl+s然后clean 然后再build!
了解SDK开发的STA模式操作方法,熟悉相关API函数。
1、wifi_get_opmode
可以说讲的十分清楚了, 那我们就来看一下我们模块现在的模式吧。
/* * user_main.c * * Created on: 2018年1月3日 * Author: CLAY */#include "user_main.h" #include "driver/uart.h" //串口0需要的头文件void user_init(){ uint8 wifimode; uart_init(115200,115200); wifimode = wifi_get_opmode(); os_printf("\r\n当前模式是 : %d\r\n", wifimode);}void user_rf_pre_init(){}
关于”user_main.h”,这个是我自定义的文件在 app/include 中,这样以后需要哪个头文件直接往这里面一扔,然后只需要引用”user_main.h”就行了。。。
编译,有一个错误。关于os_printf
的头文件是在 os_api.h
中。
uart0 和 uart1 学习
曾在也提到过一点相关的东西。
8266有两个串口,UART0和UART1,UART1在GPIO2相当于TXD1!主要和os_printf从哪里输出有关,但无论哪个,下载程序还是用UART0。
app/driver/uart.c
332行当我加了注释并下载完成程序后,串口显示为:
换成TX1后,
哈哈,,get到一个新技能吧。
相关手册上看到,分享: 密码:yc6y
还有这个,
[Question]: RTS 和 CTS 以前也见过相关的知识点,以后补充上吧。
有一个感觉也会用到的,先记录下先。。
2、wifi_set_mode & wifi_set_mode_current
1->station 模式
2->AP模式 3->STA+AP模式然后两者比较
测试代码
/* * user_main.c * * Created on: 2018年1月3日 * Author: CLAY */#include "user_main.h"#include "driver/uart.h" //串口0需要的头文件void user_init(){ uint8 opmode; uart_init(115200,115200); opmode = wifi_get_opmode(); os_printf("\r\n当前模式是 : %d\r\n", opmode); wifi_set_opmode_current(0x01); opmode = wifi_get_opmode(); os_printf("\r\n当前模式为 :%d\r\n", opmode);}void user_rf_pre_init(){}
也可以知道,current不保存到flah中。
再来看看另一个
验证是如我所料。
3、wifi_station_scan
获取当前环境中的ap
要特别注意,
不能在user_int中调用,必须在系统初始化完成后,并且station使能的情况下(也就是说处于AP+STA或者STA模式下才能使用)
那么,问题就来了。啥时候初始化完成呢?如何知道初始化是否完成呢?
这就引入了 回调函数 —-
system_init_done_cb
看这个函数。
4、wifi_station_get_connect_status
上个整套的代码吧,边理解注释边学习上面提到的函数用法!
/* * user_main.c * * Created on: 2018年1月3日 * Author: CLAY */#include "user_main.h"#include "driver/uart.h" //串口0需要的头文件void ICACHE_FLASH_ATTRWifi_conned(void *arg){ static uint8 count=0; uint8 status; os_timer_disarm(&connect_timer);//这里先把定时器关了,一旦连上或者超过七次没连上,就不再重复打印了。 count++; status = wifi_station_get_connect_status(); if(status == STATION_GOT_IP) { os_printf("WIFI Connect success\r\n"); return; } else { if(count >= 7) { os_printf("WIFI Connect Fail\r\n"); return;//if忘了包含return,然后导致不会打印上面这两个。。 } } os_timer_arm(&connect_timer,2000,NULL);//重新打开定时器}void ICACHE_FLASH_ATTRscan_done(void *arg, STATUS status)//扫描完成的回调函数 scan_done(这个有意思了,arg是以链表的形式存在的。){ uint8 ssid[33]; struct station_config stationConf; if (status == OK) { struct bss_info *bss_link = (struct bss_info *)arg; //链表指针 bss_link = bss_link->next.stqe_next;//ignore first while (bss_link != NULL) { os_memset(ssid, 0, 33); //memset 初始化数组 if (os_strlen(bss_link->ssid) <= 32) { os_memcpy(ssid, bss_link->ssid, os_strlen(bss_link->ssid)); } else { os_memcpy(ssid, bss_link->ssid, 32); } os_printf("+CWLAP:(%d,\"%s\",%d,\""MACSTR"\",%d)\r\n", bss_link->authmode, ssid, bss_link->rssi, MAC2STR(bss_link->bssid),bss_link->channel); bss_link = bss_link->next.stqe_next; } os_memcpy(&stationConf.ssid, "6103", 32); //0s_memcpy 内存拷贝函数 32表示拷贝前32个字符 os_memcpy(&stationConf.password, "12346103", 64); wifi_station_set_config_current(&stationConf); wifi_station_connect(); //这个函数当上一个函数不是在user_int中调用,在其他地方都需要加上这句connect os_timer_setfn(&connect_timer,Wifi_conned,NULL); //定时器回调函数(当定时器时间到了该怎么办?进行回调) os_timer_arm(&connect_timer,2000,NULL); //每隔2s 去检测是否真的连接上。 } else { // os_sprintf(temp,"err, scan status %d\r\n", status); // uart0_sendStr(temp); }}void to_scan(void){ wifi_station_scan(NULL,scan_done);}void user_init(){ uint8 opmode; uart_init(115200,115200); wifi_set_opmode(0x03); opmode = wifi_get_opmode(); os_printf("\r\n当前模式是 : %d\r\n", opmode); wifi_set_opmode_current(0x01); opmode = wifi_get_opmode(); os_printf("\r\n当前模式为 :%d\r\n", opmode); //wifi_set_opmode(STATION_MODE); system_init_done_cb(to_scan);//初始化完成后的回调函数}void user_rf_pre_init(){}
还有我的user_main.h
/* * user_main.h * * Created on: 2018年1月3日 * Author: CLAY */#ifndef APP_INCLUDE_USER_MAIN_H_#define APP_INCLUDE_USER_MAIN_H_#include "osapi.h" //os_printf所需要的头文件#include "user_interface.h"ETSTimer connect_timer;#endif /* APP_INCLUDE_USER_MAIN_H_ */
关于上面的程序,其实大部分参考了人家AT的程序。不过不丢人,刚开始学嘛,能变成自己的东西就好!搬运工也只是暂时的!
寻找相关程序路径:
at_init()
-> system_os_task(at_procTask......)
->
zt_cmdprocess
->at_fun
(这个数组,at指定都在这, 找到我们想要参考的,Cwlap) ->at_exeCmcCwlap
->这样就能参考人家的代码了。。。 ->wifi_station_scan
-> scan_done
-> 特别是用到链表那一点,又复习了一波链表的知识,嘻嘻。。。
()不行了,2018年1月3日18:36:24。。午饭也没吃。。饿死了。先去吃个饭,回来接着写。嘿嘿嘿。。。
1、关于wifi几个常用的数组名
1、auth_mode 加密模式(枚举类型)
2、SSID - WIFI名字
3、rssi - 信号强度单位db
4、bssid MAC地址
5、channel 信道
2、宏 ICACHE_FLASH_ATTR的妙用
其实我们可以在很多函数顶头看到这个宏的,比如,
那么,这个宏到底是啥意思呢?添加这个宏后,讲存放在 irom中,(其实就是ROM嘛)。CPU仅在调用它们的时候,将它们读到cache中运行。没有添加这个宏的函数,一上电便被加载到iram中(其实就是RAM嘛)。
由于空间受限,定无法将所有函数都放到iram中,因此大部分函数钱都要加上“ICACHE_FLASH_ATTR”这个宏,否则ram挤爆了,就会错误了。
需要注意的
不要在GPIO或者UART中断中调用带有这种宏的函数,否则将引起异常。