• 正文
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

【CW32模塊使用】ESP01S WIFI模塊

01/25 10:55
1615
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

ESP8266系列無線模塊是安信可科技自主研發(fā)設(shè)計的一系列高性價比WiFisOC模組。該系列模塊支持標(biāo)準(zhǔn)的IEEE802.11 b/g/n 協(xié)議,內(nèi)置完整的TCP/IP協(xié)議棧。用戶可以使用該系列模塊為現(xiàn)有的設(shè)備添加聯(lián)網(wǎng)功能,也可以構(gòu)建獨立的網(wǎng)絡(luò)控制器。即使在不了解其原理的情況下,只要有一定的串口知識理解,那么就可以輕松上手該模塊,進(jìn)而實現(xiàn)手機WiFi操作。功能特點:基于ESP8266芯片開發(fā),模組集成了透傳功能,即買即用,支持串口AT指令集,用戶通過串口即可實現(xiàn)網(wǎng)絡(luò)訪問,廣泛應(yīng)用于智能穿戴,智能家居,家庭安防,遙控器,汽車電子,智慧照明,工業(yè)物聯(lián)網(wǎng)等領(lǐng)域。

模塊來源

模塊實物展示:

資料鏈接:https://pan.baidu.com/s/13mQInPq5drMzs8sXzC14dQ

資料提取碼:pj4z

規(guī)格參數(shù)

工作電壓:3.0V-3.6V

工作電流:IMAX = 170mA

模塊尺寸:14.4 x 24.7 MM

控制方式:串口

移植過程

我們的目標(biāo)是在立創(chuàng)·CW32F030C8T6開發(fā)板上能夠完成無線傳輸的功能。首先要獲取資料,查看數(shù)據(jù)手冊應(yīng)如何實現(xiàn),再移植至我們的工程。

3.1查看資料

該WIFI模塊,有三種模式即STA、AP、STA+AP。

這里主要使用AP和STA模式作為案例,實現(xiàn)近距離無線控制和遠(yuǎn)距離無線控制。

STA模式是指ESP8266作為客戶端連接到一個無線路由器上(或者無線熱點),可以訪問網(wǎng)絡(luò)中的其他設(shè)備。

AP模式是指ESP8266作為熱點,其他設(shè)備可以連接到它上面,實現(xiàn)無線網(wǎng)絡(luò)通信。

STA+AP模式就是兩者同時實現(xiàn)。、

使用前,需要燒入MQTT固件,后續(xù)的案例有使用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移植至工程

移植步驟中的導(dǎo)入.c和.h文件與【CW32模塊使用】DHT11溫濕度傳感器相同,只是將.c和.h文件更改為bsp_esp01s.c與bsp_esp01s.h。這里不再過多講述,移植完成后面修改相關(guān)代碼。

在文件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;//設(shè)備連接狀態(tài)//配合    Get_Device_connection_status    函數(shù)使用// *              0=沒有設(shè)備連接// *              1=有設(shè)備連接了WIFI// *              0=有設(shè)備斷開了WIFI// *              2=有設(shè)備連接了服務(wù)器// *              3=有設(shè)備斷開了服務(wù)器


