找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3821|回復: 2
收起左側

stm32+4G從零開始連接阿里云lot 源程序

  [復制鏈接]
ID:956564 發(fā)表于 2021-7-26 16:02 | 顯示全部樓層 |閱讀模式
stm32 4G從零開始連接阿里云IOT【490487】與4G模塊通信——AT指令框架.7z (1.17 MB, 下載次數(shù): 124)

stm32 4G從零開始連接阿里云IOT【490488】STM32 4G設備接入阿里云物聯(lián)網(wǎng).7z (1.11 MB, 下載次數(shù): 99)

stm32 4G從零開始連接阿里云IOT【490489】物模型介紹.7z (1.17 MB, 下載次數(shù): 56)

stm32 4G從零開始連接阿里云IOT【490490】OTA(一)bootloader設計.7z (835.54 KB, 下載次數(shù): 53)

stm32 4G從零開始連接阿里云IOT【490492】OTA(三)固件下載.7z (792.69 KB, 下載次數(shù): 53)

stm32 4G從零開始連接阿里云IOT【490493】OTA(四)設備OTA全流程.7z (1.16 MB, 下載次數(shù): 59)

之前搞設計的時用stm32通過廣和通4g模塊,最后連接到阿里云的云端,上傳了數(shù)據(jù)并分析數(shù)據(jù),希望對大家有用

主要代碼如下:

//EC20  移遠4G模塊

#define AT_RECEIVE_BUFFER_LEN       1536   
static uint8_t          s_ATCmdReceiveBuffer[AT_RECEIVE_BUFFER_LEN];

static void ATUartInit(void)
{
    UartInit(UART_2,115200,s_ATCmdReceiveBuffer,AT_RECEIVE_BUFFER_LEN,100,0);
}
static void ATUartDeinit(void)
{
    UartDeinit(UART_2);
}

static int ATUartSend(const char* cmd,int len)
{
    UartSend(UART_2,(const uint8_t*)cmd,len);
    return 1;
}
static int ATUartRead(char* replyBuff,int maxLen)
{
    return UartRead(UART_2,1,(uint8_t*)replyBuff,maxLen);
}

static const ATPort    s_cATParserPort =
{
    .fpUartInit = ATUartInit,
    .fpUartDeinit = ATUartDeinit,
    .fpUartSend = ATUartSend,
    .fpUartRead = ATUartRead,
    .cPrefix = "\r\n",
    .cSuffix = "\r\n",
};

//電源上/下電
static void ModulePowerOn(int flg)
{

}

//模塊休眠
static void ModuleSleep(void)
{

}

//初始化指令
static const MODULE_ATCMD_CFG  s_ModuleInitCmd[] =
{
    {
        .at_cmd = "AT\r\n",         //AT指令
        .at_len = sizeof("AT\r\n")-1,         //AT指令長度
        .at_will = "OK",        //希望收到的回復
        .timeout = 3000,        //超時時間
        .resendCnt = 10,      //重發(fā)次數(shù)
    },
    {
        .at_cmd = "ATE0\r\n",         //ATE0指令,關閉回顯
        .at_len = sizeof("ATE0\r\n") - 1,         //AT指令長度
        .at_will = "OK",        //希望收到的回復
        .timeout = 3000,        //超時時間
        .resendCnt = 3,      //重發(fā)次數(shù)
    },
    {
        .at_cmd = "AT+CSQ\r\n",         //ATE0指令,關閉回顯
        .at_len = sizeof("AT+CSQ\r\n")-1,         //AT指令長度
        .at_will = "OK",        //希望收到的回復
        .timeout = 3000,        //超時時間
        .resendCnt = 3,      //重發(fā)次數(shù)
    },
    {
        .at_cmd = "AT+CGREG?\r\n",         //查詢GPRS連接狀態(tài)
        .at_len = sizeof("AT+CGREG?\r\n")-1,         //AT指令長度
        .at_will = "+CGREG: 0,1",        //希望收到的回復
        .timeout = 3000,        //超時時間
        .resendCnt = 12,      //重發(fā)次數(shù)
    },

};

//查詢IP地址
static int CheckIpCMD(const char buff[],int buffLen,char ip[])
{
    int context_state = 0;
    int context_id = 0;
    int context_type = 0;
    const char* tmp = strstr(buff,"+QIACT: 1");
    if(tmp)
    {
        int iNum = sscanf(tmp,"+QIACT: %d,%d",&context_id,&context_state);
        if(iNum == 2)
        {
            if(context_state)       //已激活,有IP
            {
                iNum = sscanf(tmp,"+QIACT: %d,%d,%d,\"%[^\"]",&context_id,&context_state,&context_type,ip);
                if(iNum == 4)
                    return strlen(ip);
            }
        }
    }
    return 0;
}
//獲取IP地址
static int GetIpCMD(const char buff[],int buffLen,char ip[])
{
    //return CheckIpCMD(buff,buffLen,ip);
    return 1;
}

