《嵌入式 - 模块》RW007 WIFI模块联网与使用

Posted Bruceoxl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《嵌入式 - 模块》RW007 WIFI模块联网与使用相关的知识,希望对你有一定的参考价值。

开发环境:
RT-Thread版本:4.0.3
操作系统:Windows10
RT-Thread Studio版本:2.0.1
开发板MCU:STM32F746ZGT6U(NUCLEO-F746ZG开发板)

本文主要介绍RW007 WiFi模块的开发使用,在联网之后,再连接到ONENet,即可将本地传感器信息上传至云端。

1开发板与RW007简介

1.1开发板简介

NUCLEO-F746ZG开发板的处理器是STM32F746ZGT6U,基于ARM 32位Cortex®-M7内核,带FPU DSP指令、MPU、ST ART加速器、L1缓存、零等待周期执行、最高主频216MHz、性能高达462 DMIPS/2.14 DMIPS/MHz (Dhrystone 2.1)。

1.1 M Flash,320 k SRAM,最高32位数据总线的FMC可用于扩展SRAM, PSRAM, SDRAM/LPSDR SDRAM, NOR/NAND等。
2.支持Quad-SPI
3.8080/6800并行LCD接口,LCD-TFT控制器,最高支持XGA分辨率,带图形加速器
4.1.7 V to 3.6 V灵活电源选择,Sleep, Stop , Standby三种低功耗模式和RTC事实时钟
5.3个12位ADC ,2个12位DAC
6.18个定时器,其中包括一个低功耗定时器和2个32位定时器
7.25个通信接口,包括USART,I2C,SPI,CAN,HDMI-CEC等
8.USB2.0接口,网络接口,摄像头接口
9.随机数发生器,CRC校验

在这里插入图片描述

1.2 RW007简介

RW007 是由上海睿赛德电子科技有限公司开发的高速 WiFi 模块,模块基于 Realtek RTL8710BN(Ameba Z 系列) WIFI SOC,使用 SPI/UART 与主机通信 ,支持 IEEE 802.11b/g/n 网络、 WEP/WPA/WPA2 加密方式和 STA 和 AP 模式。

主要特性

1.Cortex-M4 高性能 MCU
2.可自由选择的 AT SPI 双模式,工作模式可由主机配置
3.SPI 时钟高达 30Mbps,UART 波特率高达 6Mbps。
4.SPI 模式下有效以太网带宽高达上传 1MBytes/s,下载 1MBytes/s
5.内置 Bootloader,支持固件升级、安全固件功能。
6.支持快速连接、airkiss 配网
7.支持存储多达 5 条连接信息

2 项目创建

为了简单起见,我这里使用RT-Thread Studio开发,关于如何使用RT-Thread Studio创建项目,请参看官方手册。

RT-Thread Studio

首先打开RT-Thread Studio,新建项目。

在这里插入图片描述

接下来选择新建“RT-Thread项目”,然后点击“下一步”。

在这里插入图片描述

接下来填写工程名,由于RT-Thread Studio没有NUCLEO-F746ZG开发板的demo工程,这里选择选择基于芯片,控制台是USART3。

在这里插入图片描述

点击“完成”,稍等片刻即可完成项目的创建。当然接下来你也可以使用MDK开发,我这里还是继续使用RT-Thread Studio开发。

在这里插入图片描述

工程创建好了,接下里就是开发工作了。
可以先尝试编译:
在这里插入图片描述

NUCLEO-F746ZG自带ST-Link下载器,编译成功后将程序下载到板子中,打开终端,打印信息如下:

在这里插入图片描述

以上信息表示创建工程成功。

3 RW007联网

RW007与MCU的电路连接示意图如下:

在这里插入图片描述

RW007与MCU具体IO连线如下:

在这里插入图片描述

从上图可以看出WiFi的接口是SPI。

STM32 引脚名封装管脚序号功能
PA55BOOT0/CLK
PA66MISO
PA77MOSI
PD1462BOOT1/CS
PD1563INT/BUSY
PF12252RESET

