用esp8266连接路由器时,要设置成station工作模式,然后配置好热点名字 和密码就可以连接了。
那我们首先 讲一下8266的工作模式。
1、esp8266的工作模式
首先,我们 去乐鑫官网下载SDK编程手册,如下
《2C-ESP8266__SDK__Programming Guide__CN_v1.2.0.pdf》
打开SDK编程手册,如下图,找到wifi_get_opmode函数
如图esp8266的WiFi工作模式有3种,下面是获取工作模式的程序,
void ICACHE_FLASH_ATTR user_init() //程序入口
{
uint8 opmode;
uart_init(115200,115200);
||模式查看函数
opmode = wifi_get_opmode();
||打印当前的模式
os_printf("\r\n当前模式为:%d\r\n", opmode);
//uart0_sendStr("\r\n Hello world!\r\n");
}
注意os_printf函数在"osapi.h"中,昨天我们已经设置为串口1输出,默认为串口0(开发板标号为D4的脚为串口1输出脚)。
2、ICACHE_FLASH_ATTR宏定义
细心的同学已经注意到了,上面的程序 用了一个宏ICACHE_FLASH_ATTR 来修饰user_init() 函数,那这个宏到底有什么用呢?
由于空间有限,我们无法将所有代码都一次性加载到IRAM中运行,因此大部分函数放在IROM中,运行时再加载到IRAM中。
(1)对于ESP8266_NONOS_SDK, 加了“ICACHE_FLASH_ATTR”宏的函数,将存放在IROM中,CPU仅在调用到它们的时候,将它们读到缓存中运行; 没有加“ICACHE_FLASH_ATTR”宏的函数,将在一开始上电运行时,就加载到IRAM中运行; 注意,不要在中断函数中调用带有ICACHE_FLASH_ATTR函数,因为它可能与闪存R / W操作冲突。 |
(2)对于ESP8266_RTOS_SDK 函数默认都存放在IROM中,所以无需再添加“ICACHE_FLASH_ATTR”宏。 中断处理函数也是可以定义在IROM中。 如果需要将一些频繁调用的函数定义在IRAM中,在函数前添加“IRAM_ATTR”宏就可以。 |
我现在使用的是ESP8266_RTOS_SDK,所以加和不加这个宏都可以。
3、扫描WIFI
esp8266设置为station模式,并在初始化完成后调用WiFi扫描函数。程序如下:
void ICACHE_FLASH_ATTR scan_done(void *arg, STATUS status)
{
uint8 ssid[33];
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);
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);
}
||输出AP的信息
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;
}
}
}
void ICACHE_FLASH_ATTR scan_wifi(void) {
||获取 AP 的信息
wifi_station_scan(NULL, scan_done);
}
void user_init() //程序入口
{
uint8 opmode;
uart_init(115200,115200);
opmode = wifi_get_opmode();
os_printf("\r\n当前模式为:%d\r\n", opmode);
||设置模式为station模式
wifi_set_opmode (0x01);
opmode = wifi_get_opmode();
os_printf("\r\n当前模式为:%d\r\n", opmode);
//uart0_sendStr("\r\n Hello world!\r\n");
||初始化完成后注册回调函数scan_wifi
system_init_done_cb(scan_wifi);
}
编译、下载后, 串口1输出的信息如下图:
+CWLAP:(4,"TP-LINK_501",-68,"dc:fe:18:05:da:da",6)
第一个4表示加密类型,
"TP-LINK_501"为WiFi热点名字,
-68为信号强度,
"dc:fe:18:05:da:da"为mac地址,
最后一个6为信道号。
4、连接路由与定时器的用法
设置 WiFi密码,用esp8266连接路由,使用定时器查看是否连接成功,超时返回连接失败。
定时器使用的函数如下:
||定义一个定时器变量
ETSTimer connect_timer;
||设置定时器回调函数
os_timer_setfn(&connect_timer, Wifi_conned, NULL);
||使能定时器
os_timer_arm(&connect_timer, 2000, NULL);
||关闭定时器,
os_timer_disarm(&connect_timer);
路由器wifi连接程序如下
||定义结构体stationConf
struct station_config stationConf;
||连接的路由器
os_memcpy(&stationConf.ssid, "TP-LINK", 32);
||密码
os_memcpy(&stationConf.password, "123******", 64);
||wifi来连接的接口配置。sdk有例子
wifi_station_set_config(&stationConf);
||wifi连接函数
wifi_station_connect();
||定时器回调函数
os_timer_setfn(&connect_timer, Wifi_conned, NULL);
||定时器2s扫描一次
os_timer_arm(&connect_timer, 2000, NULL);
定时器回调函数为:
void ICACHE_FLASH_ATTR Wifi_conned(void *arg)
{
static uint8 count = 0; //定变量
uint8 status; //定变量
||关闭定时器connect_timer
os_timer_disarm(&connect_timer);
count++;
||查询连接的状态函数输出
status = wifi_station_get_connect_status();
||判断连接状态
if (status == STATION_GOT_IP)
{ ||输出连接成功
os_printf("Wifi connect success!");
return;
} else {
||判断连接次数
if (count >= 7){
||输出连接失败
os_printf("Wifi connect fail!");
return;
}
}
||使能定时器connect_timer
os_timer_arm(&connect_timer, 2000, NULL);
}
程序下载后,连接路由成功后打印的信息如下图:
好了,今天就讲这么多,明天继续。
原创不易,如果你喜欢我的公众号、觉得我 文章对你有所启发,
请务必“点赞、收藏、转发”,这对我很重要,谢谢!
欢迎订阅 嵌入式小书虫