lugl4313820 发表于 2021-12-19 00:23

【安信可NB-IoT开发板EC-01F-Kit测评】STM32F103C8T6 连接MQTT发布数据

<div class='showpostmsg'><p><span style="font-size:20px;">昨天完成了手工的连接,今天用STM32F103连接开发板成功发布数据。</span></p>

<p>两块开发板的连接:STM32F103C8T6的串口2 TX(PA2)&mdash;&mdash; EC-01 RX1</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STM32F103C8T6的串口2 RX(PA3)&mdash;&mdash; EC-01 TX1</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STM32F103C8T6的开发板的VCC 3.3V &mdash;&mdash; EC-01 VCC3.3V</p>

<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; STM32F103C9T6&nbsp; &nbsp;GND&nbsp; &mdash;&mdash; EC-01 GND</p>

<p><span style="font-size:20px;">EC的库文件借鉴了<a href="https://gitee.com/ritage/stm32_-drive_-ec-01-f" target="_blank">RitaChen/STM32_Drive_EC-01F (gitee.com)</a>这位大神的代码。大家要是想连阿里云、OneNET的,可以不用改代码就可以用上。然而我要连自己的服务器,有点费事,还得改改。</span></p>

<p>EC616S.h</p>

<pre>
<code class="language-cpp">#ifndef __EC616S_H
#define __EC616S_H                          
#include "stm32f10x.h"

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;stdbool.h&gt;

#if defined ( __CC_ARM   )
#pragma anon_unions
#endif

//EC616S模式选择
typedef enum
{
    STA,
    AP,
    STA_AP
}ENUM_Net_ModeTypeDef;

typedef enum
{
        RF_Least_Func=0,
        RF_Full_Func=1,
        RF_OFF=4
}RF_Switch;

//附着网络
typedef enum{
        Register_Forbid=0,
        Register_status,
        Register_status_Location,
        Register_status_Location_failResaon,
        Register_status_Location_timer,
        Register_status_Location_failResaon_timer
} Attach_Net_Mode;

#define EC616S_RST_Pin          GPIO_Pin_4    //复位管脚
#define EC616S_RST_Pin_Port   GPIOA    //复位
#define EC616S_RST_Pin_Periph_ClockRCC_APB2Periph_GPIOA       //复位时钟

#define EC616S_CH_PD_Pin   GPIO_Pin_5   //使能管脚
#define EC616S_CH_PD_Pin_Port   GPIOA   //使能端口
#define EC616S_CH_PD_Pin_Periph_ClockRCC_APB2Periph_GPIOA                     //使能时钟


#define EC616S_RST_Pin_SetH   GPIO_SetBits(EC616S_RST_Pin_Port,EC616S_RST_Pin)
#define EC616S_RST_Pin_SetL   GPIO_ResetBits(EC616S_RST_Pin_Port,EC616S_RST_Pin)


#define EC616S_CH_PD_Pin_SetH   GPIO_SetBits(EC616S_CH_PD_Pin_Port,EC616S_CH_PD_Pin)
#define EC616S_CH_PD_Pin_SetL   GPIO_ResetBits(EC616S_CH_PD_Pin_Port,EC616S_CH_PD_Pin)


#define EC616S_USART(fmt, ...)USART_printf (USART2, fmt, ##__VA_ARGS__)   
#define PC_USART(fmt, ...)       printf(fmt, ##__VA_ARGS__)       //这是串口打印函数,串口1,执行printf后会自动执行fput函数,重定向了printf。



#define RX_BUF_MAX_LEN 1024       //最大字节数
extern struct STRUCT_USART_Fram   //数据帧结构体
{
    char Data_RX_BUF;
    union
    {
      __IO u16 InfAll;
      struct
      {
            __IO u16 FramLength       :15;                               // 14:0
            __IO u16 FramFinishFlag   :1;                              // 15
      }InfBit;
    };
       
}EC616S_Fram_Record_Struct;


//初始化和TCP功能函数
void EC616S_Init(u32 bound);
void EC616S_AT_Test(void);
bool EC616S_Send_AT_Cmd(char *cmd,char *ack1,char *ack2,u32 time);
void EC616S_Rst(void);
bool EC616S_RF_Mode_Choose(RF_Switch RFmode);
bool EC616S_Net_Attached_Mode_Choose(Attach_Net_Mode Netmode, bool stepSwitch);

