stm32 esp8266一键配网详细程序
时间: 2023-11-07 07:12:28 浏览: 285
基于STM32+ESP8266设计智能锁(支持微信小程序一键配网连接腾讯云平台).7z
5星 · 资源好评率100%
以下是 STM32 和 ESP8266 实现一键配网的详细程序:
首先,在 STM32 中初始化串口和 WiFi 模块,然后发送 AT 指令进行 WiFi 模块的初始化。
```c
/* STM32 串口初始化 */
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* 串口时钟初始化 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* 串口引脚初始化 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 将 PA9 和 PA10 引脚设置为复用功能 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
/* 配置 USART1 参数 */
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
/* 开启 USART1 */
USART_Cmd(USART1, ENABLE);
/* ESP8266 模块初始化 */
USART_SendString("AT+RST\r\n"); // 重启 WiFi 模块
Delay(1000);
USART_SendString("AT+CWMODE=2\r\n"); // 设置为 AP 模式
Delay(1000);
```
然后,配置 WiFi 模块为 AP 模式,并设置 SSID 和密码。
```c
/* 设置 AP 模式 */
USART_SendString("AT+CWMODE=2\r\n");
Delay(1000);
/* 设置 SSID 和密码 */
USART_SendString("AT+CWSAP=\"SSID\",\"password\",1,0\r\n");
Delay(1000);
```
接下来,实现一键配网的功能。首先,创建一个 TCP 服务器,并等待客户端连接。
```c
/* 创建 TCP 服务器 */
USART_SendString("AT+CIPMUX=1\r\n");
Delay(1000);
USART_SendString("AT+CIPSERVER=1,80\r\n");
Delay(1000);
/* 等待客户端连接 */
while (1) {
if (USART_GetString(str, sizeof(str))) {
if (strstr(str, "+IPD,") != NULL) {
int len = 0;
if (parse_ipd(str, &len)) {
USART_SendString("AT+CIPSEND=0,");
USART_SendString(itoa(len, buf, 10));
USART_SendString("\r\n");
Delay(1000);
USART_SendString("Hello, this is ESP8266 AP mode!\r\n");
Delay(1000);
USART_SendString("AT+CIPCLOSE=0\r\n");
Delay(1000);
}
}
}
}
```
当客户端连接后,发送一个预设的数据包。在数据包中包含 SSID 和密码。
```c
/* 发送预设的数据包 */
char ssid[] = "myssid";
char password[] = "mypassword";
int len = strlen(ssid) + strlen(password) + 1;
USART_SendString("AT+CIPSEND=0,");
USART_SendString(itoa(len, buf, 10));
USART_SendString("\r\n");
Delay(1000);
USART_SendString(ssid);
USART_SendString(",");
USART_SendString(password);
USART_SendString("\r\n");
Delay(1000);
USART_SendString("AT+CIPCLOSE=0\r\n");
Delay(1000);
```
客户端收到数据包后,将其中的 SSID 和密码保存,并使用这些信息连接 WiFi 网络。
```python
import socket
# 接收数据包
def recvall(sock):
BUFF_SIZE = 1024 # 一次接收的数据包大小
data = b""
while True:
part = sock.recv(BUFF_SIZE)
data += part
if len(part) < BUFF_SIZE:
break
return data
# 连接 WiFi
def connect_wifi():
# 创建 TCP 连接
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("192.168.4.1", 80))
# 发送数据包
data = recvall(sock)
ssid, password = data.decode().strip().split(",")
print("SSID:", ssid)
print("Password:", password)
# 关闭连接
sock.close()
# 连接 WiFi
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, password)
while not wifi.isconnected():
pass
print("WiFi connected!")
```
在 STM32 中,使用 ESP8266 的 AT 指令获取 WiFi 连接状态,如果连接成功,则退出循环。
```c
/* 等待 WiFi 连接成功 */
while (1) {
USART_SendString("AT+CWJAP?\r\n");
Delay(1000);
if (strstr(str, "+CWJAP:\"myssid\"") != NULL) {
USART_SendString("AT+CIPSERVER=0\r\n");
Delay(1000);
USART_SendString("AT+CWMODE=1\r\n");
Delay(1000);
break;
}
}
```
最后,完成一键配网的实现。
完整的 STM32 和 ESP8266 代码如下所示:
```c
#include "stm32f4xx.h"
#include <string.h>
#include <stdlib.h>
/* 延时函数 */
void Delay(__IO uint32_t nCount) {
while(nCount--) {
}
}
/* USART1 发送字符串 */
void USART_SendString(char *str) {
while (*str) {
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, *str++);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}
}
/* USART1 接收字符串 */
int USART_GetString(char *str, int len) {
int i = 0;
while (i < len) {
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) {
char ch = USART_ReceiveData(USART1);
if (ch == '\n') {
str[i] = '\0';
return i;
} else if (ch != '\r') {
str[i++] = ch;
}
}
}
return 0;
}
/* 解析 IPD 指令 */
int parse_ipd(char *str, int *len) {
char *ptr = strstr(str, ",");
if (ptr != NULL) {
ptr++;
*len = atoi(ptr);
return 1;
}
return 0;
}
/* 将整数转换为字符串 */
char *itoa(int val, char *str, int base) {
static char buf[32] = {0};
int i = 30;
for (; val && i; --i, val /= base)
buf[i] = "0123456789abcdef"[val % base];
return memcpy(str, buf + i + 1, 32 - i);
}
int main(void) {
char str[256], buf[32];
/* STM32 串口初始化 */
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* 串口时钟初始化 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* 串口引脚初始化 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 将 PA9 和 PA10 引脚设置为复用功能 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
/* 配置 USART1 参数 */
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
/* 开启 USART1 */
USART_Cmd(USART1, ENABLE);
/* ESP8266 模块初始化 */
USART_SendString("AT+RST\r\n"); // 重启 WiFi 模块
Delay(1000);
USART_SendString("AT+CWMODE=2\r\n"); // 设置为 AP 模式
Delay(1000);
/* 设置 AP 模式 */
USART_SendString("AT+CWMODE=2\r\n");
Delay(1000);
/* 设置 SSID 和密码 */
USART_SendString("AT+CWSAP=\"SSID\",\"password\",1,0\r\n");
Delay(1000);
/* 创建 TCP 服务器 */
USART_SendString("AT+CIPMUX=1\r\n");
Delay(1000);
USART_SendString("AT+CIPSERVER=1,80\r\n");
Delay(1000);
/* 等待客户端连接 */
while (1) {
if (USART_GetString(str, sizeof(str))) {
if (strstr(str, "+IPD,") != NULL) {
int len = 0;
if (parse_ipd(str, &len)) {
USART_SendString("AT+CIPSEND=0,");
USART_SendString(itoa(len, buf, 10));
USART_SendString("\r\n");
Delay(1000);
USART_SendString("Hello, this is ESP8266 AP mode!\r\n");
Delay(1000);
USART_SendString("AT+CIPCLOSE=0\r\n");
Delay(1000);
}
}
}
}
/* 发送预设的数据包 */
char ssid[] = "myssid";
char password[] = "mypassword";
int len = strlen(ssid) + strlen(password) + 1;
USART_SendString("AT+CIPSEND=0,");
USART_SendString(itoa(len, buf, 10));
USART_SendString("\r\n");
Delay(1000);
USART_SendString(ssid);
USART_SendString(",");
USART_SendString(password);
USART_SendString("\r\n");
Delay(1000);
USART_SendString("AT+CIPCLOSE=0\r\n");
Delay(1000);
/* 等待 WiFi 连接成功 */
while (1) {
USART_SendString("AT+CWJAP?\r\n");
Delay(1000);
if (strstr(str, "+CWJAP:\"myssid\"") != NULL) {
USART_SendString("AT+CIPSERVER=0\r\n");
Delay(1000);
USART_SendString("AT+CWMODE=1\r\n");
Delay(1000);
break;
}
}
while (1) {
}
}
```
阅读全文