文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

STM32F103C8T6+ESP-01S+MQTT服务器实现数据上传和接收(一)

2023-09-17 10:31

关注

STM32F103C8T6+ESP-01S+MQTT服务器实现数据的上传和接收(一)


文章目录

STM32F103C8T6+ESP-01S+MQTT服务器实现数据的上传和接收(二)

前言

ESP-01S固件烧录

ESP-01S推荐使用安信可官网1471号固件,烧录配置如下图。

在这里插入图片描述

主要AT指令

请替换其中<>里面的内容

AT+CWMODE=1#设置模组进入STA模式AT+CWJAP="",""#连接wifiAT+MQTTUSERCFG=0,1,"","<账号>","<密码>",0,0,""#设置MQTT连接所需要的的参数,包括用户ID(不为空)、账号(admin)以及密码(public)AT+MQTTCONN=0,"<服务器地址>",<端口号>,<是否重连标志>#连接mqtt服务器,设置服务器地址,端口号和是否重连标志(0或1)AT+MQTTPUB=0,"","",,#发布一条topicAT+MQTTSUB=0,"",#订阅一条topic

手写简单的库函数

常量定义

enum ON_OFF{OFF,ON};enum Qos{MAX_ONE,MIN_ONE,ONLY_ONE};enum BackFlag{UNKNOW,SUCC,FAULT};enum ESP_MODE{STA=1,AP,AP_STA};enum ATBACK_KEYWORDS{NO,WIFI_GOT,};#define ERROR "\r\nERROR\r\n"#define OK "\r\nOK\r\n"#define FAIL "\r\nFAIL\r\n"#define WIFI_GOT_IP "WIFI GOT IP\r\n"#define WIFI_CONNECTED "WIFI CONNECTED\r\n"

全局变量声明

enum BackFlag back_flag=UNKNOW;         //串口发送AT指令反馈标志  UNKNOW:未发送AT指令或者还未反馈、SUCC:8266反馈OK、FAULT:8266反馈ERRORchar USART_ReceiveString[300];         //串口接收到的数据enum ATBACK_KEYWORDS ATBack_KeyWords;  //用于判断WIFI连接状态

串口初始化

使用PA9、PA10分别连接ESP8266的RXD、TXD引脚。

void usart_init(uint32_t bound)//115200{        GPIO_InitTypeDef GPIO_InitStructure;        USART_InitTypeDef USART_InitStructure;        NVIC_InitTypeDef NVIC_InitStructure;        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);        //USART1_TX   PA.9        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        GPIO_Init(GPIOA, &GPIO_InitStructure);        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        GPIO_Init(GPIOA, &GPIO_InitStructure);               NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        NVIC_Init(&NVIC_InitStructure);           USART_InitStructure.USART_BaudRate = bound;        USART_InitStructure.USART_WordLength = USART_WordLength_8b;        USART_InitStructure.USART_StopBits = USART_StopBits_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(USART1, &USART_InitStructure);        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);        USART_Cmd(USART1, ENABLE);                   }

关闭AT指令回显

由于每次发送的AT指令都会被8266通过串口再发送回来,为了缓解串口的压力,并且更好的检测到8266反馈的OK或者ERROR,建议关掉AT指令回显,不关掉理论上对库函数的调用不造成影响,没有进行测试,只作理论上说明。(为保证初始化8266正确进行,发送AT指令前后需要使用clearBackFlag()清除8266的反馈标志位,后续代码同理)

void AT_Init(){clearBackFlag();    printf("ATE0\r\n");while(back_flag!=SUCC){if(back_flag==FAULT){printf("ATE0\r\n");}}clearBackFlag();}

设置esp8266的工作模式

设置为STA模式,8266作为设备连接其他AP热点或WIFI。

void Esp_Mode(enum ESP_MODE mode){clearBackFlag();printf("AT+CWMODE=%d\r\n",mode);//sta   modewhile(back_flag!=SUCC){if(back_flag==FAULT){printf("AT+CWMODE=%d\r\n",mode);}}clearBackFlag();}

死板方式配网(不推荐)

系统上电后会等待5s,如果已经连上wifi就不需要进行配网,否则使用固定的wifi密码连接固定的wifi

void WIFI_Connect(char ssid[],char wifi_password[]){delay_s(5);if(ATBack_KeyWords!=WIFI_GOT){Esp_Mode(STA);clearBackFlag();printf("AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,wifi_password);while(back_flag!=SUCC){if(back_flag==FAULT){printf("AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,wifi_password);}}clearBackFlag();}else{clearATBackKeyWords();}}

智能配网(推荐方式)

通过使用WIFI_Connect_Wechat()调用前面三个函数进行智能配网。
系统上电后会等待5s,如果连上了wifi就不需要进行配网,否则开始进行智能配网,当stm32f103c8t6板载led亮起后,开始进入最长1分钟的智能配网时间,配网成功后可提前结束,led熄灭表示配网结束。