bool EC616S_MQTT_Pub( char * topic,char * message);
bool EC616S_MQTT_Sub( char * topic );

bool EC616S_Port_Inquire(char * confirmMsg, bool stepSwitch);
bool EC616S_Network_Status_Inquire(char * confirmMsg, bool stepSwitch);
bool EC616S_Create_OneNET_Connection(bool stepSwitch);
bool EC616S_ADD_Object(char * objectID,int16_t instanceCount, char * instanceBitmap, int16_t attributecount, int16_t actioncount, bool stepSwitch );
bool EC616S_Register_Request(int16_t lifeCycle, int16_t registerUnit,bool stepSwitch);
bool EC616S_Register_Source(int16_t resourceIDLen, char * resourceID, bool stepSwitch);
bool EC616S_Logout(void);
bool EC616S_Delete_Object(char ClientNum, char * objectID);
bool EC616S_Delete_instance(int16_t ClientNum);
bool EC616S_Notify(char * objectID, char * resourceID, int16_t valueLen, char * value);
bool EC616S_Link_lugl_Server( bool stepSwitch);
bool EC616S_Open_lugl_Client_Link (bool stepSwitch);
void USART_printf( USART_TypeDef * USARTx, char * Data, ... );

#endif
</code></pre>

<p>EC616S.c</p>

<pre>
<code>#include "EC616S.h"
#include "usart.h"
#include "delay.h"
#include &lt;stdarg.h&gt;
#include "stdlib.h"

static char msgID = {0};

struct STRUCT_USART_Fram EC616S_Fram_Record_Struct = { 0 };//定义了一个数据帧结构体
void EC616S_Init(u32 bound)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(EC616S_RST_Pin_Periph_Clock|EC616S_CH_PD_Pin_Periph_Clock, ENABLE);

        GPIO_InitStructure.GPIO_Pin = EC616S_RST_Pin;            
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
        GPIO_Init(EC616S_RST_Pin_Port, &amp;GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = EC616S_CH_PD_Pin;               
        GPIO_Init(EC616S_CH_PD_Pin_Port, &amp;GPIO_InitStructure);
        uart2_Init(bound);
        EC616S_Rst();
}

//对EC616S模块发送AT指令
// cmd 待发送的指令
// ack1,ack2;期待的响应,为NULL表不需响应,两者为或逻辑关系
// time 等待响应时间
//返回1发送成功, 0失败
bool EC616S_Send_AT_Cmd(char *cmd,char *ack1,char *ack2,u32 time)
{
    EC616S_Fram_Record_Struct .InfBit .FramLength = 0; //重新接收新的数据包
    EC616S_USART("%s\r\n", cmd);
    if(ack1==0&amp;&amp;ack2==0)   //不需要接收数据
    {
                return true;
    }
        printf("delay some time to get receive data\r\n");
    delay_ms(time);   //提供足够的时间用于接收数据,(数据接收部分在uart中断usart.h --&gt; USART2_IRQHandler(void) 中完成)
        delay_ms(1000);
    EC616S_Fram_Record_Struct.Data_RX_BUF = '\0';
               
    printf("EC616S_data:%s",EC616S_Fram_Record_Struct .Data_RX_BUF);
    if(ack1!=0&amp;&amp;ack2!=0)
    {
      return ( ( bool ) strstr ( EC616S_Fram_Record_Struct .Data_RX_BUF, ack1 ) ||         //查询
                         ( bool ) strstr ( EC616S_Fram_Record_Struct .Data_RX_BUF, ack2 ) );
    }
    else if( ack1 != 0 )//strstr(s1,s2);检测s2是否为s1的一部分,是返回该位置,否则返回false,它强制转换为bool类型了
      return ( ( bool ) strstr ( EC616S_Fram_Record_Struct .Data_RX_BUF, ack1 ) );

    else if( ack2 != 0 )
      return ( ( bool ) strstr ( EC616S_Fram_Record_Struct .Data_RX_BUF, ack2 ) );
        else
                return false;
}


//复位重启
void EC616S_Rst(void)
{
    EC616S_RST_Pin_SetL;
    delay_ms(500);
    EC616S_RST_Pin_SetH;
}


