【程序】Marvell 88W8782/88W8801 WiFi模块创建或连接热点,并使用lwip2.1.3建立http服务器(20220213版)

本程序所用的单片机型号为:STM32F103RE、STM32F407ZG或STM32H743ZI。
复位引脚(PDN)应连接到STM32F1/F4的PA15引脚或STM32H7的PE6引脚。不连接PDN引脚将导致固件无法下载!如果模块上有PDN和RESET两个引脚,只需要连接PDN引脚。因为模块上的RESET引脚是悬空的,根本就没有连到芯片上。
STM32F1和F4用的晶振是8MHz,请注意检查自己的开发板,看看晶振是不是8MHz。如果是12MHz,在标准库程序中请修改system_stm32f10x.c或system_stm32f4xx.c文件,在HAL库程序中请修改common.c的clock_init函数。在F1单片机上是把PLL的倍频系数由9改成6(8×9=12×6),并在工程属性中定义HSE_VALUE=12000000。STM32H7用的晶振是25MHz。
WiFi模块SDIO接口最高支持的频率是50MHz。但STM32F1单片机本身并不支持25MHz以上的频率,经测试,36MHz频率下即使打开了DMA也会出现data underrun的错误。STM32F4开启SDIO clock bypass选项后,可以得到48MHz的频率并成功驱动WiFi模块。STM32H7的SDMMC支持25MHz以上的频率,例程中默认是48MHz频率。

程序支持连接无密码的热点以及WEP、WPA-PSK和WPA2-PSK认证类型的热点,加密方式支持TKIP和AES。WEP加密类型仅支持添加一个密钥。
程序还支持创建无密码的热点以及WPA-PSK和WPA2-PSK认证类型的热点,此时板子的IP地址默认为192.168.20.1(IPv4)和fd20::1(IPv6)。
连接热点属于STA模式,创建热点属于μAP模式。这两个模式可以同时启用。如果在LWIP上配置了IP_FORWARD选项,并在STA模式所连的路由器上配置好路由表,那么连接了μAP热点的设备就可以上网,也就是“电脑--->88W8801--->路由器--->Internet”的模式。
如果热点名称包含中文,请注意中文字符的编码。比如笔者的中文名热点"一个WiFi"是用的UTF-8编码,程序里面应该写成"\xe4\xb8\x80\xe4\xb8\xaaWIFI"。也可以用记事本将c源文件以UTF-8编码格式保存,然后直接写"一个WiFi"这个字符串。
另外,88W8801不支持Ad-Hoc点对点模式(88W8686支持)。
μAP网络接口不是lwip的默认接口,所以在μAP模式下测UDP的速度,请填写IP地址,不要填设备名。

用Keil5编写程序的时候,工程文件夹路径最好不要出现中文哦!不然代码提示可能会有问题。
程序是裸机运行的,不带操作系统,运行最新的lwip-2.1.3协议栈。
lwip2.1版本的压缩包(lwip-2.1.0.zip)中的src/netif文件夹下没有ethernetif.c了,那个文件是被移动到contrib-2.1.0.zip的examples/ethernetif文件夹下去了。

sd8801_uapsta.c是WiFi模块的固件,上电运行时必须由单片机发送给WiFi模块运行。
该固件数据非常大,为了节约程序编译下载的时间,可以运行flash_saver程序将这些数据保存到Flash固定区域(要求芯片Flash容量至少为384KB)。
然后根据串口提示,修改WiFi.h中WIFI_FIRMWAREAREA_ADDR的值(取消注释)。
这样就可以移除sd8801_uapsta.c文件,大幅度降低程序烧写时间了。

如果SDIO程序在固件下载完成后频繁出现CRC校验错误以及超时(timeout)的错误,可以将SDIO改为1位模式,并考虑将WIFI_CLOCK_FREQ的值降低,降速运行。
如果SPI程序频繁出现missed an interrupt的错误,则说明PC9内部的下拉电阻不起作用,建议在PC9引脚上外接一个阻值较小的下拉电阻。如果还是不行,则在wifi.h中将WIFI_LOWLEVEL_NOINTPIN设为1即可解决问题(也就是将中断方式改为轮询方式,这样会占用较多CPU资源)。

