ESP8266-SDK开发入坑(四)- STATION模式

记一个惨痛教训,务必记得即时保存文件。(这次不是丢了,而是无法build)。切记,切记,eclipse修改后务必ctrl+s然后clean 然后再build!


1、实验目的

了解SDK开发的STA模式操作方法,熟悉相关API函数。

2、函数解读


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到一个新技能吧。

这里写图片描述

相关手册上看到,分享:https://pan.baidu.com/s/1hs7xZTi 密码: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

这里写图片描述


3、代码展示

上个整套的代码吧,边理解注释边学习上面提到的函数用法!

/*
 * user_main.c
 *
 *  Created on: 2018年1月3日
 *      Author: CLAY
 */

#include "user_main.h"
#include "driver/uart.h"  //串口0需要的头文件

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\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_ATTR
scan_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 ->


特别是用到链表那一点,又复习了一波链表的知识,嘻嘻。。。
当时大一学的C的链表记录,哈哈哈

不行了,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中断中调用带有这种宏的函数,否则将引起异常。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值