ESP8266--学习笔记(二)扫描、连接WiFi

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_28877125/article/details/62319191

  经过上次的HelloWorld,我们知道了其实ESP8266其实是里面有个单片机的模块,我的操作其实就是操作里面的单片机,因为是单片机所以里面会有各种内置的外设,而我们的重点是使用WiFi,所以就直接操作WIFI了。


特别需要注意的一个宏:

  • ICACHE_FLASH_ATTR

 添加了这个宏的函数就会存放到ROM里面去,CPU仅在调用的时候才将它们读到cache(缓存)中运行,没有添加这个宏的函数将一开始上电就运行在RAM中;由于模块的空间有限,我们无法将所有的代码都一次性加载到RAM中去运行,因此在大部分函数前添加这个特殊的宏。
 需要注意的是不要在GPIO或UART中断处理函数中调用带有“ICACHE_FLASH_ATTR”宏的函数,否则将引起异常。


扫描WiFi、连接

 还是在app文件夹下面新建一个user_main.c文件,并写好

  • void user_init(){} //入口函数
  • void user_rf_pre_init(){} //必须函数

然后在入口函数里面写业务逻辑代码。
一、方法一
 怎么写呢?没思路的话就看at-firmware固件源码吧,因为at-firmware固件就是接受外面传进来的AT指令来执行的,那么,我们就可以看着它的代码来完成我们的扫描WiFi的功能,AT指令为AT+CWLAP

入口函数为:
这里写图片描述

可以看到“ICACHE_FLASH_ATTR”修饰的功能函数包含了两种任务,接受任务(at_recvTask)和处理任务(at_procTask)
这里写图片描述
进入处理任务中去。。。。

二、方法二
还可以根据,工作流程来:

  • 使用wifi_set_opmode函数设置为AP模式
  • 等到系统初始化完成后使用wifi_station_scan函数扫描WiFi
  • 然后再使用wifi_station_connect()函数连接WIFI
//步骤一
void user_init(){
    uint8 opmode;
    uart_init(115200,115200);
    wifi_set_opmode(0x03);//设置为soft-AP兼station模式
    opmode = wifi_get_opmode_default();
    os_printf("\r\n当前的工作模式:%d\r\n",opmode);
    system_init_done_cb(to_scan);//等到系统完成初始化就扫描
}
//步骤二
void to_scan(void)  {
     wifi_station_scan(NULL,scan_done); 
 }
 //步骤三
 void ICACHE_FLASH_ATTR scan_done(void *arg,STATUS status){

     uint8 ssid[33];
      char temp[128];
      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);
           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_sprintf(temp,"+CWLAP:(%d,\"%s\",%d,\""MACSTR"\",%d)\r\n",
                      bss_link->authmode, ssid, bss_link->rssi,
                      MAC2STR(bss_link->bssid),bss_link->channel);
           os_printf("%s",temp);
           bss_link = bss_link->next.stqe_next;
         }
         //扫描完成以后就开始连接WiFi了
       }
       else
       {
     //     os_sprintf(temp,"err, scan status %d\r\n", status);
     //     uart0_sendStr(temp);
        os_printf("%s","Error");
       }
}

等到扫描完成以后,就可以设定连接WiFi了,在scan_done()扫描函数中添加如下代码,

//扫描完成以后就开始连接WiFi了
os_memcpy(&stationConf.ssid, "MERCURY_6398", 32);//WiFi名字加入到配置中去
os_memcpy(&stationConf.password, "123456789", 64);//WiFi密码加入到配置中去
wifi_station_set_config_current(&stationConf);//将设置好的配置加入到配置函数中去
wifi_station_connect();//在非user_init()入口函数中连接WiFi,需要调用这个函数
os_timer_setfn(&connect_timer,Wifi_conned,NULL);//调用自己写的WiFi连接函数
os_timer_arm(&connect_timer,2000,NULL);//设置连接WiFi定时器

自己写的扫描函数

void ICACHE_FLASH_ATTR Wifi_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!");
        return;
    }else{
        if(count>=7){
        os_printf("Wifi connect fail!");
        return;
        }
    }
    os_timer_arm(&connect_timer,2000,NULL);
}

于是就完成了扫描连接的所有功能。

user_main.c的所有代码


ETSTimer connect_timer;
void ICACHE_FLASH_ATTR Wifi_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!");
        return;
    }else{
        if(count>=7){
        os_printf("Wifi connect fail!");
        return;
        }
    }
    os_timer_arm(&connect_timer,2000,NULL);
}

void ICACHE_FLASH_ATTR scan_done(void *arg,STATUS status){

     uint8 ssid[33];
      char temp[128];
      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);
           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_sprintf(temp,"+CWLAP:(%d,\"%s\",%d,\""MACSTR"\",%d)\r\n",
                      bss_link->authmode, ssid, bss_link->rssi,
                      MAC2STR(bss_link->bssid),bss_link->channel);
           os_printf("%s",temp);
           bss_link = bss_link->next.stqe_next;
         }
         //扫描完成以后就开始连接WiFi了
        os_memcpy(&stationConf.ssid, "MERCURY_6398", 32);
        os_memcpy(&stationConf.password, "123456789", 64);
        wifi_station_set_config_current(&stationConf);
        wifi_station_connect();
        os_timer_setfn(&connect_timer,Wifi_conned,NULL);//调用WiFi连接函数
        os_timer_arm(&connect_timer,2000,NULL);
       }
       else
       {
     //     os_sprintf(temp,"err, scan status %d\r\n", status);
     //     uart0_sendStr(temp);
        os_printf("%s","Error");
       }
}
void to_scan(void)  { wifi_station_scan(NULL,scan_done); }

void user_init(){
    uint8 opmode;
    uart_init(115200,115200);
    wifi_set_opmode(0x03);//设置为soft-AP兼station模式
    opmode = wifi_get_opmode_default();
    os_printf("\r\n当前的工作模式:%d\r\n",opmode);
    system_init_done_cb(to_scan);
}

void user_rf_pre_init(){}

————————————————————

后记:
 从其他地方也看到了,扫描ESP8266扫描WiFi的代码,放到这里参考一下:
扫描的套路都是一样的

void ICACHE_FLASH_ATTR
scan_done(void *arg, STATUS status)
{
  uint8 ssid[33];
  char temp[128];

  if (status == OK)
  {
    struct bss_info *bss_link = (struct bss_info *)arg;

    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);
      }
      os_printf("(%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;
    }
  }
  else
  {
     os_printf("scan fail !!!\r\n");
  }

}

void ICACHE_FLASH_ATTR
user_scan(void)
{
   if(wifi_get_opmode() == SOFTAP_MODE)
   {
     os_printf("ap mode can't scan !!!\r\n");
     return;
   }
   wifi_station_scan(NULL,scan_done);

}

void user_init(void)
{
    os_printf("SDK version:%s\n", system_get_sdk_version());

   //Set softAP + station mode
   wifi_set_opmode(STATIONAP_MODE);

   // wifi scan has to after system init done.
   system_init_done_cb(user_scan);

}

这里就是扫描特定的WiFi名字,然后代码要这样设定:比如要扫描一个为ESP8266的WiFi名字

void ICACHE_FLASH_ATTR
user_scan(void)
{
   if(wifi_get_opmode() == SOFTAP_MODE)
   {
     os_printf("ap mode can't scan !!!\r\n");
     return;
   }
   struct scan_config config;

   os_memset(&config, 0, sizeof(config));

   config.ssid = "ESP8266";

   wifi_station_scan(&config,scan_done);

}
展开阅读全文

没有更多推荐了,返回首页