本程序也支持88W8782芯片,但需要将程序中的固件文件sd8801_uapsta.c替换成sd8782_uapsta.c,其他地方不用修改。88W8782和88W8801的固件内容不一样,不能混用。

Keil5工程下载地址:https://download.csdn.net/download/ZLK1214/80481025

(2023年7月9日更新)DMA用HAL库写https://blog.csdn.net/ZLK1214/article/details/131629364 

程序中的dhcpd兼容lwip2.0.3版本,但是nd6d不行(因为2.0版本lwip的raw_pcb不支持同时绑定IPv6多播地址和netif接口,只绑定IPv6多播地址的话,最后在raw_sendto发送数据包的时候lwip根本不知道从哪个netif接口发出去,从而发送失败。所以要想兼容只有重写整个程序,不用raw_pcb实现)

此版本修复了上一个版本(20200208版)存在的一些问题,主要更新如下:

1. 增大了测速器测试的数据量。TCP固定测试30秒,UDP测试18000个数据包。
  (可在测速器的network.h头文件中改为其他值,然后重新编译测速器)
2. stdio.c与common.c合并在了一起。
3. WiFi_SendCommand函数改为了允许指定待发送命令的存放位置。
4. WiFi_AllocateArgument和WiFi_FreeArgument函数分配内存由堆的形式(malloc)改成了更安全的栈的形式。
   为了降低程序理解难度,WiFi_FreeArgument和WiFi_GetSubCommandBuffer不再使用void **二级指针。
5. 串口打印里面的一些感叹号改成了句号。
6. 命令超时时间调整为14秒。
7. SDIO时钟频率提升到48MHz(最高可以跑50MHz)。
8. 初始化时执行CMD_FUNC_INIT,通过CMD_GET_HW_SPEC自动获取数据发送通道的个数,兼容88W8782和88W8801两种模块。
9. 在ethernetif.c里面添加了错误统计计数值加1的代码。
10. lwip升级到了2.1.3版本。
11. 新增WiFi_FaultHandler函数,长时间收不到广播帧就重连路由器,以免STA模式连接路由器时间长了电脑ping不通WiFi模块。
    CMD52或CMD53连续多次读写失败、数据发送通道一直不可用、命令回应超时,这些情况下可能需要重启WiFi模块才能恢复正常。
    由专门的WiFi_FaultHandler回调函数处理这些事件。
12. 使WiFi_Init可重复调用。WiFi模块死机后能在不重启单片机的情况下重新初始化WiFi模块。
    单片机进入低功耗模式前也可以关闭WiFi模块,唤醒后再重新打开WiFi模块并初始化。
13. 解决了dhcpd有可能死机的问题。新增了显示客户端名称,以及添加静态IP地址绑定的功能。

【88W8801小模块电路图】

请注意U2的左右顺序。从模块正面看,中间左边是5脚(OUT),接的是88W8801芯片,右边是2脚(IN),接的是天线。其余四个脚都是GND。

供电方式:VDD33、AVDD33和VIO都接3.3V,VDD11和AVDD18采用芯片内部LDO电源。

通信接口选择:由CON1和CON0脚共同决定。悬空是1,接下拉电阻是0。因为电路图中CON1悬空(NC),CON0用3.3kΩ的电阻下拉到地,所以CON1=1,CON0=0,选的是SDIO接口。
注意:SDIO接口自带了一个SPI模式,也可以用SPI方式通信,不用更改CON1和CON0脚。在程序中直接替换wifi_lowlevel.c文件就可以。

88W8782/88W8801 SPI方式连线
模块引脚名称SPI引脚名称I/O口
D3CS(或NSS)PC11
CLKSCKPC12
D0MISOPC8
CMDMOSIPD2
D1INTPC9
PDN(复位)PA15
RESET悬空
VCC(电源)3.3V

【88W8782小模块电路图】

【Keil5工程截图】 

【笔者所用的开发板和WiFi模块】 