//发送恢复出厂默认设置指令将模块恢复成出厂设置
void EC616S_AT_Test(void)
{
    char count=0;
    delay_ms(1000);
    while(count &lt; 10)
    {
                printf("AT Test\r\n");
      if(EC616S_Send_AT_Cmd("AT","OK",NULL,500))
      {
            printf("OK\r\n");
            return;
      }
      ++ count;
    }
}


//EC616S的射频电路的关闭与开启方法
//设置成功返回OK 反之ERROR
bool EC616S_RF_Mode_Choose(RF_Switch RFmode)
{
    switch ( RFmode )
    {
      case RF_Least_Func:
                        printf("set RF mode: 0\r\n");
            return EC616S_Send_AT_Cmd ( "AT+CFUN=0", "OK", NULL, 500 );

      case RF_Full_Func:
                        printf("set RF mode: 1\r\n");
            return EC616S_Send_AT_Cmd ( "AT+CFUN=1", "OK", NULL, 500 );

      case RF_OFF:
                        printf("set RF mode: 4\r\n");
            return EC616S_Send_AT_Cmd ( "AT+CFUN=4", "OK", NULL, 500 );

      default:
                        printf("illegle command");
                        return false;
    }      
}

//EC616S 附着网络
//EC616S的Attach_Net_Mode附着网络类型
//AT+CEREG=0:禁止附着网络
//设置成功返回OK 反之ERROR
bool EC616S_Net_Attached_Mode_Choose(Attach_Net_Mode Netmode, bool stepSwitch)
{
    if(stepSwitch){
                switch ( Netmode )
                {
                        case Register_Forbid:
                                printf("Attach_Net_Mode: 0\r\n");
                                return EC616S_Send_AT_Cmd ( "AT+CEREG=0", "OK", NULL, 500 );

                        case Register_status:
                                printf("Attach_Net_Mode: 1\r\n");
                                return EC616S_Send_AT_Cmd ( "AT+CFUN=1", "OK", NULL, 500 );

                        case Register_status_Location:
                                printf("Attach_Net_Mode: 2\r\n");
                                return EC616S_Send_AT_Cmd ( "AT+CEREG=2", "OK", NULL, 500 );
                       
                        case Register_status_Location_failResaon:
                                return EC616S_Send_AT_Cmd ( "AT+CEREG=3", "OK", NULL, 500 );
                       
                        case Register_status_Location_timer:
                                return EC616S_Send_AT_Cmd ( "AT+CEREG=4", "OK", NULL, 500 );

                        case Register_status_Location_failResaon_timer:
                                return EC616S_Send_AT_Cmd ( "AT+CEREG=4", "OK", NULL, 500 );
                       
                        default:
                                printf("illegle command");
                                return false;
                }
        }else
                return false;
}

//EC616S 配置入网云平台                AT+ECMTCFG="cloud",&lt;tcpconnectID&gt;,&lt;cloudtype&gt;,&lt;data type&gt;
//tcpconnectID                        MQTT类型入网设置为0
//cloudtype:
//                0 mosquitto平台
//                1 OneNet平台
//                2 阿里云
//                3-255 用户自定义
//data type:
//                阿里云定义如下
//                1 Json 数据
//                2 字符串数据
//设置成功返回OK 反之ERROR
bool EC616S_Cloud_Select( uint8_t cloudType, uint8_t dataType, bool stepSwitch)
{
        char cCmd ;
        if(stepSwitch){
                printf("Log in cloud: 1\r\n");
               
                sprintf ( cCmd, "AT+ECMTCFG =\"cloud\",0,%d,%d", cloudType, dataType );
                return EC616S_Send_AT_Cmd( cCmd, "OK", NULL, 1000 );
        }else
                return false;
}





//EC616S 打开客户端连接                AT+ECMTOPEN=&lt;tcpconnectID&gt;,“&lt;host_name&gt;”,&lt;port&gt;
bool EC616S_Open_lugl_Client_Link(bool stepSwitch)
{
    if(stepSwitch){
                char cStr ;
                sprintf ( cStr, "AT+ECMTOPEN=0,\"your host_name\",1883" );
                return EC616S_Send_AT_Cmd ( cStr, "OK", 0, 1000 );
        }else
                return false;
}