3.1 WiFi配置

1.配置 SPI

在这里插入图片描述

进行配置 SPI1,并生成代码,保存退出即可 。

2.配置 RW007 软件包
RT-Thread 通过软件包的形式,对 RW007 模块提供配套驱动支持,系统默认选项不包含软件包,用户需手动开启:
RT-Thread online packages —> 、IoT - internet of things —>、Wi-Fi —>,勾选 rw007: SPI WIFI rw007 driver —> 选项

在这里插入图片描述

接着进一步设置软件包参数,完成 SPI 总线和 IO 的配置,更改总线设备名称 RW007 BUS NAME 为 spi1。

在这里插入图片描述

当然啦,这里需要根据自己的板子来决定使用哪个SPI。还需要配置 SPI 控制 IO。

3.开启 WiFi 框架
RW007 驱动使用了 WLAN 相关的接口,按以下选项路径打开 WiFi 框架:
RT-Thread Components —>、Device Drivers —>、Using WiFi —>,勾选 Using Wi-Fi framework:

在这里插入图片描述

保存即可配置完成。

3.3 WiFi联网测试

一切完成后,编译,下载,打开终端。

在这里插入图片描述

这里通过wifi命令来联网。

先对周围的无线网络进行扫描,如果你知道Wii信息可以跳过该步骤:

wifi scan

在这里插入图片描述

连接网络:

wifi join ssid passwd

在这里插入图片描述

联网成功后会显示IP,接下来可以使用下WiFi相关的的其他命令。

有WiFi信息不代表联网成功,接下来ping下IP。

ping ip/域名

在这里插入图片描述

【问题】RW007 初始化失败
在这里插入图片描述

【问题分析】由于RW007的软件版本默认选择的是1.1.1,不是最新版本,固件和应用软件不匹配。

【解决办法】选择与固件匹配的软件版本即可。

3.3 WiFi联网总结

关于WiFi的底层驱动已经封装了,这部分内容也很多,主要是协议栈内容多,但是大体的流程和其他驱动一样的。

驱动的入口是wifi_spi_device_init函数,主要要RW007硬件使能。然后跳转到rt_hw_wifi_init函数中。

int wifi_spi_device_init(void)
{
    char sn_version[32];
    
    GPIO_TypeDef *cs_gpiox;
    uint16_t cs_pin;

    cs_gpiox = (GPIO_TypeDef *)((rt_base_t)GPIOA + (rt_base_t)(RW007_CS_PIN / 16) * 0x0400UL);
    cs_pin = (uint16_t)(1 << RW007_CS_PIN % 16);
    
    rw007_gpio_init();
    rt_hw_spi_device_attach(RW007_SPI_BUS_NAME, "wspi", cs_gpiox, cs_pin);
    rt_hw_wifi_init("wspi");

    rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);
    rt_wlan_set_mode(RT_WLAN_DEVICE_AP_NAME, RT_WLAN_AP);

    rw007_sn_get(sn_version);
    rt_kprintf("\\nrw007  sn: [%s]\\n", sn_version);
    rw007_version_get(sn_version);
    rt_kprintf("rw007 ver: [%s]\\n\\n", sn_version);

    return 0;
}
INIT_APP_EXPORT(wifi_spi_device_init);