STM32F103RE开发板: 

STM32F407ZG开发板:

STM32H743ZI开发板:

带底板的88W8782和88W8801 WiFi模块:

这个底板的PCB文件是淘宝卖家给的,笔者发现他的PCB上面,ANT天线和GND被铺铜误连在了一起,因此模块上这个天线是完全不起作用的,PCB文件设计上有瑕疵。他卖的模块上面三个贴片槽,只贴了中间的,而且贴的是一个电容,两边槽位都没有贴,估计就是跟ANT和GND短路了有关。

如果用的开发板上面带有SD卡槽,运行程序时,下载固件后或获取MAC地址后一直出现CRC错误和data timeout错误,可以采取下面的措施:

(1)把SDIO模式由4位数据线模式改为1位模式,只接SDIO_D0(PC8)和SDIO_D1(PC9,作为SDIO中断引脚),不接SDIO_D2~3(PC10~11) 。修改wifi_lowlevel.c中的WiFi_LowLevel_SDIOInit函数,将下面两句话注释掉,只保留SDIO_Init

/* SDIO外设的总线宽度设为4位 */
//sdio.BusWide = SDIO_BUS_WIDE_4B;
SDIO_Init(SDIO, sdio);
//WiFi_LowLevel_WriteReg(0, SDIO_CCCR_BUSIFCTRL, WiFi_LowLevel_ReadReg(0, SDIO_CCCR_BUSIFCTRL) | SDIO_CCCR_BUSIFCTRL_BUSWID_4Bit);

改为1位数据模式后,笔者上面的黑色带卡槽开发板的问题已经解决(用电脑USB口供电,串口用的是USB转TTL模块)。

(2)如果还是不行,就降低SDIO的时钟频率。打开WiFi.h,将WIFI_CLOCK_FREQ改小。如100万(1MHz),50万(500kHz),或者10万(100kHz),可以设为0(使用最低频率,也就是最高分频系数)

(3)将时钟线(SDIO_CK)连线的长度加长一倍。

不过SD卡槽里面不要插内存卡。尽管插了内存卡进去,Wi-Fi模块还是可以照常使用,但是SD卡是没法用的,SD卡正常的初始化命令序列(如CMD2、CMD3)是无法成功执行的。

虽然SDIO标准规定可以总线上可以接多张SD卡,但STM32单片机的SDIO接口只支持接一张卡,STM32F103的芯片手册Datasheet(不是参考手册)中有声明:
The current version supports only one SD/SDIO/MMC4.2 card at any one time and a stack of MMC4.1 or previous.
如果想要同时使用WiFi模块和SD内存卡,建议SD内存卡采用SPI总线通信。

【程序运行截图】

1. 串口输出

2. ping IP地址和计算机名

3. 访问http服务器

4. 将固件烧写到单片机Flash固定区域的程序(用于节约主程序烧写时间) 

5. 创建的热点

6. 测速器上位机

STM32F103RE和STM32F407VE单片机用lwip 2.1.2驱动88W8801 WiFi模块,如何提高TCP和UDP的传输速率_ZLK1214的专栏-CSDN博客_lwip提速https://blog.csdn.net/ZLK1214/article/details/1120950177. 电脑连接创建的热点

【程序运行结果】