//设置成功返回true,反之fasle
bool EC616S_Link_lugl_Server( bool stepSwitch)
{
    if(stepSwitch){
                char cStr ;
                sprintf ( cStr, "AT+ECMTCONN=0,\"78376LS6RW10U\",\"user_name\",\"pwd\"");
                return EC616S_Send_AT_Cmd ( cStr, "OK", 0, 3000 );
        }else
                return false;
}


//EC616S发布数据
//设置成功返回true, 反之false
bool EC616S_MQTT_Pub ( char * topic,char * message)
{
        char cStr ;
        sprintf ( cStr, "AT+ECMTPUB=0,0,0,0,\"%s\",\"%s\"", topic , message );
    return EC616S_Send_AT_Cmd ( cStr, "OK", 0, 1000 );
}


//EC616S订阅数据
//设置成功返回true, 反之false
bool EC616S_MQTT_Sub ( char * topic )
{
        char cStr ;
        sprintf ( cStr, "AT+ECMTSUB=0,1,\"%s\",1", topic );
        return EC616S_Send_AT_Cmd ( cStr, "OK", 0, 1000 );
}


/*                                                                以下内容为入网OneNET的一些操作指令                                                */
//查询OneNET入网IP以及端口                服务器IP号以及端口号:"+MIPLCONFIG: 1,183.230.40.39,5683"
bool EC616S_Port_Inquire(char * confirmMsg, bool stepSwitch)
{
        char cStr ;
        if(stepSwitch){
                printf("OneNET IP &amp; PORT\r\n");
               
                sprintf ( cStr, "AT+MIPLCONFIG?" );
                return EC616S_Send_AT_Cmd ( cStr, "OK", confirmMsg, 1500 );
        }else
                return false;
}

//查询当前的网络状态,当且仅当返回“+CEREG:1,1”时表示网络正常,可入网OneNET
bool EC616S_Network_Status_Inquire(char * confirmMsg, bool stepSwitch)
{
        if(stepSwitch){
                printf("OneNET net status\r\n");
                return(EC616S_Send_AT_Cmd("AT+CEREG?","OK",confirmMsg,2000));
        }else
                return false;
}

//创建OneNET的连接,当且仅当返回“+MIPLCREATE: 0”时表示网络正常,可入网OneNET
bool EC616S_Create_OneNET_Connection(bool stepSwitch)
{
        if(stepSwitch){
                printf("create OneNET Cloud mount\r\n");
                return(EC616S_Send_AT_Cmd("AT+MIPLCREATE","OK",NULL,2000));
        }else
                return false;
}

//添加对象实例
//"AT+MIPLADDOBJ"命令需要
//                                                对象ID号
//                                                实例个数
//                                                实例位图(一个字符表示一个实例的位图,0表示不可用,1表示可用)
//                                                属性个数
//                                                操作个数
bool EC616S_ADD_Object(char * objectID,int16_t instanceCount, char * instanceBitmap, int16_t attributecount, int16_t actioncount, bool stepSwitch )
{
        if(stepSwitch){
                char cStr ;
                printf("create oneNET object\r\n");
                sprintf ( cStr, "AT+MIPLADDOBJ=0,%s,%d,\"%s\",%d,%d", objectID, instanceCount, instanceBitmap, attributecount, actioncount );
                return EC616S_Send_AT_Cmd ( cStr, "OK", NULL, 2000 );
        }else
                return false;
}

//向OneNET发送注册请求
//                参数内容:生命周期
//                                        注册周期的单位(s)
bool EC616S_Register_Request(int16_t lifeCycle, int16_t registerUnit, bool stepSwitch)
{
        char * tempData;
        int i = 0;
        bool flag = 0;
        tempData = (char *) malloc(sizeof(char) * 15);
       
        if(stepSwitch){
                char cStr ;
                printf("send oneNET register request\r\n");
                sprintf ( cStr, "AT+MIPLOPEN=0,%d,%d", lifeCycle ,registerUnit);
                flag = EC616S_Send_AT_Cmd ( cStr, "OK", "MIPLOBSERVE:", 3000 );
                if(flag){
                        tempData = strstr(EC616S_Fram_Record_Struct .Data_RX_BUF, "MIPLOBSERVE:");                //获取"MIPLOBSERVE"在字符串中的位置返回char指针
                        printf("template Data:%s\n",tempData);
                        tempData = tempData + sizeof("MIPLOBSERVE:") + 2;
                        while(*tempData!=','){
                                msgID = *tempData;
                                i ++;
                                tempData++;
                        }
                        printf("msgID is:%s\n",msgID);
                }
                return flag;
        }else
                return false;
}