static const ATModuleIP     s_cATModuleIPPort =
{
    .fpMakeCheckIp = CheckIpCMD,            
    .pcCheckIp = "AT+QIACT?\r\n",                 //查詢IP的AT指令
    .pcCheckIpSuccess = "OK",                  //查詢IP的AT指令成功

    .fpMakeGetIp = GetIpCMD,               
    .pcGetIp = "AT+QIACT=1\r\n",                   //請求獲取IP的AT指令
    .pcGetIpSuccess = "OK",                    //請求獲取IP的AT指令成功

    .iTimeOut = 30*1000,
};

void MakeTcpConnectCMD(int id,const char* ip,uint16_t port,char buff[],int buffLen)
{
    snprintf(buff,buffLen,"AT+QIOPEN=1,0,\"TCP\",\"%s\",%d,0,1\r\n",ip,port);
}
void MakeTcpDisconnectCMD(int id,char buff[],int buffLen)
{
    snprintf(buff,buffLen,"AT+QICLOSE=0\r\n");
}
void MakeTcpSendHeadCMD(int id,const uint8_t* pkt,int len,char buff[],int buffLen)
{
    snprintf(buff,buffLen,"AT+QISEND=0,%d\r\n",len);
}
void MakeTcpSendCMD(int id,const uint8_t* pkt,int len,char buff[],int buffLen)
{
    memcpy(buff,pkt,len);
    buff[len] = 0;
}


void ParserTcpReceiveCMD(int* id,const char* pkt,int pktLen,uint8_t* buff,int *len)
{
    const char *c_ucReceiveHead = strstr(pkt,"+QIURC: \"recv\"");
    if(c_ucReceiveHead)
    {
        int id = 0;
        int datalen = 0;
        int iNum = sscanf(c_ucReceiveHead,"+QIURC: \"recv\",%d,%d",&id,&datalen);
        if(iNum == 2)
        {
            const char* dataHead = strstr(c_ucReceiveHead,"\r\n");
            if(dataHead)
                dataHead += 2;
            memcpy(buff,dataHead,datalen);
            *len = datalen;
        }
    }
}

//初始化指令
static const MODULE_ATCMD_CFG  s_MqttConfigCmd[] =
{
    {
        .at_cmd = "AT+QMTCFG=\"recv/mode\",0,0,1\r\n",         //AT指令
        .at_len = sizeof("AT+QMTCFG=\"recv/mode\",0,0,1\r\n") - 1,         //AT指令長度
        .at_will = "OK",        //希望收到的回復
        .timeout = 3000,        //超時時間
        .resendCnt = 3,      //重發(fā)次數(shù)
    },
};

static const ATModuleTCP    s_cATModuleTCPPort =
{
    .fpMakeTcpConnect = MakeTcpConnectCMD,
    .fpMakeTcpDisconnect = MakeTcpDisconnectCMD,
    .fpMakeTcpSendHead = MakeTcpSendHeadCMD,
    .fpMakeTcpSend = MakeTcpSendCMD,
    .fpParserTcpReceive = ParserTcpReceiveCMD,
    .pcConnectSuccess = "+QIOPEN: 0,0",
    .pcSendHead = ">",
    .pcSendSuccess = "SEND OK",
    .pcDisconnectHead = "OK",
    .pcReceiveURC = "+QIURC: \"recv\"",
    .pcDisconnectURC = "+QIURC: \"closed\"",
    .iTimeout = 20*1000,
};

static uint16_t s_usMqttMsgID = 1;

//生成MQTT的TCP連接的AT指令
void MakeMqttTCPConnectCMD(const char* ip,uint16_t port,char buff[],int buffLen)
{
    snprintf(buff,buffLen,"AT+QMTOPEN=0,\"%s\",%d\r\n",ip,port);
}
//生成MQTT的連接AT指令
void MakeMqttConnectCMD(const char* clientid,const char* username,const char* password,char buff[],int buffLen)
{
    snprintf(buff,buffLen,"AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n",clientid,username,password);
}
//生成MQTT的SUB AT指令
void MakeMqttSubCMD(const char* topic,int qos,char buff[],int buffLen)
{

    snprintf(buff,buffLen,"AT+QMTSUB=0,%d,\"%s\",%d\r\n",s_usMqttMsgID++,topic,qos);
}
//生成MQTT的PUB AT指令
void MakeMqttPubCMD(const char* topic,const char* payload,int payloadLen,int qos,char buff[],int buffLen)
{
    snprintf(buff,buffLen,"AT+QMTPUBEX=0,%d,%d,0,\"%s\",%d\r\n",s_usMqttMsgID,qos,topic,payloadLen);
}