/************************************************************ * 函數(shù)名稱:WIFI_USART_Init * 函數(shù)說明:連接WIFI的初始化 * 型    參:bund=串口波特率 * 返 回 值:無 * 備    注:無*************************************************************/void WIFI_USART_Init(unsigned int bund){    GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化結(jié)構(gòu)體
    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復(fù)用    BSP_GPS_AF_UART_RX(); // UART_RX復(fù)用
    // 配置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;               // 設(shè)置時鐘源    USART_InitStructure.USART_UclkFreq = 64000000;                      //設(shè)置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;     // 收發(fā)模式    USART_Init(WIFI_USART, &USART_InitStructure);                       // 初始化串口2
    // 優(yōu)先級,無優(yōu)先級分組    NVIC_SetPriority(WIFI_USART_IRQ, 0);
    // UARTx中斷使能    NVIC_EnableIRQ(WIFI_USART_IRQ);
    // 使能UARTx RC中斷    USART_ITConfig(WIFI_USART, USART_IT_RC, ENABLE);}
/****************************************************************** * 函 數(shù) 名 稱:WIFI_USART_Send_Bit * 函 數(shù) 說 明:向WIFI模塊發(fā)送單個字符 * 函 數(shù) 形 參:ch=字符 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:無******************************************************************/void WIFI_USART_Send_Bit(unsigned char ch){    // 發(fā)送一個字節(jié)    USART_SendData_8bit(WIFI_USART, (uint8_t)ch);
    // 等待發(fā)送完成    while( RESET == USART_GetFlagStatus(WIFI_USART, USART_FLAG_TXE) ){}}

/****************************************************************** * 函 數(shù) 名 稱:WIFI_USART_send_String * 函 數(shù) 說 明:向WIFI模塊發(fā)送字符串 * 函 數(shù) 形 參:str=發(fā)送的字符串 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:無******************************************************************/void WIFI_USART_send_String(unsigned char *str){        printf("string : %srn",str);        while( str && *str ) // 地址為空或者值為空跳出        {                WIFI_USART_Send_Bit(*str++);        }}//清除串口接收的數(shù)據(jù)/****************************************************************** * 函 數(shù) 名 稱:Clear_WIFI_RX_BUFF * 函 數(shù) 說 明:清除WIFI發(fā)過來的數(shù)據(jù) * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作       者: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;}

/****************************************************************** * 函 數(shù) 名 稱:WIFI_Send_Cmd * 函 數(shù) 說 明:向WIFI模塊發(fā)送指令,并查看WIFI模塊是否返回想要的數(shù)據(jù) * 函 數(shù) 形 參:cmd=發(fā)送的AT指令  ack=想要的應(yīng)答    waitms=等待應(yīng)答的時間     cnt=等待應(yīng)答多少次 * 函 數(shù) 返 回:1=得到了想要的應(yīng)答   0=沒有得到想要的應(yīng)答 * 作       者: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.發(fā)送AT指令        while(cnt--)        {                //時間間隔                delay_1ms(waitms);                //串口中斷接收藍(lán)牙應(yīng)答                if( WIFI_RX_FLAG == 1 )                {                        WIFI_RX_FLAG = 0;                        WIFI_RX_LEN = 0;                        //查找是否有想要的數(shù)據(jù)                        if( strstr((char*)WIFI_RX_BUFF, ack) != NULL )                        {                                        return 1;                        }                        //清除接收的數(shù)據(jù)                        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;}
/****************************************************************** * 函 數(shù) 名 稱:WIFI_ESP01S_Init * 函 數(shù) 說 明:WIFI模塊ESP01S初始化 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:ESP01S的默認(rèn)波特率是115200******************************************************************/void WIFI_ESP01S_Init(void){        WIFI_USART_Init(115200);//默認(rèn)波特率為115200}
/****************************************************************** * 函 數(shù) 名 稱:WIFI_MODE_AP_Init * 函 數(shù) 說 明:開啟AP模式,即模塊開啟熱點讓手機連接 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:1=配置成功   其他=失敗 * 作       者:LC * 備       注:手機通過WIFI模塊默認(rèn)的IP地址192.168.4.1和設(shè)置的端口號,進(jìn)行連接******************************************************************/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);  //設(shè)置wifi賬號與密碼        if( ret != 1 ) return ret;
    ret = WIFI_Send_Cmd("AT+RSTrn","ready",800,3); //重新復(fù)位        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); //開啟服務(wù)器設(shè)置端口號為5000    if( ret != 1 ) return ret;    return ret;}




/****************************************************************** * 函 數(shù) 名 稱:Get_Device_connection_status * 函 數(shù) 說 明:獲取設(shè)備連接狀態(tài)(AP模式) * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:0=沒有設(shè)備連接 *              1=有設(shè)備連接了WIFI *              2=有設(shè)備斷開了WIFI *              3=有設(shè)備連接了服務(wù)器 *              4=有設(shè)備斷開了服務(wù)器 * 作       者:LC * 備       注:手機要連接WIFI模塊的步驟是先連接WIFI再連接服務(wù)器//當(dāng)有設(shè)備連接AP模式下的熱點時,WIFI模塊會給連接的設(shè)備分配IP地址//我們只需檢測是否有分配地址,則知道是否有設(shè)備連接。//設(shè)備連接時WIFI返回://  +STA_CONNECTED:"f0:6c:5d:d6:f6:18"//  +DIST_STA_IP:"f0:6c:5d:d6:f6:18","192.168.4.2"//設(shè)備斷開連接時返回://  +STA_DISCONNECTED:"f0:6c:5d:d6:f6:18"******************************************************************/uint8_t Get_Device_connection_status(void){    //串口中斷接收WIFI應(yīng)答    if( WIFI_RX_FLAG == 1 )    {        WIFI_RX_FLAG = 0;        WIFI_RX_LEN = 0;        //有設(shè)備連接了熱點        if( strstr((char*)WIFI_RX_BUFF, "+STA_CONNECTED") != NULL )        {            //清除接收的數(shù)據(jù)            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;        }        //有設(shè)備斷開了熱點        if( strstr((char*)WIFI_RX_BUFF, "+STA_DISCONNECTED") != NULL )        {            //清除接收的數(shù)據(jù)            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;        }        //有設(shè)備連接了服務(wù)器        if( strstr((char*)WIFI_RX_BUFF, ",CONNECT") != NULL )        {            //清除接收的數(shù)據(jù)            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        }        //有設(shè)備斷開了服務(wù)器        if( strstr((char*)WIFI_RX_BUFF, ",CLOSED") != NULL )        {            //清除接收的數(shù)據(jù)            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;}

/********************************************************** * 函 數(shù) 名 稱:Get_WIFI_AP_Data * 函 數(shù) 功 能:解析設(shè)備發(fā)送過來的數(shù)據(jù) * 傳 入 參 數(shù):ap_parameter要將數(shù)據(jù)保存的地址 * 函 數(shù) 返 回:1:有設(shè)備發(fā)送過來數(shù)據(jù)        0:沒有設(shè)備發(fā)送過來數(shù)據(jù) * 作       者: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;
    //接收到設(shè)備發(fā)過來的數(shù)據(jù)    if( strstr((char*)WIFI_RX_BUFF,"+IPD,") != NULL )    {        test = strstr((char*)WIFI_RX_BUFF,"+IPD,");
        //記錄設(shè)備ID號        strncpy(buff,test+5,1);        buff[1] ='';        ap_parameter->device_id = atoi(buff);        printf("device_id = %srn",buff);
        //記錄發(fā)送過來的數(shù)據(jù)長度        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);        //記錄發(fā)送過來的數(shù)據(jù)        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;}/****************************************************************** * 函 數(shù) 名 稱:WIFI_Send_To_Client * 函 數(shù) 說 明:AP模式下,WIFI發(fā)送數(shù)據(jù)至客戶端(連接AP模式下熱點的設(shè)備) * 函 數(shù) 形 參:id=向第幾個客戶端發(fā)送數(shù)據(jù)   data=要發(fā)送的數(shù)據(jù)(字符串形式) * 函 數(shù) 返 回:0=發(fā)送失敗   1=發(fā)送成功 * 作       者:LC * 備       注:使用該函數(shù)函數(shù)請確保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;}
/****************************************************************** * 函 數(shù) 名 稱:mstrcat * 函 數(shù) 說 明:字符串連接 * 函 數(shù) 形 參:s1:目標(biāo)字符串, s2:源字符串 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:哈希使用******************************************************************/static void mstrcat(char *s1, const char *s2){    // 尋找s1的末尾(即''字符)    while(*s1 != '')        s1++;    // 將s2的內(nèi)容復(fù)制到s1的末尾,包括s2的結(jié)束字符''    while((*s1++ = *s2++));}
/****************************************************************** * 函 數(shù) 名 稱:CalculateSha1 * 函 數(shù) 說 明:計算sha1密匙 * 函 數(shù) 形 參:password:密匙存放緩沖區(qū) * 函 數(shù) 返 回:無 * 作       者: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);        }}
/****************************************************************** * 函 數(shù) 名 稱:WIFI_MODE_STA_Aliyun_Init * 函 數(shù) 說 明:配置WIFI模塊連接阿里云物聯(lián)網(wǎng)平臺 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:無******************************************************************/void WIFI_MODE_STA_Aliyun_Init(void){        char AT_CMD[250]={0};        uint8_t PassWord[50] = {0};  //存放的是哈希計算的密鑰
        RST:    //測試指令A(yù)T        WIFI_Send_Cmd("ATrn","OK",100,3);
        //配置WIFI STA        WIFI_Send_Cmd("AT+CWMODE=1rn","OK",300,3);
        //設(shè)置時區(qū)  NTSP服務(wù)器  用于調(diào)整客戶端自身所在系統(tǒng)的時間,達(dá)到同步時間的目的        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名稱或密碼有錯,復(fù)位重啟rn");        //wifi連接不上,重啟                WIFI_Send_Cmd("AT+RSTrn","ready",1000,1);                goto RST;        }        //清0數(shù)組,備用        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);
        //設(shè)置連接客戶端ID        memset(AT_CMD,0,sizeof(AT_CMD));  //清0數(shù)組,備用        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失敗,復(fù)位STM32重連rn");        //wifi連接不上,重啟  1000延時1S    2鏈接次數(shù)                WIFI_Send_Cmd("AT+RSTrn","ready",1000,2);//                __set_FAULTMASK(1); //STM32程序軟件復(fù)位                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();//清除串口接收緩存    //上電就上傳數(shù)據(jù)至手機//        Publish_MQTT_message(publish_mqtt_message,5,); //發(fā)布主題}



/*點擊LED開關(guān)+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"}*//****************************************************************** * 函 數(shù) 名 稱:Get_Aliyun_json_data * 函 數(shù) 說 明:獲取阿里云JSON格式的數(shù)據(jù)(接收手機發(fā)送過來的數(shù)據(jù)) * 函 數(shù) 形 參:data=數(shù)據(jù)的保存地址 * 函 數(shù) 返 回:1=接收到JSON數(shù)據(jù)并處理   0=沒有接收到數(shù)據(jù) * 作       者:LC * 備       注:無******************************************************************/uint8_t Get_Aliyun_json_data(JSON_PUBLISH *data){        char *buff=0;    //串口中斷接收WIFI應(yīng)答    if( WIFI_RX_FLAG == SET )    {                printf("rn--rn");        WIFI_RX_FLAG = 0;        WIFI_RX_LEN = 0;        //有設(shè)備連接了熱點        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;}

/****************************************************************** * 函 數(shù) 名 稱:Clear_Aliyun_json_data * 函 數(shù) 說 明:清除JSON接收過的數(shù)據(jù) * 函 數(shù) 形 參:data=要清除的數(shù)據(jù) * 函 數(shù) 返 回:無 * 作       者: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++] = '';        }}
//在自定義功能時,有多少個標(biāo)識符,就添加多少個//我就只有兩個標(biāo)識符。//LED_Switch=LED開關(guān) 范圍0-1//brightness=亮度    范圍0-100JSON_PUBLISH publish_mqtt_message[2]={        { ""LED_Switch":","0" },        { ""brightness":","0" }};
/****************************************************************** * 函 數(shù) 名 稱:Publish_MQTT_message * 函 數(shù) 說 明:發(fā)布主題 ,上發(fā)多個數(shù)據(jù)(設(shè)備將數(shù)據(jù)發(fā)送至手機) * 函 數(shù) 形 參:data=publish_mqtt_message, data_num=上傳的數(shù)據(jù)個數(shù) * 函 數(shù) 返 回:無 * 作       者: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結(jié)構(gòu)體的value        sprintf(data[1].value,"%d",90);
        //          4        for(i=0;i<data_num;i++)        {        // 3                if(i<(data_num-1))                {                        sprintf(sp,"%s%s%s",data[i].keyname,data[i].value,",");                        while(*sp!=0) {sp++;} //防止覆蓋                }                else                        sprintf(sp,"%s%s",data[i].keyname,data[i].value);        }        sprintf(AT_CMD,"AT+MQTTPUB=0,"%s","{"params":{%s}}",1,0rn",PublishMessageTopPost,params);        //發(fā)送指令后等待2000ms再判斷是否發(fā)送成功,不發(fā)送成功則重發(fā)3-1次    //這里會阻塞CPU的運行,可以直接使用    WIFI_USART_send_String(AT_CMD); 發(fā)送,但是無法判斷是否發(fā)送成功。    WIFI_Send_Cmd(AT_CMD,"OK",2000,3);}

/****************************************************************** * 函 數(shù) 名 稱:WIFI_USART_IRQHandler * 函 數(shù) 說 明:連接WIFI的串口中斷服務(wù)函數(shù) * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:無******************************************************************/void WIFI_USART_IRQHandler(void){        if(USART_GetITStatus(WIFI_USART, USART_IT_RC) == SET) // 接收緩沖區(qū)不為空        {                        //接收數(shù)據(jù)                        WIFI_RX_BUFF[ WIFI_RX_LEN ] = USART_ReceiveData(WIFI_USART);
#if DEBUG                        //測試,查看接收到了什么數(shù)據(jù)                        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] = ''; //字符串結(jié)尾補 ''                        WIFI_RX_FLAG = SET;               // 接收完成
                        USART_ClearITPendingBit(WIFI_USART, USART_IT_RC); //已經(jīng)處理就清楚標(biāo)志位        }}

在文件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調(diào)試,查看WIFI回顯數(shù)據(jù)#define     DEBUG   1
/****************************   STA模式    ****************************///STA模式下,WIFI模塊要連接的熱點(需要自行修改為自己的參數(shù))#define  WIFISSID       "aaa"               //wifi熱點名稱#define  WIFIPASS       "12345678"          //wifi熱點密碼
//連接的阿里云IP端口(不可修改)#define  IP             "203.107.45.14"     //阿里云服務(wù)器IP或域名//#define  IP           "a1PaQm83lGg.iot-as-mqtt.cn-shenzhen.aliyuncs.com"   //服務(wù)器IP或域名#define  PORT           1883                            //連接端口號,MQTT默認(rèn)1883
//阿里云三元組(需要自行修改為自己的參數(shù))#define DeviceName       "TEST"                   //設(shè)備名稱#define ProductKey       "a1PJRLOWo3p"            //產(chǎn)品密匙#define DeviceSecret     "3e7a1a43694b65abdcbc4f5c724e9faf"        //設(shè)備密匙
//計算哈希算法用到加密(不可修改)#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)                               //用戶名
//訂閱發(fā)布的主題(不可修改)#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)
//上傳數(shù)據(jù)結(jié)構(gòu)體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的引腳復(fù)用#define BSP_GPS_AF_UART_RX()       PA03_AFx_UART2RXD()        // GPIO的引腳復(fù)用
#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中斷服務(wù)函數(shù)

#define WIFI_RX_LEN_MAX     200       //串口接收最大長度
extern uint8_t wifi_link_flag;//設(shè)備連接狀態(tài)//配合    Get_Device_connection_status    函數(shù)使用// *              0=沒有設(shè)備連接// *              1=有設(shè)備連接了WIFI// *              0=有設(shè)備斷開了WIFI// *              2=有設(shè)備連接了服務(wù)器// *              3=有設(shè)備斷開了服務(wù)器

void WIFI_ESP01S_Init(void);            //WIFI模塊初始化uint8_t WIFI_MODE_AP_Init(void);        //AP模式初始化uint8_t Get_Device_connection_status(void);//獲取連接狀態(tài)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模塊開啟熱點、多連接、服務(wù)器。待手機連接后,通過手機APP進(jìn)行數(shù)據(jù)互傳。

使用案例前,請確保bsp_esp01s.c和bsp_esp01s.h移植成功。

手機APP下載地址:

鏈接:https://pan.baidu.com/s/1-wh0aaqRMW8fJ5nLH1Lwyw?pwd=LCKF

提取碼:LCKF

APP操作

首先使用手機連接WIFI模塊的熱點。其次打開APP連接服務(wù)器。服務(wù)器默認(rèn)IP為192.168.4.1,端口號在代碼中設(shè)置為了5000。

連接上WIFI的熱點后,打開APP連接服務(wù)器。

編輯各個按鈕值,方便后面我們進(jìn)行控制。

在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();
    //設(shè)置WIFI模塊為AP模式    WIFI_MODE_AP_Init();    while(1)    {        //判斷是否有設(shè)備連接        Get_Device_connection_status();        //如果當(dāng)前設(shè)備連接了服務(wù)器(手機APP連接上熱點)        if( wifi_link_flag == 2 )        {            if( Get_WIFI_AP_Data(&ap_parameter) == 1 )//如果接收到數(shù)據(jù)            {                                //輸出接收的數(shù)據(jù)                printf("ID = %drn", ap_parameter.device_id );//設(shè)備ID                printf("data len = %drn", ap_parameter.device_datalen );//發(fā)送過來的數(shù)據(jù)長度                printf("data = %srn", ap_parameter.device_data );//發(fā)送過來的數(shù)據(jù)

            }        }    }}

案例現(xiàn)象:

當(dāng)手機APP接入WIFI連接成功之后,APP發(fā)送數(shù)據(jù)到開發(fā)板的串口。

默認(rèn)ip:192.168.4.1 默認(rèn)端口:5000

工程代碼下載:

鏈接:https://pan.baidu.com/s/16IPzyT_Rdm2E2BgPvYe-pw?pwd=LCKF

提取碼:LCKF

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

以開放、共享、互助為理念,致力于構(gòu)建武漢芯源半導(dǎo)體CW32系列MCU生態(tài)社區(qū)。無論是嵌入式MCU小自還是想要攻破技術(shù)難題的工程師,亦或是需求解決方案的產(chǎn)品經(jīng)理都可在CW32生態(tài)社區(qū)汲取營養(yǎng)、共同成長。

B站