当前位置:网站首页>STM32封装ESP8266一键配置函数:实现实现AP模式和STA模式切换、服务器与客户端创建
STM32封装ESP8266一键配置函数:实现实现AP模式和STA模式切换、服务器与客户端创建
2022-07-06 22:23:00 【华为云】
一、硬件环境介绍
1. ESP8266 : 采用安信可的模组,型号是ESP12F
2. STM32 : 采用STM32F103C8T6
3. 编程软件 : 采用Keil5

ESP8266编程调试过程中用到的相关软件下载地址:

二、ESP8266通信的调试与运行效果
下面几张图是将ESP8266配置成AP+TCP服务器模式,电脑连接ESP8266的热点之后,实现数据通信。通信的效果是,在电脑点击物联网控制系统软件,实现控制开发板上的LED灯和蜂鸣器,开发板上将检测的光敏数据、温度数据、RC522刷卡数据传输到电脑的软件上进行显示。----局域网通信


三、硬件接线与代码技术部分介绍
硬件连接: 下面会贴出核心代码,在当前开发板上,ESP8266接在STM32F103C8T6的串口3上。
代码分为以下几个部分:
(1) STM32程序里的串口接收采用定时器+接收中断的形式接收数据,使用这种方式可以接收不定长度数据,方便接下来与ESP8266进行通信。
(2). ESP8266驱动代码:代码实现了STA+TCP客户端的一键配置函数,AP+TCP服务器的一键配置函数,要配置ESP8266只需要调用对应的函数传入参数即可。
四、核心代码部分
4.1 ESP8266.c代码
#include "esp8266.h"u8 ESP8266_IP_ADDR[16]; //255.255.255.255u8 ESP8266_MAC_ADDR[18]; //硬件地址/*函数功能: ESP8266命令发送函数函数返回值:0表示成功 1表示失败*/u8 ESP8266_SendCmd(char *cmd){ u8 i,j; for(i=0;i<10;i++) //检测的次数--发送指令的次数 { USARTx_StringSend(USART3,cmd); for(j=0;j<100;j++) //等待的时间 { delay_ms(50); if(USART3_RX_FLAG) { USART3_RX_BUFFER[USART3_RX_CNT]='\0'; USART3_RX_FLAG=0; USART3_RX_CNT=0; if(strstr((char*)USART3_RX_BUFFER,"OK")) { return 0; } } } } return 1;}/*函数功能: ESP8266硬件初始化检测函数函数返回值:0表示成功 1表示失败*/u8 ESP8266_Init(void){ //退出透传模式 USARTx_StringSend(USART3,"+++"); delay_ms(50); return ESP8266_SendCmd("AT\r\n");}/*函数功能: 一键配置WIFI为AP+TCP服务器模式函数参数:char *ssid 创建的热点名称char *pass 创建的热点密码 (最少8位)u16 port 创建的服务器端口号函数返回值: 0表示成功 其他值表示对应错误值*/u8 ESP8266_AP_TCP_Server_Mode(char *ssid,char *pass,u16 port){ char *p; u8 i; char ESP8266_SendCMD[100]; //组合发送过程中的命令 /*1. 测试硬件*/ if(ESP8266_SendCmd("AT\r\n"))return 1; /*2. 关闭回显*/ if(ESP8266_SendCmd("ATE0\r\n"))return 2; /*3. 设置WIFI模式*/ if(ESP8266_SendCmd("AT+CWMODE=2\r\n"))return 3; /*4. 复位*/ ESP8266_SendCmd("AT+RST\r\n"); delay_ms(1000); delay_ms(1000); delay_ms(1000); /*5. 关闭回显*/ if(ESP8266_SendCmd("ATE0\r\n"))return 5; /*6. 设置WIFI的AP模式参数*/ sprintf(ESP8266_SendCMD,"AT+CWSAP=\"%s\",\"%s\",1,4\r\n",ssid,pass); if(ESP8266_SendCmd(ESP8266_SendCMD))return 6; /*7. 开启多连接*/ if(ESP8266_SendCmd("AT+CIPMUX=1\r\n"))return 7; /*8. 设置服务器端口号*/ sprintf(ESP8266_SendCMD,"AT+CIPSERVER=1,%d\r\n",port); if(ESP8266_SendCmd(ESP8266_SendCMD))return 8; /*9. 查询本地IP地址*/ if(ESP8266_SendCmd("AT+CIFSR\r\n"))return 9; //提取IP地址 p=strstr((char*)USART3_RX_BUFFER,"APIP"); if(p) { p+=6; for(i=0;*p!='"';i++) { ESP8266_IP_ADDR[i]=*p++; } ESP8266_IP_ADDR[i]='\0'; } //提取MAC地址 p=strstr((char*)USART3_RX_BUFFER,"APMAC"); if(p) { p+=7; for(i=0;*p!='"';i++) { ESP8266_MAC_ADDR[i]=*p++; } ESP8266_MAC_ADDR[i]='\0'; } //打印总体信息 USART1_Printf("当前WIFI模式:AP+TCP服务器\n"); USART1_Printf("当前WIFI热点名称:%s\n",ssid); USART1_Printf("当前WIFI热点密码:%s\n",pass); USART1_Printf("当前TCP服务器端口号:%d\n",port); USART1_Printf("当前TCP服务器IP地址:%s\n",ESP8266_IP_ADDR); USART1_Printf("当前TCP服务器MAC地址:%s\n",ESP8266_MAC_ADDR); return 0;}/*函数功能: TCP服务器模式下的发送函数发送指令: */u8 ESP8266_ServerSendData(u8 id,u8 *data,u16 len){ u8 i,j,n; char ESP8266_SendCMD[100]; //组合发送过程中的命令 for(i=0;i<10;i++) { sprintf(ESP8266_SendCMD,"AT+CIPSEND=%d,%d\r\n",id,len); USARTx_StringSend(USART3,ESP8266_SendCMD); for(j=0;j<10;j++) { delay_ms(50); if(USART3_RX_FLAG) { USART3_RX_BUFFER[USART3_RX_CNT]='\0'; USART3_RX_FLAG=0; USART3_RX_CNT=0; if(strstr((char*)USART3_RX_BUFFER,">")) { //继续发送数据 USARTx_DataSend(USART3,data,len); //等待数据发送成功 for(n=0;n<200;n++) { delay_ms(50); if(USART3_RX_FLAG) { USART3_RX_BUFFER[USART3_RX_CNT]='\0'; USART3_RX_FLAG=0; USART3_RX_CNT=0; if(strstr((char*)USART3_RX_BUFFER,"SEND OK")) { return 0; } } } } } } } return 1;}/*函数功能: 配置WIFI为STA模式+TCP客户端模式函数参数:char *ssid 创建的热点名称char *pass 创建的热点密码 (最少8位)char *p 将要连接的服务器IP地址u16 port 将要连接的服务器端口号u8 flag 1表示开启透传模式 0表示关闭透传模式函数返回值:0表示成功 其他值表示对应的错误*/u8 ESP8266_STA_TCP_Client_Mode(char *ssid,char *pass,char *ip,u16 port,u8 flag){ char ESP8266_SendCMD[100]; //组合发送过程中的命令 //退出透传模式 //USARTx_StringSend(USART3,"+++"); //delay_ms(50); /*1. 测试硬件*/ if(ESP8266_SendCmd("AT\r\n"))return 1; /*2. 关闭回显*/ if(ESP8266_SendCmd("ATE0\r\n"))return 2; /*3. 设置WIFI模式*/ if(ESP8266_SendCmd("AT+CWMODE=1\r\n"))return 3; /*4. 复位*/ ESP8266_SendCmd("AT+RST\r\n"); delay_ms(1000); delay_ms(1000); delay_ms(1000); /*5. 关闭回显*/ if(ESP8266_SendCmd("ATE0\r\n"))return 5; /*6. 配置将要连接的WIFI热点信息*/ sprintf(ESP8266_SendCMD,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pass); if(ESP8266_SendCmd(ESP8266_SendCMD))return 6; /*7. 设置单连接*/ if(ESP8266_SendCmd("AT+CIPMUX=0\r\n"))return 7; /*8. 配置要连接的TCP服务器信息*/ sprintf(ESP8266_SendCMD,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",ip,port); if(ESP8266_SendCmd(ESP8266_SendCMD))return 8; /*9. 开启透传模式*/ if(flag) { if(ESP8266_SendCmd("AT+CIPMODE=1\r\n"))return 9; //开启 if(ESP8266_SendCmd("AT+CIPSEND\r\n"))return 10; //开始透传 if(!(strstr((char*)USART3_RX_BUFFER,">"))) { return 11; } //如果想要退出发送: "+++" } //打印总体信息 USART1_Printf("当前WIFI模式:STA+TCP客户端\n"); USART1_Printf("当前连接的WIFI热点名称:%s\n",ssid); USART1_Printf("当前连接的WIFI热点密码:%s\n",pass); USART1_Printf("当前连接的TCP服务器端口号:%d\n",port); USART1_Printf("当前连接的TCP服务器IP地址:%s\n",ip); return 0;}/*函数功能: TCP客户端模式下的发送函数发送指令: */u8 ESP8266_ClientSendData(u8 *data,u16 len){ u8 i,j,n; char ESP8266_SendCMD[100]; //组合发送过程中的命令 for(i=0;i<10;i++) { sprintf(ESP8266_SendCMD,"AT+CIPSEND=%d\r\n",len); USARTx_StringSend(USART3,ESP8266_SendCMD); for(j=0;j<10;j++) { delay_ms(50); if(USART3_RX_FLAG) { USART3_RX_BUFFER[USART3_RX_CNT]='\0'; USART3_RX_FLAG=0; USART3_RX_CNT=0; if(strstr((char*)USART3_RX_BUFFER,">")) { //继续发送数据 USARTx_DataSend(USART3,data,len); //等待数据发送成功 for(n=0;n<200;n++) { delay_ms(50); if(USART3_RX_FLAG) { USART3_RX_BUFFER[USART3_RX_CNT]='\0'; USART3_RX_FLAG=0; USART3_RX_CNT=0; if(strstr((char*)USART3_RX_BUFFER,"SEND OK")) { return 0; } } } } } } } return 1;}4.2 ESP8266.h
#ifndef _ESP8266_H#define _ESP8266_H#include "stm32f10x.h"#include "usart.h"#include "delay.h"//函数声明u8 ESP8266_Init(void);u8 ESP8266_SendCmd(char *cmd);u8 ESP8266_AP_TCP_Server_Mode(char *ssid,char *pass,u16 port);u8 ESP8266_ServerSendData(u8 id,u8 *data,u16 len);u8 ESP8266_STA_TCP_Client_Mode(char *ssid,char *pass,char *ip,u16 port,u8 flag);u8 ESP8266_ClientSendData(u8 *data,u16 len);#endif4.3 串口部分代码
/*函数功能: 串口1的初始化硬件连接: PA9(TX) 和 PA10(RX)*/void USART1_Init(u32 baud){ /*1. 开时钟*/ RCC->APB2ENR|=1<<14; //USART1时钟 RCC->APB2ENR|=1<<2; //PA RCC->APB2RSTR|=1<<14; //开启复位时钟 RCC->APB2RSTR&=~(1<<14);//停止复位 /*2. 配置GPIO口的模式*/ GPIOA->CRH&=0xFFFFF00F; GPIOA->CRH|=0x000008B0; /*3. 配置波特率*/ USART1->BRR=72000000/baud; /*4. 配置核心寄存器*/ USART1->CR1|=1<<5; //开启接收中断 STM32_SetPriority(USART1_IRQn,1,1); //设置中断优先级 USART1->CR1|=1<<2; //开启接收 USART1->CR1|=1<<3; //开启发送 USART1->CR1|=1<<13;//开启串口功能}/*函数功能: 串口3的初始化硬件连接: PB10(TX) 和 PB11(RX)*/void USART3_Init(u32 baud){ /*1. 开时钟*/ RCC->APB1ENR|=1<<18; //USART3时钟 RCC->APB2ENR|=1<<3; //PB RCC->APB1RSTR|=1<<18; //开启复位时钟 RCC->APB1RSTR&=~(1<<18);//停止复位 /*2. 配置GPIO口的模式*/ GPIOB->CRH&=0xFFFF00FF; GPIOB->CRH|=0x00008B00; /*3. 配置波特率*/ USART3->BRR=36000000/baud; /*4. 配置核心寄存器*/ USART3->CR1|=1<<5; //开启接收中断 STM32_SetPriority(USART3_IRQn,1,1); //设置中断优先级 USART3->CR1|=1<<2; //开启接收 USART3->CR1|=1<<3; //开启发送 USART3->CR1|=1<<13;//开启串口功能}u8 USART3_RX_BUFFER[USART3_RX_LENGTH]; //保存接收数据的缓冲区u32 USART3_RX_CNT=0; //当前接收到的数据长度u8 USART3_RX_FLAG=0; //1表示数据接收完毕 0表示没有接收完毕//串口3的中断服务函数void USART3_IRQHandler(void){ u8 data; //接收中断 if(USART3->SR&1<<5) { TIM3->CNT=0; //清除计数器 TIM3->CR1|=1<<0; //开启定时器3 data=USART3->DR; //读取串口数据 // if(USART3_RX_FLAG==0) //判断上一次的数据是否已经处理完毕 { //判断是否可以继续接收 if(USART3_RX_CNT<USART3_RX_LENGTH) { USART3_RX_BUFFER[USART3_RX_CNT++]=data; } else //不能接收,超出存储范围,强制表示接收完毕 { USART3_RX_FLAG=1; } } }}/*函数功能: 字符串发送*/void USARTx_StringSend(USART_TypeDef *USARTx,char *str){ while(*str!='\0') { USARTx->DR=*str++; while(!(USARTx->SR&1<<7)){} }}/*函数功能: 数据发送*/void USARTx_DataSend(USART_TypeDef *USARTx,u8 *data,u32 len){ u32 i; for(i=0;i<len;i++) { USARTx->DR=*data++; while(!(USARTx->SR&1<<7)){} }}/*函数功能: 格式化打印函数*/char USART1_PRINTF_BUFF[1024];void USART1_Printf(char *fmt,...){ va_list ap; /*1. 初始化形参列表*/ va_start(ap,fmt); /*2. 提取可变形参数据*/ vsprintf(USART1_PRINTF_BUFF,fmt,ap); /*3. 结束,释放空间*/ va_end(ap); /*4. 输出数据到串口1*/ USARTx_StringSend(USART1,USART1_PRINTF_BUFF); //USART1_Printf("%d%s",123,454656); //int data=va_arg(ap,int);}4.4 定时器部分代码
/*函数功能: 配置定时器3函数参数: psc 预分频器 arr重装载值*/void TIMER3_Init(u16 psc,u16 arr){ /*1. 开时钟*/ RCC->APB1ENR|=1<<1; //开启定时器3的时钟 RCC->APB1RSTR|=1<<1;//开启定时器3复位时钟 RCC->APB1RSTR&=~(1<<1);//关闭定时器3复位时钟 /*2. 配置核心寄存器*/ TIM3->PSC=psc-1; TIM3->ARR=arr; TIM3->DIER|=1<<0; //开启更新中断 STM32_SetPriority(TIM3_IRQn,1,1); //设置中断优先级 // TIM3->CR1|=1<<0; //开启定时器3}/*函数功能: 定时器3中断服务函数*/void TIM3_IRQHandler(void){ if(TIM3->SR&1<<0) { TIM3->SR&=~(1<<0); USART3_RX_FLAG=1; //表示接收完毕 TIM3->CR1&=~(1<<0); //关闭定时器3 }}4.5 主函数调用部分(STA+TCP客户端)示例
int main(){ u8 key,cnt=0; LED_Init(); BEEP_Init(); KEY_Init(); USART1_Init(115200); USART3_Init(115200);//串口-WIFI TIMER3_Init(72,20000); //超时时间20ms USART1_Printf("正在初始化WIFI请稍等.\n"); if(ESP8266_Init()) { USART1_Printf("ESP8266硬件检测错误.\n"); } else { USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode("ChinaNet-wbyw","12345678","192.168.101.6",8088,1)); } while(1) { if(USART3_RX_FLAG) { USART3_RX_BUFFER[USART3_RX_CNT]='\0'; USART1_Printf("%s",USART3_RX_BUFFER); USART3_RX_CNT=0; USART3_RX_FLAG=0; } key=KEY_Scan(0); if(key==2) { USARTx_StringSend(USART3,"AT+GMR\r\n"); //查看版本信息 } else if(key==3) { USARTx_StringSend(USART3,"12345ABCD"); } else if(key==4) //退出透传模式 { USARTx_StringSend(USART3,"+++"); } else if(key==5) //发送AT { USARTx_StringSend(USART3,"AT+CIPSTATUS\r\n"); //查看状态信息 } }}4.6 主函数调用部分(AP+TCP服务器)示例
int main(){ u8 key; LED_Init(); BEEP_Init(); KEY_Init(); USART1_Init(115200); USART3_Init(115200);//串口-WIFI TIMER3_Init(72,20000); //超时时间20ms USART1_Printf("正在初始化WIFI请稍等.\n"); //初始化WIFI硬件 if(ESP8266_Init())USART1_Printf("WIFI硬件错误.\n"); else { //配置WIFI的模式 USART1_Printf("WIFI配置状态:%d\n",ESP8266_AP_TCP_Server_Mode("esp8266_666","12345678",8088)); } while(1) { if(USART3_RX_FLAG) { USART3_RX_BUFFER[USART3_RX_CNT]='\0'; USART1_Printf("%s",USART3_RX_BUFFER); USART3_RX_CNT=0; USART3_RX_FLAG=0; } key=KEY_Scan(0); if(key==2) { ESP8266_ServerSendData(0,(u8*)"1234567890",10); } else if(key==3) { ESP8266_ServerSendData(0,(u8*)"abcd",4); } }}边栏推荐
- 两个div在同一行,两个div不换行「建议收藏」
- namespace基础介绍
- 《原动力 x 云原生正发声 降本增效大讲堂》第三讲——Kubernetes 集群利用率提升实践
- Common methods of list and map
- Canteen user dish relationship system (C language course design)
- Easycvr cannot be played using webrtc. How to solve it?
- JS form get form & get form elements
- Chapter 9 Yunji datacanvas was rated as 36 krypton "the hard core technology enterprise most concerned by investors"
- acwing 843. n-皇后问题
- How to open win11 remote desktop connection? Five methods of win11 Remote Desktop Connection
猜你喜欢

Case reward: Intel brings many partners to promote the innovation and development of multi domain AI industry
![[line segment tree practice] recent requests + area and retrieval - array modifiable + my schedule I / III](/img/13/d598bb53b71fbadd4a97c603152124.png)
[line segment tree practice] recent requests + area and retrieval - array modifiable + my schedule I / III

【736. Lisp 语法解析】

offer如何选择该考虑哪些因素

Digital chemical plants realize the coexistence of advantages of high quality, low cost and fast efficiency

5G VoNR+之IMS Data Channel概念

Vscode automatically adds a semicolon and jumps to the next line

程序员上班摸鱼,这么玩才高端!

Vscode 如何使用内置浏览器?

Windows are not cheap things
随机推荐
leetcode 53. Maximum subarray maximum subarray sum (medium)
Chapter 9 Yunji datacanvas company won the highest honor of the "fifth digital finance innovation competition"!
[line segment tree practice] recent requests + area and retrieval - array modifiable + my schedule I / III
Windows are not cheap things
【线段树实战】最近的请求次数 + 区域和检索 - 数组可修改+我的日程安排表Ⅰ/Ⅲ
抖音或将推出独立种草社区平台:会不会成为第二个小红书
On the 110th anniversary of Turing's birth, has the prediction of intelligent machine come true?
If you ask me about R code debugging, I will tell you head, STR, help
九章云极DataCanvas公司摘获「第五届数字金融创新大赛」最高荣誉!
什么是Web3
Mathematical analysis_ Notes_ Chapter 10: integral with parameters
sscanf,sscanf_ S and its related usage "suggested collection"
How does vscade use the built-in browser?
【实践出真理】import和require的引入方式真的和网上说的一样吗
九章云极DataCanvas公司获评36氪「最受投资人关注的硬核科技企业」
R语言主成分pca、因子分析、聚类对地区经济研究分析重庆市经济指标
Depth first traversal template principle of tree and graph
Intel and Xinbu technology jointly build a machine vision development kit to jointly promote the transformation of industrial intelligence
What about the collapse of win11 playing pubg? Solution to win11 Jedi survival crash
The easycvr platform is connected to the RTMP protocol, and the interface call prompts how to solve the error of obtaining video recording?