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
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復用
// 配置UART
USART_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; // 停止位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(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 失敗返回ERROR
if( 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); //開啟服務器設置端口號為5000
if( 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 DEBUG
printf("The device is connected to a hotspot.rn");
#endif
return 1;
}
//有設備斷開了熱點
if( strstr((char*)WIFI_RX_BUFF, "+STA_DISCONNECTED") != NULL )
{
//清除接收的數據
wifi_link_flag = 0;
memset( WIFI_RX_BUFF, 0, sizeof(WIFI_RX_BUFF) );
#if DEBUG
printf("The device is disconnected from the hotspot.rn");
#endif
return 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 DEBUG
printf("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 DEBUG
printf("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;cnt20;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:
//測試指令AT
WIFI_Send_Cmd("ATrn","OK",100,3);
//配置WIFI STA
WIFI_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);
#endif
sprintf(AT_CMD,"AT+MQTTUSERCFG=0,1,"NULL","%s","%s",0,0,""rn", UserName, PassWord);
WIFI_Send_Cmd(AT_CMD,"OK",2000,3);
//設置連接客戶端ID
memset(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-100
JSON_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結構體的value
sprintf(data[1].value,"%d",90);
// 4
for(i=0;i
在文件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 );//設備ID
printf("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
審核編輯 黃宇
-
芯片
+關注
關注
456文章
51140瀏覽量
426132 -
WIFI
+關注
關注
81文章
5307瀏覽量
204402 -
CW32
+關注
關注
1文章
218瀏覽量
706
發布評論請先 登錄
相關推薦
評論