- 程序流程图:
- 调用AT源码扫描附近ap的函数:
static 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;
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);
uart0_sendStr(temp);
bss_link = bss_link->next.stqe_next;
}
at_backOk;
}
else
{
// os_sprintf(temp,"err, scan status %d\r\n", status);
// uart0_sendStr(temp);
at_backError;
}
specialAtState = TRUE;
at_state = at_statIdle;
}
- 修改代码:(如果扫描结果ok,使LED灯亮,串口输出ap信息,否则关闭LED,输出错误信息)
LOCAL os_timer_t scanAP_timer; //定义一个定时器变量用来储存定时器对象
static void ICACHE_FLASH_ATTR
scan_done(void *arg, STATUS status)
{
uint8 ssid[33]; //定义了33个无符号字符型的数组,WiFi名字的一个数组 ,(typedef unsigned char uint8;)
char temp[128];
unsigned int i=1;//用来显示扫描出AP的个数
if (status == OK)
{
//定义一个struct bss_info类型数据的指针变量bss_link,并将指针变量arg强制转换为struct bss_info类型的指针
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_strlen封装 C语言函数,计算字符串长度。返回 字符串长度
{
os_memcpy(ssid, bss_link->ssid, os_strlen(bss_link->ssid));
}
else
{
os_memcpy(ssid, bss_link->ssid, 32);
}
os_sprintf(temp,"AP%d:(%d,\"%s\",%d,\""MACSTR"\",%d)\r\n",//字符串格式化命令,把格式化的数据写入某个字符串中(当前一个ap的信息)
i, //ap个数
bss_link->authmode, ssid, bss_link->rssi,
MAC2STR(bss_link->bssid),bss_link->channel);
uart0_sendStr(temp); //将字符串发送给UART0口
bss_link = bss_link->next.stqe_next;//下一个ap的信息
i++;
}
GPIO_OUTPUT_SET(GPIO_ID_PIN(2), 0);//打开LED
os_printf("ok!\r\n");
}
else
{
os_sprintf(temp,"err, scan status %d\r\n", status);//显示错误信息
uart0_sendStr(temp);
os_printf("error!\r\n");
GPIO_OUTPUT_SET(GPIO_ID_PIN(2), 1);//关闭LED
}
}
4.user_main.c的全部程序
#include "c_types.h" //数据类型定义
#include "user_interface.h"
#include "osapi.h"
#include "gpio.h"
#include "eagle_soc.h"
/*GPIO 相关接口位于 /ESP8266_NONOS_SDK/include/eagle_soc.h & gpio.h。*/
//#include "eagle_soc.h"
//#include "gpio.h"
/*GPIO 相关接口位于 /ESP8266_NONOS_SDK/include/eagle_soc.h & gpio.h。*/
/**************************************************************************
* 对于 ESP8266_NONOS_SDK_v1.5.2 至 ESP8266_NONOS_SDK_v2.2.1 之间的版
* 本,请在 user_main.c 增加函数 void user_rf_pre_init(void) 和 uint32
* user_rf_cal_sector_set(void),可参考 IOT_Demo 的 user_main.c。用户可在
* user_rf_pre_init中配置 RF初始化,RF设置接口为 system_phy_set_rfoption,
* 或者在 Deep-sleep(深度睡眠)前调用 system_deep_sleep_set_option。如果设置为 RF不打
* 开,则 ESP8266 Station 及 SoftAP均无法使用,请勿调用 Wi-Fi 相关接口及网络功
* 能。RF 关闭时,Wi-Fi 射频功能和网络堆栈管理API 均无法使用。
***************************************************************************/
uint32 priv_param_start_sec;
/******************************************************************************
* FunctionName : user_rf_cal_sector_set <-- 将 RF参数设置存放在 Flash倒数第 5个扇区
* 功能 :用户自定义 RF_CAL 参数存放在 Flash 的扇区号
* 注意 : • 用户必须在程序中实现此函数,否则编译链接时会报错。但用户程序无需调用此函数,SDK
* 底层会调用它,将 RF_CAL 参数保存在用户指定的 Flash 扇区里,这将占用用户参数区的⼀一个扇区。
* • SDK 预留的 4个扇区的系统参数区已经使用,因此 RF_CAL 参数需要占用到用户参数区的空
* 间,由用户通过此函数设置⼀一个可用扇区供 SDK 底层使用。
* • 建议整个系统需要初始化时,或需要重新进行RF_CAL 时,烧录 blank.bin 初始化 RF_CAL 参
* 数区,并烧录 esp_init_data.bin。注意,esp_init_data.bin 至少需要烧录⼀一次。
* Parameters(参数) : none
* Returns(返回) : rf cal sector(存储 RF_CAL 参数的 Flash 扇区号
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR
/* 应用函数在定义时建议添加 ICACHE_FLASH_ATTR 宏,相应程序将存放在 flash 中,被
调用时才加载到 cache运行。而如果添加了IRAM_ATTR 宏的函数,则会在上电启动
时就加载到 iRAM(internal ram:内部RAM,指的是集成到SoC内部的RAM)中。*/
user_rf_cal_sector_set(void)
{
enum flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
priv_param_start_sec = 0x3C;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
priv_param_start_sec = 0x7C;
break;
case FLASH_SIZE_16M_MAP_512_512:
rf_cal_sec = 512 - 5;
priv_param_start_sec = 0x7C;
break;
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
priv_param_start_sec = 0xFC;
break;
case FLASH_SIZE_32M_MAP_512_512:
rf_cal_sec = 1024 - 5;
priv_param_start_sec = 0x7C;
break;
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
priv_param_start_sec = 0xFC;
break;
case FLASH_SIZE_64M_MAP_1024_1024:
rf_cal_sec = 2048 - 5;
priv_param_start_sec = 0xFC;
break;
case FLASH_SIZE_128M_MAP_1024_1024:
rf_cal_sec = 4096 - 5;
priv_param_start_sec = 0xFC;
break;
default:
rf_cal_sec = 0;
priv_param_start_sec = 0;
break;
}
return rf_cal_sec;
}
void ICACHE_FLASH_ATTR
user_rf_pre_init(void)
{
}
/******************************************************************************
* FunctionName : user_init
* 描述: 是上层程序的入口函数,给用户提供⼀一个初始化接口,用户可在
* 该函数内增加硬件初始化、网络参数设置、定时器初始化等功能。
* Parameters : none
* Returns : none
*******************************************************************************/
LOCAL os_timer_t scanAP_timer; //定义一个定时器变量用来储存定时器对象
static void ICACHE_FLASH_ATTR
scan_done(void *arg, STATUS status)
{
uint8 ssid[33]; //定义了33个无符号字符型的数组,WiFi名字的一个数组 ,(typedef unsigned char uint8;)
char temp[128];
unsigned int i=1;//用来显示扫描出AP的个数
if (status == OK)
{
//定义一个struct bss_info类型数据的指针变量bss_link,并将指针变量arg强制转换为struct bss_info类型的指针
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_strlen封装 C语言函数,计算字符串长度。返回 字符串长度
{
os_memcpy(ssid, bss_link->ssid, os_strlen(bss_link->ssid));
}
else
{
os_memcpy(ssid, bss_link->ssid, 32);
}
os_sprintf(temp,"AP%d:(%d,\"%s\",%d,\""MACSTR"\",%d)\r\n",//字符串格式化命令,把格式化的数据写入某个字符串中(当前一个ap的信息)
i, //ap个数
bss_link->authmode, ssid, bss_link->rssi,
MAC2STR(bss_link->bssid),bss_link->channel);
uart0_sendStr(temp); //将字符串发送给UART0口
bss_link = bss_link->next.stqe_next;//下一个ap的信息
i++;
}
GPIO_OUTPUT_SET(GPIO_ID_PIN(2), 0);//打开LED
os_printf("ok!\r\n");
}
else
{
os_sprintf(temp,"err, scan status %d\r\n", status);//显示错误信息
uart0_sendStr(temp);
os_printf("error!\r\n");
GPIO_OUTPUT_SET(GPIO_ID_PIN(2), 1);//关闭LED
}
}
void scanAP_cb(void){//设置定时器回调函数
wifi_station_scan(NULL,scan_done);//扫描附近ap的信息//每5s重新扫描附近的ap信息
}
void ICACHE_FLASH_ATTR
init_cb(void){
wifi_station_disconnect();//关闭ap
// wifi_station_scan(NULL,scan_done);//扫描附近ap的信息
}
void ICACHE_FLASH_ATTR
user_init(void)
{
wifi_set_opmode(0x01);//Station 模式
os_timer_disarm (&scanAP_timer);//先关闭定时器
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
GPIO_OUTPUT_SET(GPIO_ID_PIN(2), 1);//先关闭LED
os_timer_setfn(&scanAP_timer,(os_timer_func_t *)scanAP_cb,NULL);//设置定时器回调函数
os_timer_arm(&scanAP_timer,5000,1);//使能毫秒定时器,每5s扫描一次ap
system_init_done_cb(init_cb);//等到系统完成初始化就扫描,扫描获取所有可用AP的信息
}