void SmartConfig_ON(){//开始智能配网clearBackFlag();printf("AT+CWSTARTSMART=3\r\n");while(back_flag!=SUCC){if(back_flag==FAULT){printf("AT+CWSTARTSMART=3\r\n");}}clearBackFlag();}uint16_t SmartConfig(){//微信配网过程中  最长持续60suint16_t wifi_delay_i=0;while(ATBack_KeyWords!=WIFI_GOT&&wifi_delay_i<20){delay_s(3);wifi_delay_i+=1;}return wifi_delay_i<10;}void SmartConfig_OFF(){//停止微信配网clearBackFlag();printf("AT+CWSTOPSMART\r\n");while(back_flag!=SUCC){if(back_flag==FAULT){printf("AT+CWSTOPSMART\r\n");}}clearBackFlag();}void WIFI_Connect_Wechat(){delay_s(5);if(ATBack_KeyWords!=WIFI_GOT){//如果没有自动连上wifiEsp_Mode(STA);SmartConfig_ON();led_on();SmartConfig();led_off();SmartConfig_OFF();}else{clearATBackKeyWords();}}

配置MQTT的client ID、用户名、密码

需要注意Client ID不能重复,建议配合时间戳设置Client ID。

void Mqtt_UserCFG(char *client_id,char *username,char *password){clearBackFlag();printf("AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",client_id,username,password);while(back_flag!=SUCC){if(back_flag==FAULT){            printf("AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",client_id,username,password);}}clearBackFlag();}

连接MQTT服务器

通过ip、端口号连接MQTT服务器。

void Mqtt_Connect(char *ip,char* port,enum ON_OFF reconnect){clearBackFlag();printf("AT+MQTTCONN=0,\"%s\",%s,%d\r\n",ip,port,reconnect);while(back_flag!=SUCC){if(back_flag==FAULT){printf("AT+MQTTCONN=0,\"%s\",%s,%d\r\n",ip,port,reconnect);}}clearBackFlag();}

订阅主题

void Mqtt_SubTopic(char *Topic_Name,enum Qos qos){clearBackFlag();printf("AT+MQTTSUB=0,\"%s\",%d\r\n",Topic_Name,qos);while(back_flag!=SUCC){if(back_flag==FAULT){printf("AT+MQTTSUB=0,\"%s\",%d\r\n",Topic_Name,qos);}}clearBackFlag();}

发布主题

两种用于发布主题的函数,区别是第一种带有8266的反馈判断,如果反馈ERROR会继续发送;第二种没有反馈判断。

void Mqtt_PubTopic(char *Topic_Name,char* data,enum Qos qos,enum ON_OFF retain){clearBackFlag();printf("AT+MQTTPUB=0,\"%s\",\"%s\",%d,%d\r\n",Topic_Name,data,qos,retain);while(back_flag!=SUCC){if(back_flag==FAULT){printf("AT+MQTTPUB=0,\"%s\",\"%s\",%d,%d\r\n",Topic_Name,data,qos,retain);}}clearBackFlag();}void Mqtt_PubTopic_UsartIT(char *Topic_Name,char* data,enum Qos qos,enum ON_OFF retain){printf("AT+MQTTPUB=0,\"%s\",\"%s\",%d,%d\r\n",Topic_Name,data,qos,retain);}

AT指令执行反馈检测

用于检测AT指令执行后返回结果。

uint16_t checkOK(char* res_txt,char*match_txt){uint16_t res_len,mat_len,flag=1;res_len=strlen(res_txt);mat_len=strlen(match_txt);for(int i=res_len-mat_len,j=0;i<res_len&&j<mat_len;i++,j++){if(res_txt[i]!=match_txt[j]){flag=0;break;}}return flag;}

判断是否是MQTT订阅的话题消息

当串口接收到数据后,可用当前函数来检测是否是mqtt消息。可对串口数据进行分类处理。

uint16_t info_type(char USART_ReceiveString[]){//1为mqtt消息  0为普通消息uint16_t i,flag=1;char head[13]="+MQTTSUBRECV";   //12+1   +MQTTSUBRECV+'\0'for(i=0;USART_ReceiveString[i]!='\0'&&i<12;i++){if(USART_ReceiveString[i]!=head[i]){flag=0;break;}}return flag;}

清除标志位

主要用于发送AT指令前后,辅助其他函数。

void clearBackFlag(){back_flag=UNKNOW;}void clearATBackKeyWords(){ATBack_KeyWords=NO;}

MQTT初始化

该函数整合了MQTT初始化函数。订阅test/stm32_server主题的消息,最后会发布一条test/stm32_client话题,内容为{“type”:“init”,“msg”:“success”},表示初始化完成。

void mqtt_init(char *ip,char* port,char *username,char *password,char *client_id){delay_s(1);AT_Init();WIFI_Connect_Wechat();Mqtt_UserCFG(client_id,username,password);Mqtt_Connect(ip,port,ON);Mqtt_SubTopic("test/stm32_server",MAX_ONE);Mqtt_PubTopic("test/stm32_client","{\\\"type\\\":\\\"init\\\"\\,\\\"msg\\\":\\\"success\\\"}",ONLY_ONE,OFF);}

来源地址:https://blog.csdn.net/weixin_46144773/article/details/128793578

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-服务器
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