STM32H743ZI SDMMC2 88W8801
SystemCoreClock=480000000
[Clock] freq=400.0kHz, requested=400.0kHz, divider=120
RESPCMD63, RESP1_b0ff8000
RESPCMD63, RESP1_b0300000
Number of I/O Functions: 3
Memory Present: 0
Relative Card Address: 0x0001
Card selected! RESP1_00001e00
[Clock] freq=48000.0kHz, requested=50000.0kHz, divider=1
CCCR/FBR defined in SDIO Version: 2.00
SDIO Specification Version: 2.00
SD Physical Specification Version: 2.00 (May 2006)
[CIS] func=0, ptr=0x00008000
Product Information: Marvell 802.11 SDIO ID: 48
Manufacturer Code: 0x02df
Manufacturer Information: 0x9138
Card Function Code: 0x0c
System Initialization Bit Mask: 0x00
Maximum Block Size: 256
Maximum Transfer Rate Code: 0x5a
[CIS] func=1, ptr=0x00008080
Manufacturer Code: 0x02df
Manufacturer Information: 0x9139
Card Function Code: 0x0c
System Initialization Bit Mask: 0x00
Maximum Block Size: 512
[CIS] func=2, ptr=0x00008100
[CIS] func=3, ptr=0x00008180
Firmware is successfully downloaded!
CMDRESP 0x80a9 at 32ms
CMDRESP 0x8003 at 0ms
Firmware release number: 14.76.36.p61
Firmware capability: 802.11n 802.11g 802.11b [PS] [WPA]
Number of antenna: 2
Number of multicast addresses: 64
Number of Tx ports: 12
CMDRESP 0x804d at 0ms
MAC Addr: 44:EF:BF:CB:0B:BA
IP_FORWARD is enabled
LWIP_IPV6_FORWARD is enabled
Join group FF02::1. bss=0x00
IPv6 link-local address: FE80::46EF:BFFF:FECB:BBA
Join group FF02::1. bss=0x10
IPv6 link-local address for micro AP: FE80::46EF:BFFF:FECB:BBA
IPv6 address for micro AP: FD20::1
Join group FF02::2. bss=0x10
[Send] len=86, bss=0x10, port=-1
[Send] len=86, bss=0x10, port=-1
CMDRESP 0x8006 at 435ms
SSID 'ziroom904-1', MAC 80:12:DF:90:7F:5A, RSSI 87, Channel 1
  Timestamp 2590326947538, Beacon Interval 100, TSF timestamp: 230883
  Capability: 0x0c11 (Security: WPA2, Mode: Infrastructure)
  Rates: 1.0Mbps 2.0Mbps 5.5Mbps 11.0Mbps 9.0Mbps 18.0Mbps 36.0Mbps 54.0Mbps
SSID 'CMCC-kx7H', MAC 8C:53:D2:47:38:CE, RSSI 56, Channel 4
  Timestamp 89155298141, Beacon Interval 100, TSF timestamp: 551675
  Capability: 0x0431 (Security: WPA2, Mode: Infrastructure)
  Rates: 1.0Mbps 2.0Mbps 5.5Mbps 11.0Mbps 9.0Mbps 18.0Mbps 36.0Mbps 54.0Mbps
CMDRESP 0x8006 at 435ms
CMDRESP 0x8006 at 434ms
SSID 'Oct1158-6', MAC 04:95:E6:E5:CD:A2, RSSI 52, Channel 11
  Timestamp 89156004079, Beacon Interval 100, TSF timestamp: 1322607
  Capability: 0x0511 (Security: WPA2, Mode: Infrastructure)
  Rates: 1.0Mbps 2.0Mbps 5.5Mbps 11.0Mbps 18.0Mbps 24.0Mbps 36.0Mbps 54.0Mbps
SSID 'Oct1158-2', MAC FC:D7:33:FE:D6:02, RSSI 52, Channel 11
  Timestamp 89179618233, Beacon Interval 100, TSF timestamp: 1325915
  Capability: 0x0431 (Security: WPA2, Mode: Infrastructure)
  Rates: 1.0Mbps 2.0Mbps 5.5Mbps 11.0Mbps 6.0Mbps 9.0Mbps 12.0Mbps 18.0Mbps
SSID 'Oct1158-6-2', MAC 5C:92:5E:99:76:70, RSSI 67, Channel 11
  Timestamp 88838507580, Beacon Interval 100, TSF timestamp: 1328089
  Capability: 0x0411 (Security: WPA2, Mode: Infrastructure)
  Rates: 1.0Mbps 2.0Mbps 5.5Mbps 11.0Mbps 6.0Mbps 9.0Mbps 12.0Mbps 18.0Mbps