rt_err_t rt_hw_wifi_init(const char *spi_device_name)
{
    static struct rt_wlan_device wlan_sta, wlan_ap;
    rt_err_t ret;
    wifi_sta.wlan = &wlan_sta;
    wifi_sta.hspi = &rw007_spi;
    wifi_ap.wlan = &wlan_ap;
    wifi_ap.hspi = &rw007_spi;
    /* align and struct size check. */
    RT_ASSERT((SPI_MAX_DATA_LEN & 0x03) == 0);

    memset(&rw007_spi, 0, sizeof(struct rw007_spi));

    rw007_spi.spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);

    if (rw007_spi.spi_device == RT_NULL)
    {
        LOG_E("spi device %s not found!\\r", spi_device_name);
        return -RT_ENOSYS;
    }

    /* config spi */
    {
        struct rt_spi_configuration cfg;
        cfg.data_width = 8;
        cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
        cfg.max_hz = RW007_SPI_MAX_HZ;             /* 15M 007 max 30M */
        rt_spi_configure(rw007_spi.spi_device, &cfg);
    }

    /* init spi send mempool */
    rt_mp_init(&rw007_spi.spi_tx_mp,
               "spi_tx",
               &rw007_spi.spi_tx_mempool[0],
               sizeof(rw007_spi.spi_tx_mempool),
               sizeof(struct spi_data_packet));

    /* init spi send mailbox */
    rt_mb_init(&rw007_spi.spi_tx_mb,
               "spi_tx",
               &rw007_spi.spi_tx_mb_pool[0],
               SPI_TX_POOL_SIZE,
               RT_IPC_FLAG_PRIO);
    
    /* init spi recv mempool */
    rt_mp_init(&rw007_spi.spi_rx_mp,
               "spi_rx",
               &rw007_spi.spi_rx_mempool[0],
               sizeof(rw007_spi.spi_rx_mempool),
               sizeof(struct spi_data_packet));

    /* init spi recv mailbox */
    rt_mb_init(&rw007_spi.spi_rx_mb,
               "spi_rx",
               &rw007_spi.spi_rx_mb_pool[0],
               SPI_RX_POOL_SIZE,
               RT_IPC_FLAG_PRIO);

    /* init spi data notify event */
    rt_event_init(&spi_wifi_data_event, "wifi", RT_IPC_FLAG_FIFO);

    rw007_spi.rw007_cmd_event = rt_event_create("wifi_cmd", RT_IPC_FLAG_FIFO);

    /* register wlan device for ap */
    ret = rt_wlan_dev_register(&wlan_ap, RT_WLAN_DEVICE_AP_NAME, &ops, 0, &wifi_ap);
    if (ret != RT_EOK)
    {
        return ret;
    }

    /* register wlan device for sta */
    ret = rt_wlan_dev_register(&wlan_sta, RT_WLAN_DEVICE_STA_NAME, &ops, 0, &wifi_sta);
    if (ret != RT_EOK)
    {
        return ret;
    }

    {
        rt_thread_t tid;

        /* Create package parse thread */
        tid = rt_thread_create("wifi_handle",
                               wifi_data_process_thread_entry,
                               &rw007_spi,
                               2048,
                               8,
                               20);
        if(!tid)
        {
            return -RT_ERROR;
        }
        rt_thread_startup(tid);

        /* Create wifi transfer thread */
        tid = rt_thread_create("wifi_xfer",
                               spi_wifi_data_thread_entry,
                               RT_NULL,
                               2048,
                               9,
                               20);
        if(!tid)
        {
            return -RT_ERROR;
        }
        rt_thread_startup(tid);
    }

    spi_wifi_hw_init();

    return RT_EOK;
}

rt_hw_wifi_init负责创建WIFI数据处理线程,函数如下:

rt_err_t rt_hw_wifi_init(const char *spi_device_name)
{
    static struct rt_wlan_device wlan_sta, wlan_ap;
    rt_err_t ret;
    wifi_sta.wlan = &wlan_sta;
    wifi_sta.hspi = &rw007_spi;
    wifi_ap.wlan = &wlan_ap;
    wifi_ap.hspi = &rw007_spi;
    /* align and struct size check. */
    RT_ASSERT((SPI_MAX_DATA_LEN & 0x03) == 0);

    memset(&rw007_spi, 0, sizeof(struct rw007_spi));

    rw007_spi.spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);

    if (rw007_spi.spi_device == RT_NULL)
    {
        LOG_E("spi device %s not found!\\r", spi_device_name);
        return -RT_ENOSYS;
    }

    /* config spi */
    {
        struct rt_spi_configuration cfg;
        cfg.data_width = 8;
        cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
        cfg.max_hz = RW007_SPI_MAX_HZ;             /* 15M 007 max 30M */
        rt_spi_configure(rw007_spi.spi_device, &cfg);
    }

    /* init spi send mempool */
    rt_mp_init(&rw007_spi.spi_tx_mp,
               "spi_tx",
               &rw007_spi.spi_tx_mempool[0],
               sizeof(rw007_spi.spi_tx_mempool),
               sizeof(struct spi_data_packet));

    /* init spi send mailbox */
    rt_mb_init(&rw007_spi.spi_tx_mb,
               "spi_tx",
               &rw007_spi.spi_tx_mb_pool[0],
               SPI_TX_POOL_SIZE,
               RT_IPC_FLAG_PRIO);
    
    /* init spi recv mempool */
    rt_mp_init(&rw007_spi.spi_rx_mp,
               "spi_rx",
               &rw007_spi.spi_rx_mempool[0],
               sizeof(rw007_spi.spi_rx_mempool),
               sizeof(struct spi_data_packet));

    /* init spi recv mailbox */
    rt_mb_init(&rw007_spi.spi_rx_mb,
               "spi_rx",
               &rw007_spi.spi_rx_mb_pool[0],
               SPI_RX_POOL_SIZE,
               RT_IPC_FLAG_PRIO);

    /* init spi data notify event */
    rt_event_init(&spi_wifi_data_event, "wifi", RT_IPC_FLAG_FIFO);

    rw007_spi.rw007_cmd_event = rt_event_create("wifi_cmd", RT_IPC_FLAG_FIFO);

    /* register wlan device for ap */
    ret = rt_wlan_dev_register(&wlan_ap, RT_WLAN_DEVICE_AP_NAME, &ops, 0, &wifi_ap);
    if (ret != RT_EOK)
    {
        return ret;
    }

    /* register wlan device for sta */
    ret = rt_wlan_dev_register(&wlan_sta, RT_WLAN_DEVICE_STA_NAME, &ops, 0, &wifi_sta);
    if (ret != RT_EOK)
    {
        return ret;
    }

    {
        rt_thread_t tid;

        /* Create package parse thread */
        tid = rt_thread_create("wifi_handle",
                               wifi_data_process_thread_entry,
                               &rw007_spi,
                               2048,
                               8,
                               20);
        if(!tid)
        {
            return -RT_ERROR;
        }
        rt_thread_startup(tid);

        /* Create wifi transfer thread */
        tid = rt_thread_create("wifi_xfer",
                               spi_wifi_data_thread_entry,
                               RT_NULL,
                               2048,
                               9,
                               20);
        if(!tid)
        {
            return -RT_ERROR;
        }
        rt_thread_startup(tid);
    }

    spi_wifi_hw_init();

    return RT_EOK;
}

后面就是进行WIFI 的连接断开,扫描等操作。

关于WiFi的更多信息,请参看官方手册:

WiFi

完整代码地址




欢迎访问我的网站

BruceOu的哔哩哔哩
BruceOu的主页
BruceOu的博客
BruceOu的CSDN博客
BruceOu的简书


欢迎订阅我的微信公众号

在这里插入图片描述

以上是关于《嵌入式 - 模块》RW007 WIFI模块联网与使用的主要内容,如果未能解决你的问题,请参考以下文章

《嵌入式 - 模块》RW007 WIFI模块联网与使用

《嵌入式 - 模块》RW007 WIFI模块联网与使用

RW007系列综合实战2使用RW007模块连接小米蓝牙温湿度计2代

RW007系列连载1RW007-BLE主机通信使用学习示例与综合Demo

RW007系列综合实战1STM32+RW007实现BLE透传功能

物联网无线串口WiFi模块,智能生活无线应用,无线WiFi模组技术