//向OneNET注册资源
//                        参数:msgID,信息ID,每次注册分配的msgID均会变
//                                        resourceIDLen,资源长度
//                                        resourceID,资源内容
bool EC616S_Register_Source(int16_t resourceIDLen, char * resourceID, bool stepSwitch)
{
        if(stepSwitch){
                char cStr ;
                sprintf ( cStr, "AT+MIPLDISCOVERRSP=0,%s,1,%d,\"%s\"", msgID, resourceIDLen,resourceID);
                return EC616S_Send_AT_Cmd ( cStr, "OK", NULL, 2000 );
        }else
                return false;
}

//删除对象,参数:对象ID
bool EC616S_Logout(void)
{
    return(EC616S_Send_AT_Cmd("AT+MIPLCLOSE=0","OK", 0, 1000 ));
}

//发送注销请求
bool EC616S_Delete_Object(char ClientNum, char * objectID)
{
        char cStr ;
        sprintf ( cStr, "AT+MIPLDELOBJ=%c,%s", ClientNum, objectID);
    return EC616S_Send_AT_Cmd ( cStr, "OK", NULL, 500 );
}

//删除实例,AT+MIPLDELETE
bool EC616S_Delete_instance(int16_t ClientNum)
{
    char cStr ;
        sprintf ( cStr, "AT+MIPLDELETE=%d", ClientNum );
    return EC616S_Send_AT_Cmd ( cStr, "OK", NULL, 500 );
}

//上传数据到OneNET平台
bool EC616S_Notify(char * objectID, char * resourceID, int16_t valueLen, char * value)
{
    char cStr ;
        sprintf ( cStr, "AT+MIPLNOTIFY=0,%s,%s,0,%s,1,%d,\"%s\",0,0", msgID,objectID,resourceID,valueLen,value);
    return EC616S_Send_AT_Cmd ( cStr, "OK", NULL, 3000 );
}


static char *itoa( int value, char *string, int radix )
{
    int   i, d;
    int   flag = 0;
    char    *ptr = string;

    /* This implementation only works for decimal numbers. */
    if (radix != 10)
    {
      *ptr = 0;
      return string;
    }

    if (!value)
    {
      *ptr++ = 0x30;
      *ptr = 0;
      return string;
    }

    /* if this is a negative value insert the minus sign. */
    if (value &lt; 0)
    {
      *ptr++ = '-';

      /* Make the value positive. */
      value *= -1;

    }

    for (i = 10000; i &gt; 0; i /= 10)
    {
      d = value / i;

      if (d || flag)
      {
            *ptr++ = (char)(d + 0x30);
            value -= (d * i);
            flag = 1;
      }
    }

    /* Null terminate the string. */
    *ptr = 0;

    return string;

} /* NCL_Itoa */


void USART_printf ( USART_TypeDef * USARTx, char * Data, ... )
{
    const char *s;
    int d;   
    char buf;


    va_list ap;
    va_start(ap, Data);

    while ( * Data != 0 )   // 判断数据是否到达结束符
    {                                       
      if ( * Data == 0x5c )//'\'
      {                                    
            switch ( *++Data )
            {
                case 'r':                                     //回车符
                USART_SendData(USARTx, 0x0d);
                Data ++;
                break;

                case 'n':                                     //换行符
                USART_SendData(USARTx, 0x0a);   
                Data ++;
                break;

                default:
                Data ++;
                break;
            }            
      }

      else if ( * Data == '%')
      {                                    
            switch ( *++Data )
            {               
                case 's':                                       //字符串
                s = va_arg(ap, const char *);
                for ( ; *s; s++)
                {
                  USART_SendData(USARTx,*s);
                  while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
                }
                Data++;
                break;

                case 'd':         
                  //十进制
                d = va_arg(ap, int);
                itoa(d, buf, 10);
                for (s = buf; *s; s++)
                {
                  USART_SendData(USARTx,*s);
                  while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
                }
                     Data++;
                     break;
                default:
                     Data++;
                     break;
            }      
      }
      else USART_SendData(USARTx, *Data++);
      while ( USART_GetFlagStatus ( USARTx, USART_FLAG_TXE ) == RESET );

    }
}
</code></pre>