CMDRESP 0x8006 at 219ms
Scan finished
CMDRESP 0x80b0 at 1ms
[Event] code=0x002e, bss=0x10, size=85, reason=0, mac=44:EF:BF:CB:0B:BA
AP is created
Packet forwarding mode: by host
CMDRESP 0x80b1 at 6851ms
CMDRESP 0x8028 at 0ms
CMDRESP 0x8006 at 1650ms
CMDRESP 0x80c4 at 7633ms
[Event] code=0x002e, bss=0x10, size=85, reason=0, mac=44:EF:BF:CB:0B:BA
AP is created
Packet forwarding mode: by host
CMDRESP 0x8012 at 30ms
capability=0x0431, status_code=0x0000, aid=0xc004
Waiting for authentication
[Event] code=0x0017, bss=0x00, size=77
WMM status change event occurred
Synchronizing multicast filter... (num=1)
CMDRESP 0x8010 at 0ms
Multicast filter is synchronized. num=1
[Event] code=0x002b, bss=0x00, size=10
Authenticated
[Send] len=350, bss=0x00, port=1
[Recv] len=60, bss=0x00, port=1
Join group FF02::1:FFCB:BBA. bss=0x00
[Send] len=86, bss=0x00, port=2
[Send] len=78, bss=0x00, port=3
Synchronizing multicast filter... (num=2)
CMDRESP 0x8010 at 0ms
Multicast filter is synchronized. num=2
[Send] len=86, bss=0x00, port=4
[Send] len=86, bss=0x00, port=5
[Send] len=350, bss=0x00, port=6
[Recv] len=590, bss=0x00, port=2
[Send] len=350, bss=0x00, port=7
[Recv] len=590, bss=0x00, port=3
[Send] len=42, bss=0x00, port=8
[Recv] len=60, bss=0x00, port=4
[Send] len=42, bss=0x00, port=9
[Send] len=42, bss=0x00, port=10
[Send] len=70, bss=0x00, port=11
-- Packet port 1 released at 3133ms
[Send] len=42, bss=0x00, port=1
DHCP supplied address!
IP address: 192.168.1.111
Subnet mask: 255.255.255.0
Default gateway: 192.168.1.1
DNS Server: 192.168.1.1
-- Packet port 2 released at 3021ms
[Send] len=42, bss=0x00, port=2
dns_test: IP for savannah.nongnu.org is not in cache.
Packet port 3 released at 3029ms
Packet port 4 released at 2838ms
Packet port 5 released at 2041ms
Packet port 6 released at 1544ms
Packet port 7 released at 1119ms
Packet port 8 released at 962ms
Packet port 9 released at 553ms
Packet port 10 released at 56ms
[Recv] len=142, bss=0x00, port=5
[Send] len=86, bss=0x00, port=3
[Recv] len=42, bss=0x00, port=6
[Send] len=79, bss=0x00, port=4
[Recv] len=86, bss=0x00, port=7
[Recv] len=95, bss=0x00, port=8
[Send] len=42, bss=0x00, port=5
[Send] len=99, bss=0x00, port=6
[Send] len=78, bss=0x00, port=7
[Recv] len=115, bss=0x00, port=9
DNS found IP for savannah.nongnu.org: 209.51.188.72
TCP socket is connecting to 209.51.188.72...
[Send] len=62, bss=0x00, port=8
[Recv] len=62, bss=0x00, port=10
TCP socket is connected. err=0
[Send] len=115, bss=0x00, port=9
[Recv] len=54, bss=0x00, port=11
[Recv] len=1506, bss=0x00, port=12
1452 bytes received
[Recv] len=1506, bss=0x00, port=13
1452 bytes received
[Send] len=54, bss=0x00, port=10
[Recv] len=1506, bss=0x00, port=14
1452 bytes received
[Recv] len=1506, bss=0x00, port=15
1452 bytes received
-- Packet port 11 released at 1616ms
[Send] len=54, bss=0x00, port=11
Packet port 1 released at 1616ms
Packet port 2 released at 1601ms
Packet port 3 released at 1569ms
Packet port 4 released at 1566ms
Packet port 5 released at 637ms
Packet port 6 released at 637ms
Packet port 7 released at 637ms
Packet port 8 released at 625ms
Packet port 9 released at 347ms
[Recv] len=1506, bss=0x00, port=1
1452 bytes received
[Recv] len=1506, bss=0x00, port=2
1452 bytes received
[Send] len=54, bss=0x00, port=1
[Recv] len=1506, bss=0x00, port=3
1452 bytes received
[Recv] len=1506, bss=0x00, port=4
1452 bytes received
[Send] len=54, bss=0x00, port=2
[Send] len=42, bss=0x00, port=3
IPv6 address 1: 2409:8A62:32E:3570:46EF:BFFF:FECB:BBA
DNS Server: FE80::1
dns_test: IP for savannah.nongnu.org is in cache: 209.51.188.72
TCP socket is connecting to 209.51.188.72...
[Send] len=62, bss=0x00, port=4
[Send] len=86, bss=0x00, port=5
[Recv] len=1506, bss=0x00, port=5
1452 bytes received
[Recv] len=1506, bss=0x00, port=6
1452 bytes received
[Send] len=54, bss=0x00, port=6
[Recv] len=1506, bss=0x00, port=7
1452 bytes received
[Recv] len=1506, bss=0x00, port=8
1452 bytes received
[Send] len=54, bss=0x00, port=7
[Recv] len=1506, bss=0x00, port=9
1452 bytes received
[Recv] len=1506, bss=0x00, port=10
1452 bytes received
[Send] len=54, bss=0x00, port=8
[Recv] len=1506, bss=0x00, port=11
1452 bytes received
[Recv] len=1506, bss=0x00, port=12
1452 bytes received
[Send] len=54, bss=0x00, port=9
Packet port 1 released at 579ms
Packet port 2 released at 569ms
Packet port 3 released at 490ms
Packet port 4 released at 474ms
Packet port 5 released at 396ms
Packet port 6 released at 317ms
Packet port 7 released at 306ms
Packet port 8 released at 40ms
Packet port 10 released at 903ms
Packet port 11 released at 889ms
[Recv] len=1506, bss=0x00, port=13
1452 bytes received
[Recv] len=1506, bss=0x00, port=14
1452 bytes received
[Send] len=54, bss=0x00, port=10
[Recv] len=1506, bss=0x00, port=15
1452 bytes received
[Recv] len=1506, bss=0x00, port=1
1452 bytes received
[Send] len=54, bss=0x00, port=11
[Send] len=42, bss=0x00, port=1
[Recv] len=1506, bss=0x00, port=2
1452 bytes received
[Recv] len=1506, bss=0x00, port=3
1452 bytes received
[Send] len=54, bss=0x00, port=2
[Recv] len=1374, bss=0x00, port=4
1320 bytes received
[Send] len=54, bss=0x00, port=3
[Send] len=62, bss=0x00, port=4
[Recv] len=86, bss=0x00, port=5
[Send] len=86, bss=0x00, port=5
[Recv] len=54, bss=0x00, port=6
TCP socket is closed. err=0, count=33264
[Send] len=54, bss=0x00, port=6
[Recv] len=54, bss=0x00, port=7
[Send] len=62, bss=0x00, port=7
[Recv] len=42, bss=0x00, port=8
[Send] len=42, bss=0x00, port=8
Packet port 1 released at 5027ms
Packet port 2 released at 5001ms
Packet port 3 released at 4751ms
Packet port 4 released at 3251ms
Packet port 5 released at 2965ms
Packet port 6 released at 1395ms
Packet port 7 released at 257ms
Packet port 9 released at 5566ms
Packet port 10 released at 5307ms
Packet port 11 released at 5293ms
[Recv] len=60, bss=0x00, port=9
[Send] len=62, bss=0x00, port=9
[Send] len=86, bss=0x00, port=10
[Recv] len=78, bss=0x00, port=10
[Send] len=62, bss=0x00, port=11
[Send] len=62, bss=0x00, port=1
[Send] len=62, bss=0x00, port=2
TCP socket error! err=-13
[Recv] len=60, bss=0x00, port=11
[Recv] len=60, bss=0x00, port=12

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

巨大八爪鱼

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值