ESP8266系列无线模块是安信可科技自主研发设计的一系列高性价比WiFisOC模组。该系列模块支持标准的IEEE802.11 b/g/n 协议,内置完整的TCP/IP协议栈。用户可以使用该系列模块为现有的设备添加联网功能,也可以构建独立的网络控制器。即使在不了解其原理的情况下,只要有一定的串口知识理解,那么就可以轻松上手该模块,进而实现手机WiFi操作。功能特点:基于ESP8266芯片开发,模组集成了透传功能,即买即用,支持串口AT指令集,用户通过串口即可实现网络访问,广泛应用于智能穿戴,智能家居,家庭安防,遥控器,汽车电子,智慧照明,工业物联网等领域。
一模块来源
模块实物展示:
资料链接:https://pan.baidu.com/s/13mQInPq5drMzs8sXzC14dQ
资料提取码:pj4z
二规格参数
工作电压:3.0V-3.6V
工作电流:IMAX = 170mA
模块尺寸:14.4 x 24.7 MM
控制方式:串口
三移植过程
我们的目标是在立创·CW32F030C8T6开发板上能够完成无线传输的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。
3.1查看资料
该WIFI模块,有三种模式即STA、AP、STA+AP。
这里主要使用AP和STA模式作为案例,实现近距离无线控制和远距离无线控制。
STA模式是指ESP8266作为客户端连接到一个无线路由器上(或者无线热点),可以访问网络中的其他设备。
AP模式是指ESP8266作为热点,其他设备可以连接到它上面,实现无线网络通信。
STA+AP模式就是两者同时实现。、
使用前,需要烧入MQTT固件,后续的案例有使用MQTT,如不烧入MQTT固件,在涉及到MQTT的AT命令时会不断失败。
固件下载地址:
链接:https://pan.baidu.com/s/1BB_X7XhKpedunGY1EIFX7A?pwd=LCKF
提取码:LCKF
固件烧录接线:
烧录步骤:
链接:https://pan.baidu.com/s/1acnXmU3ASNQMjsner4DSrA?pwd=LCKF
提取码:LCKF
3.2引脚选择
使用串口2(串口2-TX=PA2,串口2-RX=PA3)
模块接线图
3.3移植至工程
移植步骤中的导入.c和.h文件与【CW32模块使用】DHT11温湿度传感器相同,只是将.c和.h文件更改为bsp_esp01s.c与bsp_esp01s.h。这里不再过多讲述,移植完成后面修改相关代码。
在文件bsp_esp01s.c中,编写如下代码。
/** Change Logs:* Date Author Notes* 2024-06-21 LCKFB-LP first version*/#include "bsp_ESP01S.h"#include "stdio.h"#include "hmacsha1.h"#include "string.h"#include <stdlib.h>unsigned char WIFI_RX_BUFF[WIFI_RX_LEN_MAX];unsigned char WIFI_RX_FLAG = 0;unsigned char WIFI_RX_LEN = 0;uint8_t wifi_link_flag = 0;//设备连接状态//配合 Get_Device_connection_status 函数使用// * 0=没有设备连接// * 1=有设备连接了WIFI// * 0=有设备断开了WIFI// * 2=有设备连接了服务器// * 3=有设备断开了服务器/************************************************************* 函数名称:WIFI_USART_Init* 函数说明:连接WIFI的初始化* 型 参:bund=串口波特率* 返 回 值:无* 备 注:无*************************************************************/void WIFI_USART_Init(unsigned int bund){GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化结构体RCC_WIFI_GPIO_ENABLE(); // 使能GPIO时钟RCC_WIFI_USART_ENABLE(); // 使能UART时钟GPIO_InitStruct.Pins = GPIO_WIFI_TX; // GPIO引脚GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 输出速度高GPIO_Init(PORT_WIFI_GPIO, &GPIO_InitStruct); // 初始化GPIO_InitStruct.Pins = GPIO_WIFI_RX; // GPIO引脚GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP; // 上拉输入GPIO_Init(PORT_WIFI_GPIO, &GPIO_InitStruct); // 初始化BSP_GPS_AF_UART_TX(); // UART_TX复用BSP_GPS_AF_UART_RX(); // UART_RX复用// 配置UARTUSART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = bund; // 波特率USART_InitStructure.USART_Over = USART_Over_16; // 配置USART的过采样率。USART_InitStructure.USART_Source = USART_Source_PCLK; // 设置时钟源USART_InitStructure.USART_UclkFreq = 64000000; //设置USART时钟频率(和主频一致即可)USART_InitStructure.USART_StartBit = USART_StartBit_FE; //RXD下降沿开始USART_InitStructure.USART_StopBits = USART_StopBits_1; // 停止位1USART_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(WIFI_USART, &USART_InitStructure); // 初始化串口2// 优先级,无优先级分组NVIC_SetPriority(WIFI_USART_IRQ, 0);// UARTx中断使能NVIC_EnableIRQ(WIFI_USART_IRQ);// 使能UARTx RC中断USART_ITConfig(WIFI_USART, USART_IT_RC, ENABLE);}/******************************************************************* 函 数 名 称:WIFI_USART_Send_Bit* 函 数 说 明:向WIFI模块发送单个字符* 函 数 形 参:ch=字符* 函 数 返 回:无* 作 者:LC* 备 注:无******************************************************************/void WIFI_USART_Send_Bit(unsigned char ch){// 发送一个字节USART_SendData_8bit(WIFI_USART, (uint8_t)ch);// 等待发送完成while( RESET == USART_GetFlagStatus(WIFI_USART, USART_FLAG_TXE) ){}}/******************************************************************* 函 数 名 称:WIFI_USART_send_String* 函 数 说 明:向WIFI模块发送字符串* 函 数 形 参:str=发送的字符串* 函 数 返 回:无* 作 者:LC* 备 注:无******************************************************************/void WIFI_USART_send_String(unsigned char *str){printf("string : %srn",str);while( str && *str ) // 地址为空或者值为空跳出{WIFI_USART_Send_Bit(*str++);}}//清除串口接收的数据/******************************************************************* 函 数 名 称:Clear_WIFI_RX_BUFF* 函 数 说 明:清除WIFI发过来的数据* 函 数 形 参:无* 函 数 返 回:无* 作 者:LC* 备 注:无******************************************************************/void Clear_WIFI_RX_BUFF(void){unsigned char i = WIFI_RX_LEN_MAX-1;while(i){WIFI_RX_BUFF[i--] = 0;}WIFI_RX_LEN = 0;WIFI_RX_FLAG = 0;}/******************************************************************* 函 数 名 称:WIFI_Send_Cmd* 函 数 说 明:向WIFI模块发送指令,并查看WIFI模块是否返回想要的数据* 函 数 形 参:cmd=发送的AT指令 ack=想要的应答 waitms=等待应答的时间 cnt=等待应答多少次* 函 数 返 回:1=得到了想要的应答 0=没有得到想要的应答* 作 者:LC* 备 注:无******************************************************************/char WIFI_Send_Cmd(char *cmd,char *ack,unsigned int waitms,unsigned char cnt){uint8_t tt = 0;re:WIFI_USART_send_String((unsigned char*)cmd);//1.发送AT指令while(cnt--){//时间间隔delay_1ms(waitms);//串口中断接收蓝牙应答if( WIFI_RX_FLAG == 1 ){WIFI_RX_FLAG = 0;WIFI_RX_LEN = 0;//查找是否有想要的数据if( strstr((char*)WIFI_RX_BUFF, ack) != NULL ){return 1;}//清除接收的数据memset( WIFI_RX_BUFF, 0, sizeof(WIFI_RX_BUFF) );}}WIFI_RX_FLAG = 0;WIFI_RX_LEN = 0;if(tt < 3){tt++;goto re;}return 0;}/******************************************************************* 函 数 名 称:WIFI_ESP01S_Init* 函 数 说 明:WIFI模块ESP01S初始化* 函 数 形 参:无* 函 数 返 回:无* 作 者:LC* 备 注:ESP01S的默认波特率是115200******************************************************************/void WIFI_ESP01S_Init(void){WIFI_USART_Init(115200);//默认波特率为115200}/******************************************************************* 函 数 名 称:WIFI_MODE_AP_Init* 函 数 说 明:开启AP模式,即模块开启热点让手机连接* 函 数 形 参:无* 函 数 返 回:1=配置成功 其他=失败* 作 者:LC* 备 注:手机通过WIFI模块默认的IP地址192.168.4.1和设置的端口号,进行连接******************************************************************/uint8_t WIFI_MODE_AP_Init(void){uint8_t ret = 0;char send_buff[200];ret = WIFI_Send_Cmd("ATrn", "OK", 10, 3);//测试指令:ATrn 成功返回OK 失败返回ERRORif( ret != 1 ) return ret;ret = WIFI_Send_Cmd("AT+CWMODE=2rn","OK",30,3); //配置WIFI AP模式if( ret != 1 ) return ret;sprintf(send_buff, "AT+CWSAP="%s","%s",11,4rn", AP_WIFISSID,AP_WIFIPASS );ret = WIFI_Send_Cmd(send_buff,"OK",30,3); //设置wifi账号与密码if( ret != 1 ) return ret;ret = WIFI_Send_Cmd("AT+RSTrn","ready",800,3); //重新复位if( ret != 1 ) return ret;ret = WIFI_Send_Cmd("AT+CIPMUX=1rn","OK",50,3); //开启多个连接if( ret != 1 ) return ret;ret = WIFI_Send_Cmd("AT+CIPSERVER=1,5000rn","OK",50,3); //开启服务器设置端口号为5000if( ret != 1 ) return ret;return ret;}/******************************************************************* 函 数 名 称:Get_Device_connection_status* 函 数 说 明:获取设备连接状态(AP模式)* 函 数 形 参:无* 函 数 返 回:0=没有设备连接* 1=有设备连接了WIFI* 2=有设备断开了WIFI* 3=有设备连接了服务器* 4=有设备断开了服务器* 作 者:LC* 备 注:手机要连接WIFI模块的步骤是先连接WIFI再连接服务器//当有设备连接AP模式下的热点时,WIFI模块会给连接的设备分配IP地址//我们只需检测是否有分配地址,则知道是否有设备连接。//设备连接时WIFI返回:// +STA_CONNECTED:"f0:6c:5d:d6:f6:18"// +DIST_STA_IP:"f0:6c:5d:d6:f6:18","192.168.4.2"//设备断开连接时返回:// +STA_DISCONNECTED:"f0:6c:5d:d6:f6:18"******************************************************************/uint8_t Get_Device_connection_status(void){//串口中断接收WIFI应答if( WIFI_RX_FLAG == 1 ){WIFI_RX_FLAG = 0;WIFI_RX_LEN = 0;//有设备连接了热点if( strstr((char*)WIFI_RX_BUFF, "+STA_CONNECTED") != NULL ){//清除接收的数据wifi_link_flag = 1;memset( WIFI_RX_BUFF, 0, sizeof(WIFI_RX_BUFF) );#if DEBUGprintf("The device is connected to a hotspot.rn");#endifreturn 1;}//有设备断开了热点if( strstr((char*)WIFI_RX_BUFF, "+STA_DISCONNECTED") != NULL ){//清除接收的数据wifi_link_flag = 0;memset( WIFI_RX_BUFF, 0, sizeof(WIFI_RX_BUFF) );#if DEBUGprintf("The device is disconnected from the hotspot.rn");#endifreturn 2;}//有设备连接了服务器if( strstr((char*)WIFI_RX_BUFF, ",CONNECT") != NULL ){//清除接收的数据wifi_link_flag = 2;memset( WIFI_RX_BUFF, 0, sizeof(WIFI_RX_BUFF) );return 3;#if DEBUGprintf("The device is connected to the server.rn");#endif}//有设备断开了服务器if( strstr((char*)WIFI_RX_BUFF, ",CLOSED") != NULL ){//清除接收的数据wifi_link_flag = 3;memset( WIFI_RX_BUFF, 0, sizeof(WIFI_RX_BUFF) );return 4;#if DEBUGprintf("The device is disconnected from the server.rn");#endif}}return 0;}/*********************************************************** 函 数 名 称:Get_WIFI_AP_Data* 函 数 功 能:解析设备发送过来的数据* 传 入 参 数:ap_parameter要将数据保存的地址* 函 数 返 回:1:有设备发送过来数据 0:没有设备发送过来数据* 作 者:LC* 备 注:device_id最大5个 //+IPD,1,4:abcd**********************************************************/uint8_t Get_WIFI_AP_Data(AP_PARAMETER *ap_parameter){char buff[50];char *test;char i=0;//接收到设备发过来的数据if( strstr((char*)WIFI_RX_BUFF,"+IPD,") != NULL ){test = strstr((char*)WIFI_RX_BUFF,"+IPD,");//记录设备ID号strncpy(buff,test+5,1);buff[1] ='';ap_parameter->device_id = atoi(buff);printf("device_id = %srn",buff);//记录发送过来的数据长度strncpy(buff,test+7,strcspn(test+7,":") );buff[ strcspn(test+7,":") ] ='';printf("device_data = %srn",buff);ap_parameter->device_datalen = atoi(buff);printf("device_datalen = %srn",buff);//记录发送过来的数据memset(buff,0,sizeof(buff));while(test[i++]!=':');strncpy(buff, test+i,strcspn(test+i,"r") );printf("device_data = %srn",buff);strcpy((char*)ap_parameter->device_data, buff);//清除串口接近缓存Clear_WIFI_RX_BUFF();return 1;}return 0;}/******************************************************************* 函 数 名 称:WIFI_Send_To_Client* 函 数 说 明:AP模式下,WIFI发送数据至客户端(连接AP模式下热点的设备)* 函 数 形 参:id=向第几个客户端发送数据 data=要发送的数据(字符串形式)* 函 数 返 回:0=发送失败 1=发送成功* 作 者:LC* 备 注:使用该函数函数请确保WIFI模块处于AP模式******************************************************************/uint8_t WIFI_Send_To_Client(uint8_t id,char * data){uint8_t send_buf[20]={0};sprintf((char*)send_buf,"AT+CIPSEND=%d,%drn",id,strlen(data));if(WIFI_Send_Cmd((char*)send_buf,">",20,3)){WIFI_USART_send_String((unsigned char *)data);return 1;}return 0;}/******************************************************************* 函 数 名 称:mstrcat* 函 数 说 明:字符串连接* 函 数 形 参:s1:目标字符串, s2:源字符串* 函 数 返 回:无* 作 者:LC* 备 注:哈希使用******************************************************************/static void mstrcat(char *s1, const char *s2){// 寻找s1的末尾(即''字符)while(*s1 != '')s1++;// 将s2的内容复制到s1的末尾,包括s2的结束字符''while((*s1++ = *s2++));}/******************************************************************* 函 数 名 称:CalculateSha1* 函 数 说 明:计算sha1密匙* 函 数 形 参:password:密匙存放缓冲区* 函 数 返 回:无* 作 者:LC* 备 注:无******************************************************************/static void CalculateSha1(unsigned char *password){unsigned char temp[3] = {0};unsigned char digest[30]={0};unsigned char cnt = 0;hmac_sha1((unsigned char *)DeviceSecret,32,(unsigned char *)Encryption,46,digest);memset(temp, 0, sizeof(temp));for(cnt=0;cnt<20;cnt++){sprintf((char *)temp,"%02X",digest[cnt]);mstrcat((char *)password,(char *)temp);}}/******************************************************************* 函 数 名 称:WIFI_MODE_STA_Aliyun_Init* 函 数 说 明:配置WIFI模块连接阿里云物联网平台* 函 数 形 参:无* 函 数 返 回:无* 作 者:LC* 备 注:无******************************************************************/void WIFI_MODE_STA_Aliyun_Init(void){char AT_CMD[250]={0};uint8_t PassWord[50] = {0}; //存放的是哈希计算的密钥RST://测试指令ATWIFI_Send_Cmd("ATrn","OK",100,3);//配置WIFI STAWIFI_Send_Cmd("AT+CWMODE=1rn","OK",300,3);//设置时区 NTSP服务器 用于调整客户端自身所在系统的时间,达到同步时间的目的WIFI_Send_Cmd("AT+CIPSNTPCFG=1,8,"ntp1.alliyun.com"rn","OK",100,3);//连接wifi 账号&密码sprintf(AT_CMD,"AT+CWJAP="%s","%s"rn",WIFISSID,WIFIPASS);if( WIFI_Send_Cmd(AT_CMD,"OK",3000,3) == 0 ){printf("WIFI名称或密码有错,复位重启rn");//wifi连接不上,重启WIFI_Send_Cmd("AT+RSTrn","ready",1000,1);goto RST;}//清0数组,备用memset(AT_CMD,0,sizeof(AT_CMD));//计算哈希CalculateSha1(PassWord);#if DEBUG// sprintf(PassWord,"%s","AF7596ADFFD4C57C5FD43F1CA1A20DE961634360");printf("haxi=%srn",PassWord);printf("UserName=%srn",UserName);#endifsprintf(AT_CMD,"AT+MQTTUSERCFG=0,1,"NULL","%s","%s",0,0,""rn", UserName, PassWord);WIFI_Send_Cmd(AT_CMD,"OK",2000,3);//设置连接客户端IDmemset(AT_CMD,0,sizeof(AT_CMD)); //清0数组,备用sprintf(AT_CMD,"AT+MQTTCLIENTID=0,"%s"rn",ClientId);WIFI_Send_Cmd(AT_CMD,"OK",1000,3);//连接到MQTT代理(阿里云平台)memset(AT_CMD,0,sizeof(AT_CMD));sprintf(AT_CMD,"AT+MQTTCONN=0,"%s",1883,1rn",IP);if(WIFI_Send_Cmd(AT_CMD,"OK",2000,3)==0){printf("连接aliyu失败,复位STM32重连rn");//wifi连接不上,重启 1000延时1S 2链接次数WIFI_Send_Cmd("AT+RSTrn","ready",1000,2);// __set_FAULTMASK(1); //STM32程序软件复位NVIC_SystemReset();}//订阅主题memset(AT_CMD,0,sizeof(AT_CMD));sprintf(AT_CMD, "AT+MQTTSUB=0,"%s",1rn", PublishMessageTopSet);WIFI_Send_Cmd(AT_CMD,"OK",1000,3);printf("连接aliyu成功rn");Clear_WIFI_RX_BUFF();//清除串口接收缓存//上电就上传数据至手机// Publish_MQTT_message(publish_mqtt_message,5,); //发布主题}/*点击LED开关+MQTTSUBRECV:0,"/sys/a1PJRLOWo3p/TEST/thing/service/property/set",100,{"method":"thing.service.property.set","id":"367399823","params":{"LED_Switch":1},"version":"1.0.0"}*//*滑动亮度条+MQTTSUBRECV:0,"/sys/a1PJRLOWo3p/TEST/thing/service/property/set",101,{"method":"thing.service.property.set","id":"812539841","params":{"brightness":75},"version":"1.0.0"}*//******************************************************************* 函 数 名 称:Get_Aliyun_json_data* 函 数 说 明:获取阿里云JSON格式的数据(接收手机发送过来的数据)* 函 数 形 参:data=数据的保存地址* 函 数 返 回:1=接收到JSON数据并处理 0=没有接收到数据* 作 者:LC* 备 注:无******************************************************************/uint8_t Get_Aliyun_json_data(JSON_PUBLISH *data){char *buff=0;//串口中断接收WIFI应答if( WIFI_RX_FLAG == SET ){printf("rn--rn");WIFI_RX_FLAG = 0;WIFI_RX_LEN = 0;//有设备连接了热点if( strstr((char*)WIFI_RX_BUFF, "params":") != NULL ){//获取功能名称buff = strstr((char*)WIFI_RX_BUFF, "params":");buff += strlen("params":{"");strcpy(data->keyname,strtok(buff,"""));printf("data->keyname = %srn",data->keyname);//获取功能值buff = strstr((char*)WIFI_RX_BUFF, "params":" );buff += strlen("params":{"")+strlen(data->keyname)+2;strcpy(data->value, strtok(buff,"}"));return 1;}}return 0;}/******************************************************************* 函 数 名 称:Clear_Aliyun_json_data* 函 数 说 明:清除JSON接收过的数据* 函 数 形 参:data=要清除的数据* 函 数 返 回:无* 作 者:LC* 备 注:无******************************************************************/void Clear_Aliyun_json_data(JSON_PUBLISH *data){uint16_t i = 0;while( data->keyname[i] != 0 ){data->keyname[i++] = '';}i= 0;while( data->value[i] != 0 ){data->keyname[i++] = '';}}//在自定义功能时,有多少个标识符,就添加多少个//我就只有两个标识符。//LED_Switch=LED开关 范围0-1//brightness=亮度 范围0-100JSON_PUBLISH publish_mqtt_message[2]={{ ""LED_Switch":","0" },{ ""brightness":","0" }};/******************************************************************* 函 数 名 称:Publish_MQTT_message* 函 数 说 明:发布主题 ,上发多个数据(设备将数据发送至手机)* 函 数 形 参:data=publish_mqtt_message, data_num=上传的数据个数* 函 数 返 回:无* 作 者:LC* 备 注:无******************************************************************/void Publish_MQTT_message(JSON_PUBLISH *data,uint8_t data_num){char AT_CMD[384]={0};char params[256]={0},i,*sp;sp=params;sprintf(data[0].value,"%d",0); //把传感器的值赋值给json结构体的valuesprintf(data[1].value,"%d",90);// 4for(i=0;i<data_num;i++){ // 3if(i<(data_num-1)){sprintf(sp,"%s%s%s",data[i].keyname,data[i].value,",");while(*sp!=0) {sp++;} //防止覆盖}elsesprintf(sp,"%s%s",data[i].keyname,data[i].value);}sprintf(AT_CMD,"AT+MQTTPUB=0,"%s","{"params":{%s}}",1,0rn",PublishMessageTopPost,params);//发送指令后等待2000ms再判断是否发送成功,不发送成功则重发3-1次//这里会阻塞CPU的运行,可以直接使用 WIFI_USART_send_String(AT_CMD); 发送,但是无法判断是否发送成功。WIFI_Send_Cmd(AT_CMD,"OK",2000,3);}/******************************************************************* 函 数 名 称:WIFI_USART_IRQHandler* 函 数 说 明:连接WIFI的串口中断服务函数* 函 数 形 参:无* 函 数 返 回:无* 作 者:LC* 备 注:无******************************************************************/void WIFI_USART_IRQHandler(void){if(USART_GetITStatus(WIFI_USART, USART_IT_RC) == SET) // 接收缓冲区不为空{//接收数据WIFI_RX_BUFF[ WIFI_RX_LEN ] = USART_ReceiveData(WIFI_USART);#if DEBUG//测试,查看接收到了什么数据printf("%c", WIFI_RX_BUFF[ WIFI_RX_LEN ]);#endif//接收长度限制WIFI_RX_LEN = ( WIFI_RX_LEN + 1 ) % WIFI_RX_LEN_MAX;WIFI_RX_BUFF[WIFI_RX_LEN] = ''; //字符串结尾补 ''WIFI_RX_FLAG = SET; // 接收完成USART_ClearITPendingBit(WIFI_USART, USART_IT_RC); //已经处理就清楚标志位}}
在文件bsp_esp01s.h中,编写如下代码。
/** Change Logs:* Date Author Notes* 2024-06-21 LCKFB-LP first version*/#ifndef _BSP_ESP01S_H_#define _BSP_ESP01S_H_#include "board.h"#include "string.h"//是否开启串口0调试,查看WIFI回显数据#define DEBUG 1/**************************** STA模式 ****************************///STA模式下,WIFI模块要连接的热点(需要自行修改为自己的参数)#define WIFISSID "aaa" //wifi热点名称#define WIFIPASS "12345678" //wifi热点密码//连接的阿里云IP端口(不可修改)#define IP "203.107.45.14" //阿里云服务器IP或域名//#define IP "a1PaQm83lGg.iot-as-mqtt.cn-shenzhen.aliyuncs.com" //服务器IP或域名#define PORT 1883 //连接端口号,MQTT默认1883//阿里云三元组(需要自行修改为自己的参数)#define DeviceName "TEST" //设备名称#define ProductKey "a1PJRLOWo3p" //产品密匙#define DeviceSecret "3e7a1a43694b65abdcbc4f5c724e9faf" //设备密匙//计算哈希算法用到加密(不可修改)#define Client "clientId123deviceName"#define productKey "productKey"#define Encryption (Client DeviceName productKey ProductKey)//AT指令的#define AND "&"#define ClientId "123|securemode=3,signmethod=hmacsha1|" //客户端ID#define UserName (DeviceName AND ProductKey) //用户名//订阅发布的主题(不可修改)#define SYS "/sys/"#define LINK "/"#define TOP "/thing/event/property/"#define POST "post"#define ESET "set"#define PublishMessageTopPost (SYS ProductKey LINK DeviceName TOP POST)#define PublishMessageTopSet (SYS ProductKey LINK DeviceName TOP ESET)//上传数据结构体typedef struct{char keyname[50]; //键读取char value[20]; //读取到的值,类型字符串}JSON_PUBLISH;extern JSON_PUBLISH publish_mqtt_message[2];/**************************** AP模式 ****************************///AP模式下,WIFI开启的热点#define AP_WIFISSID "ESP-01S"#define AP_WIFIPASS "12345678"typedef struct{uint8_t device_id;uint8_t device_datalen;uint8_t device_data[200];}AP_PARAMETER;/**************************** 串口配置 ****************************/#define RCC_WIFI_GPIO_ENABLE() __RCC_GPIOA_CLK_ENABLE() // 串口TX的端口时钟#define RCC_WIFI_USART_ENABLE() __RCC_UART2_CLK_ENABLE() // 串口2的时钟#define BSP_GPS_AF_UART_TX() PA02_AFx_UART2TXD() // GPIO的引脚复用#define BSP_GPS_AF_UART_RX() PA03_AFx_UART2RXD() // GPIO的引脚复用#define PORT_WIFI_GPIO CW_GPIOA // 串口TX的端口#define GPIO_WIFI_TX GPIO_PIN_2 // 串口TX的引脚#define GPIO_WIFI_RX GPIO_PIN_3 // 串口RX的引脚#define WIFI_USART CW_UART2 // 串口2#define WIFI_USART_IRQ UART2_IRQn // 串口2中断#define WIFI_USART_IRQHandler UART2_IRQHandler // 串口2中断服务函数#define WIFI_RX_LEN_MAX 200 //串口接收最大长度extern uint8_t wifi_link_flag;//设备连接状态//配合 Get_Device_connection_status 函数使用// * 0=没有设备连接// * 1=有设备连接了WIFI// * 0=有设备断开了WIFI// * 2=有设备连接了服务器// * 3=有设备断开了服务器void WIFI_ESP01S_Init(void); //WIFI模块初始化uint8_t WIFI_MODE_AP_Init(void); //AP模式初始化uint8_t Get_Device_connection_status(void);//获取连接状态void WIFI_MODE_STA_Aliyun_Init(void); //连接阿里云初始化uint8_t Get_WIFI_AP_Data(AP_PARAMETER *ap_parameter);uint8_t Get_Aliyun_json_data(JSON_PUBLISH *data);void Clear_Aliyun_json_data(JSON_PUBLISH *data);void Publish_MQTT_message(JSON_PUBLISH *data,uint8_t data_num);char WIFI_Send_Cmd(char *cmd,char *ack,unsigned int waitms,unsigned char cnt);#endif
四案例一AP模式下的手机控制
>>>
使用AP模式通过AT命令,控制WIFI模块开启热点、多连接、服务器。待手机连接后,通过手机APP进行数据互传。
使用案例前,请确保bsp_esp01s.c和bsp_esp01s.h移植成功。
手机APP下载地址:
链接:https://pan.baidu.com/s/1-wh0aaqRMW8fJ5nLH1Lwyw?pwd=LCKF
提取码:LCKF
APP操作
首先使用手机连接WIFI模块的热点。其次打开APP连接服务器。服务器默认IP为192.168.4.1,端口号在代码中设置为了5000。
连接上WIFI的热点后,打开APP连接服务器。
编辑各个按钮值,方便后面我们进行控制。
在main.c中,编写如下代码。
/** Change Logs:* Date Author Notes* 2024-06-21 LCKFB-LP first version*/#include "board.h"#include "stdio.h"#include "bsp_uart.h"#include "bsp_esp01s.h"int32_t main(void){AP_PARAMETER ap_parameter={0};uint8_t test_ret = 0;board_init();uart1_init(115200U);printf("Startrn");//WIFI初始化WIFI_ESP01S_Init();//设置WIFI模块为AP模式WIFI_MODE_AP_Init();while(1){//判断是否有设备连接Get_Device_connection_status();//如果当前设备连接了服务器(手机APP连接上热点)if( wifi_link_flag == 2 ){if( Get_WIFI_AP_Data(&ap_parameter) == 1 )//如果接收到数据{//输出接收的数据printf("ID = %drn", ap_parameter.device_id );//设备IDprintf("data len = %drn", ap_parameter.device_datalen );//发送过来的数据长度printf("data = %srn", ap_parameter.device_data );//发送过来的数据}}}}
案例现象:
当手机APP接入WIFI连接成功之后,APP发送数据到开发板的串口。
默认ip:192.168.4.1 默认端口:5000
工程代码下载:
链接:https://pan.baidu.com/s/16IPzyT_Rdm2E2BgPvYe-pw?pwd=LCKF
提取码:LCKF
4154