<p>mqtt.c</p>

<pre>
<code>#include "mqtt.h"
#include "EC616S.h"
#include "delay.h"


/*
*以下参数需要用户自行修改才能测试用过
*/

#define pub_topic "temp/1"
#define sub_topic "temp/+"
RF_Switch RFMode = RF_Full_Func;
Attach_Net_Mode NetMode = Register_status;





void EC616S_lugl_MQTTClient_Test(char * buff)
{

        EC616S_MQTT_Pub (pub_topic,buff);                //发布消息到MQTT服务器
}


void EC616S_lugl_MQTTClient_connect(void)
{
        bool stepFlag = 0;
        printf("正在配置EC616S参数\r\n");
        EC616S_AT_Test();                                //AT指令测试
        printf("正在关闭飞行模式\r\n");
        stepFlag = EC616S_RF_Mode_Choose(RFMode);        //关闭飞行模式
        printf("附着网络\r\n");
        stepFlag = EC616S_Net_Attached_Mode_Choose(NetMode, stepFlag);        //附着网络
        printf("正在连接MQTT服务器\r\n");
        stepFlag = EC616S_Open_lugl_Client_Link(1);                //打开TCP客户端
        printf("正在认证用户名\r\n");
        stepFlag = EC616S_Link_lugl_Server(1);                                //连接服务器

}</code></pre>

<p><span style="font-size:20px;">主要的代码就是在这里了,串口配置、中断收发大家去用原子开板的就行了,这里考虑到版权,就不上了,如果需要的话可以私信我。</span></p>

<p>main.c</p>

<pre>
<code> int main(void)
{               
        u16 t;
        u16 len;       
       char cData;
        u16 times=0;
        delay_init();                 //延时函数初始化          
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        uart_init(115200);       //串口初始化为115200
        EC616S_Init(9600);        //command serial
        LED_Init();                             //LED端口初始化
        //KEY_Init();          //初始化与按键连接的硬件接口
        EC616S_lugl_MQTTClient_connect();
        while(1)
        {
                if(USART_RX_STA&amp;0x8000)
                {                                          
                        len=USART_RX_STA&amp;0x3fff;//得到此次接收到的数据长度
                        printf("\r\n您发送的消息为:\r\n\r\n");
                        for(t=0;t&lt;len;t++)
                        {
                                USART_SendData(USART1, USART_RX_BUF);//向串口1发送数据
                                while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
                               
                        }
                        sprintf(cData,USART_RX_BUF,4);
                        printf("\r\n\r\n");//插入换行
                        USART_RX_STA=0;
                        EC616S_lugl_MQTTClient_Test(cData);
                }else
                {
                        times++;
                        if(times%5000==0)
                        {
                               
                                EC616S_lugl_MQTTClient_connect();
                        }
                        if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
                        delay_ms(10);   
                }
        }       
}</code></pre>

<p><strong><span style="font-size:20px;">用串口助手发送数到单片机,单片机上传给服务器,并成功收到。效果为:</span></strong></p>

<p> &nbsp;</p>

<p>至此,STM32F103C8T6的测试基本上可以了,下一步,采集温度或者电压,用手机APP进行接收并展示。&nbsp;</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

Jacktang 发表于 2021-12-19 09:15

<p>上传给服务器,并成功收到,结果应该是成功的</p>

<p>说明修改的很成功,</p>

<p>mark</p>

freebsder 发表于 2021-12-20 17:41

<p>MQTT是模块自己带了支持吗?</p>

lugl4313820 发表于 2021-12-20 20:49

freebsder 发表于 2021-12-20 17:41
MQTT是模块自己带了支持吗?

<p>带了的,就三步就可以实现了!</p>
页: [1]
查看完整版本: 【安信可NB-IoT开发板EC-01F-Kit测评】STM32F103C8T6 连接MQTT发布数据