//生成MQTT的PUB AT指令
void MakeMqttPubMessageCMD(const char* topic,const char* payload,int payloadLen,int qos,char buff[],int buffLen)
{
    memcpy(buff,payload,payloadLen);
    buff[payloadLen] = 0;
}

//生成MQTT的UNSUB AT指令
void MakeMqttUnSubCMD(const char* topic,int qos,char buff[],int buffLen)
{
    snprintf(buff,buffLen,"AT+QMTUNS=0,%d,\"%s\",%d\r\n",s_usMqttMsgID++,topic,qos);
}

//生成MQTT退出登錄連接指令
void MakeMqttLogoutCMD(char buff[],int buffLen)
{
    snprintf(buff,buffLen,"AT+QMTCLOSE=0\r\n");
}


//生成MQTT主動斷開連接指令
void MakeMqttDisconnectCMD(char buff[],int buffLen)
{
    snprintf(buff,buffLen,"AT+QMTDISC=0\r\n");
}

//生成MQTT接收PUB解析數(shù)據(jù)
void ParserMqttPubCMD(const char* pkt,int len,char* topic,char* payload,int *payloadLen,int *qos)
{
    const char* cmdHead = 0;
    cmdHead = strstr(pkt,"+QMTRECV");
    if(pkt)
    {
        int clientID = 0;
        int msgID = 0;

        sscanf(cmdHead,"+QMTRECV: %d,%d,\"%[^\"]\",\"%[^\"]",&clientID,&msgID,topic,payload);
    }
}

static const ATModuleMqtt   s_cATModuleMqttPort =
{
    .pMqttConfig = s_MqttConfigCmd,
    .iMqttCfgCmdNum = sizeof(s_MqttConfigCmd)/sizeof(MODULE_ATCMD_CFG),
    .fpMakeMqttTcpConnect = MakeMqttTCPConnectCMD,
    .fpMakeMqttConncet = MakeMqttConnectCMD,
    .fpMakeMqttSub = MakeMqttSubCMD,
    .fpMakeMqttPub = MakeMqttPubCMD,
    .fpMakeMqttPubMessage = MakeMqttPubMessageCMD,
    .fpMakeMqttUnSub = MakeMqttUnSubCMD,
        .fpMakeMqttLogout = MakeMqttLogoutCMD,
    .fpMakeMqttDisconnect = MakeMqttDisconnectCMD,
    .fpParserMqttPub = ParserMqttPubCMD,

    .pcMqttConnectSuccess = "+QMTOPEN: 0,0",
    .pcMqttLoginSuccess = "+QMTCONN: 0,0",
    .pcMqttPubHead = ">",
    .pcMqttPubSuccess = "+QMTPUBEX: 0",
    .pcMqttSubSuccess = "+QMTSUB: 0",/*,<msgID>,<result>*/
    .pcMqttUnsubSuccess = "+QMTUNS: 0",
    .pcMqttLogoutSuccess = "+QMTCLOSE: 0,0",
    .pcMqttDisconnectSuccess = "OK",

    .pcMqttPubURC = "+QMTRECV:",
    .pcMqttDisconnectURC = "+QMTSTAT: 0",

    .iTimeout = 20*1000,
};

ATModuleConfig      g_ATModule;

void ATModuleInit(pATGetSystick f)
{
    module_init(&g_ATModule);
    g_ATModule.pInitCmd = s_ModuleInitCmd;               //AT設備初始化的指令
    g_ATModule.iInitCmdNum = sizeof(s_ModuleInitCmd)/sizeof(MODULE_ATCMD_CFG);            //初始化指令個數(shù)
    g_ATModule.fpPowerOn = ModulePowerOn;              //模塊上電
    g_ATModule.fpSleep = ModuleSleep;                //模塊休眠
    g_ATModule.atConfig.atPort = &s_cATParserPort;               //
    g_ATModule.atConfig.fpSystick = f;
    g_ATModule.atIpCfg = &s_cATModuleIPPort;                //IP指令
    g_ATModule.atTcpCfg = &s_cATModuleTCPPort;               //TCP連接指令
    g_ATModule.atMqttCfg = &s_cATModuleMqttPort;              //MQTT連接指令

    at_parser_log(&g_ATModule.atConfig,1);          //啟動日志監(jiān)控
}

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:441966 發(fā)表于 2021-10-26 17:15 | 顯示全部樓層
真是好東西,正需要研究4G呢,謝謝樓主了
回復

使用道具 舉報

ID:904364 發(fā)表于 2022-2-28 14:47 | 顯示全部樓層
多謝樓主,正要搞4g
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表