当前位置:   article > 正文

stm32F407+ESP8266+AT指令+阿里云+代码进阶版(4)_stm32f407 esp8266

stm32f407 esp8266

(1)esp8266.c

  1. #include "esp8266.h"
  2. char *wifi="317";
  3. char *wifiPasswd="88888888";
  4. //返回值:0,发送成功;1,发送失败
  5. u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
  6. {
  7. u8 res=0;
  8. USART3_RX_STA=0;
  9. u3_printf("%s\r\n",cmd); //发送命令
  10. if(ack&&waittime) //需要等待应答
  11. {
  12. while(--waittime) //等待倒计时
  13. {
  14. delay_ms(10);
  15. if(USART3_RX_STA&0X8000)//接收到期待的应答结果
  16. {
  17. if(esp8266_check_cmd(ack))
  18. {
  19. printf("sendcmd_OK\r\n");
  20. break;//得到有效数据
  21. }
  22. USART3_RX_STA=0;
  23. }
  24. }
  25. if(waittime==0)
  26. {
  27. res=1;
  28. printf("sendcmd_ERR\r\n");
  29. }
  30. }
  31. return res;
  32. }
  33. u8* esp8266_check_cmd(u8 *str)
  34. {
  35. char *strx=0;
  36. if(USART3_RX_STA&0X8000) //接收到一次数据了
  37. {
  38. USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
  39. strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
  40. }
  41. return (u8*)strx;
  42. }
  43. //连接wifi
  44. void esp8266_init(char *url)
  45. {
  46. char tempBuf[100]={0};
  47. esp8266_send_cmd("AT+RST","ready",100);//让Wifi模块重启的命令
  48. delay_ms(1000); //延时3S等待重启成功
  49. delay_ms(1000);
  50. delay_ms(1000);
  51. //设置工作模式 1:station模式 2:AP模式 3:兼容 AP+station模式
  52. esp8266_send_cmd("AT+CWMODE=1","OK",100);
  53. esp8266_send_cmd("AT+CWAUTOCONN=0","OK",100);
  54. sprintf(tempBuf,"AT+CWJAP=\"%s\",\"%s\"",wifi,wifiPasswd);
  55. while(esp8266_send_cmd(tempBuf,"WIFI GOT IP",600));
  56. esp8266_send_cmd("AT+CIPMODE=1","OK",20);
  57. esp8266_send_cmd("AT+CIPMUX=0","OK",20);
  58. sprintf(tempBuf,"AT+CIPSTART=\"TCP\",\"%s\",1883,1",url);
  59. while(esp8266_send_cmd(tempBuf,"CONNECT",1000));
  60. esp8266_send_cmd("AT+CIPMODE=1","OK",200);//是否开启透传模式 0:表示关闭 1:表示开启透传
  61. esp8266_send_cmd("AT+CIPSEND","OK",50);//透传模式下 开始发送数据的指令 这个指令之后就可以直接发数据了
  62. }

(2)esp8266.h

  1. #ifndef __ESP8266_H
  2. #define __ESP8266_H
  3. #include "string.h"
  4. #include "stdio.h"
  5. #include "stdlib.h"
  6. #include "usart3.h"
  7. #include "stm32f4xx_conf.h"
  8. #include "delay.h"
  9. extern char *wifi;
  10. extern char *wifiPasswd;
  11. u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime);
  12. u8* esp8266_check_cmd(u8 *str);
  13. void esp8266_init(char *url);
  14. #endif

(3)aliyun_mqtt.c

  1. #include "aliyun_mqtt.h"
  2. u8 *mqtt_rxbuf;
  3. u8 *mqtt_txbuf;
  4. u16 mqtt_rxlen;
  5. u16 mqtt_txlen;
  6. u8 _mqtt_txbuf[256];//发送数据缓存区
  7. u8 _mqtt_rxbuf[256];//接收数据缓存区
  8. const u8 parket_connetAck[] = {0x20,0x02,0x00,0x00};
  9. const u8 parket_disconnet[] = {0xe0,0x00};
  10. const u8 parket_heart[] = {0xc0,0x00};
  11. const u8 parket_heart_reply[] = {0xc0,0x00};
  12. const u8 parket_subAck[] = {0x90,0x03};
  13. void MQTT_Init(void)
  14. {
  15. mqtt_rxbuf = _mqtt_rxbuf;
  16. mqtt_rxlen = sizeof(_mqtt_rxbuf);
  17. mqtt_txbuf = _mqtt_txbuf;
  18. mqtt_txlen = sizeof(_mqtt_txbuf);
  19. memset(mqtt_rxbuf,0,mqtt_rxlen);
  20. memset(mqtt_txbuf,0,mqtt_txlen);
  21. memset(USART3_RX_BUF,0,sizeof(USART3_RX_BUF));
  22. USART3_RX_STA=0;
  23. MQTT_Disconnect();
  24. delay_ms(100);
  25. MQTT_Disconnect();
  26. delay_ms(100);
  27. }
  28. u8 MQTT_Connect(char *ClientID,char *Username,char *Password)
  29. {
  30. u8 i,j;
  31. int ClientIDLen = strlen(ClientID);
  32. int UsernameLen = strlen(Username);
  33. int PasswordLen = strlen(Password);
  34. int DataLen;
  35. mqtt_txlen=0;
  36. memset(mqtt_txbuf,0,mqtt_txlen);
  37. DataLen = 10 + (ClientIDLen+2) + (UsernameLen+2) + (PasswordLen+2);
  38. mqtt_txbuf[mqtt_txlen++] = 0x10;
  39. do
  40. {
  41. u8 encodedByte = DataLen % 128;
  42. DataLen = DataLen / 128;
  43. if ( DataLen > 0 )
  44. encodedByte = encodedByte | 128;
  45. mqtt_txbuf[mqtt_txlen++] = encodedByte;
  46. }while ( DataLen > 0 );
  47. mqtt_txbuf[mqtt_txlen++] = 0; // Protocol Name Length MSB
  48. mqtt_txbuf[mqtt_txlen++] = 4; // Protocol Name Length LSB
  49. mqtt_txbuf[mqtt_txlen++] = 'M'; // ASCII Code for M
  50. mqtt_txbuf[mqtt_txlen++] = 'Q'; // ASCII Code for Q
  51. mqtt_txbuf[mqtt_txlen++] = 'T'; // ASCII Code for T
  52. mqtt_txbuf[mqtt_txlen++] = 'T'; // ASCII Code for T
  53. mqtt_txbuf[mqtt_txlen++] = 4; // MQTT Protocol version = 4
  54. mqtt_txbuf[mqtt_txlen++] = 0xc2; // conn flags
  55. mqtt_txbuf[mqtt_txlen++] = 0; // Keep-alive Time Length MSB
  56. mqtt_txbuf[mqtt_txlen++] = 100; // Keep-alive Time Length LSB 100S心跳包
  57. mqtt_txbuf[mqtt_txlen++] = BYTE1(ClientIDLen);// Client ID length MSB
  58. mqtt_txbuf[mqtt_txlen++] = BYTE0(ClientIDLen);// Client ID length LSB
  59. memcpy(&mqtt_txbuf[mqtt_txlen],ClientID,ClientIDLen);
  60. mqtt_txlen += ClientIDLen;
  61. if(UsernameLen > 0)
  62. {
  63. mqtt_txbuf[mqtt_txlen++] = BYTE1(UsernameLen); //username length MSB
  64. mqtt_txbuf[mqtt_txlen++] = BYTE0(UsernameLen); //username length LSB
  65. memcpy(&mqtt_txbuf[mqtt_txlen],Username,UsernameLen);
  66. mqtt_txlen += UsernameLen;
  67. }
  68. if(PasswordLen > 0)
  69. {
  70. mqtt_txbuf[mqtt_txlen++] = BYTE1(PasswordLen); //password length MSB
  71. mqtt_txbuf[mqtt_txlen++] = BYTE0(PasswordLen); //password length LSB
  72. memcpy(&mqtt_txbuf[mqtt_txlen],Password,PasswordLen);
  73. mqtt_txlen += PasswordLen;
  74. }
  75. for(i=0;i<10;i++)
  76. {
  77. memset(mqtt_rxbuf,0,mqtt_rxlen);
  78. MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);
  79. for(j=0;j<10;j++)
  80. {
  81. delay_ms(50);
  82. if(USART3_RX_STA&0x8000)
  83. {
  84. USART3_RX_BUF[USART3_RX_STA&0X7FFF]='\0';
  85. sprintf((char *)mqtt_rxbuf,"%s",USART3_RX_BUF);
  86. USART3_RX_STA=0;
  87. memset(USART3_RX_BUF,0,sizeof(USART3_RX_BUF));
  88. }
  89. if(mqtt_rxbuf[0]==parket_connetAck[0] && mqtt_rxbuf[1]==parket_connetAck[1]) //连接成功
  90. {
  91. return 0;//连接成功
  92. }
  93. }
  94. }
  95. return 1;
  96. }
  97. /*
  98. 函数功能: MQTT订阅/取消订阅数据打包函数
  99. 函数参数:
  100. topic 主题
  101. qos 消息等级 0:最多分发一次 1: 至少分发一次 2: 仅分发一次
  102. whether 订阅/取消订阅请求包 (1表示订阅,0表示取消订阅)
  103. 返回值: 0表示成功 1表示失败
  104. */
  105. u8 MQTT_SubscribeTopic(char *topic,u8 qos,u8 whether)
  106. {
  107. u8 i,j;
  108. int topiclen = strlen(topic);
  109. int DataLen = 2 + (topiclen+2) + (whether?1:0);//可变报头的长度(2字节)加上有效载荷的长度
  110. //固定报头
  111. //控制报文类型
  112. mqtt_txlen=0;
  113. if(whether)mqtt_txbuf[mqtt_txlen++] = 0x82; //消息类型和标志订阅
  114. else mqtt_txbuf[mqtt_txlen++] = 0xA2; //取消订阅
  115. //剩余长度
  116. do
  117. {
  118. u8 encodedByte = DataLen % 128;
  119. DataLen = DataLen / 128;
  120. // if there are more data to encode, set the top bit of this byte
  121. if ( DataLen > 0 )
  122. encodedByte = encodedByte | 128;
  123. mqtt_txbuf[mqtt_txlen++] = encodedByte;
  124. }while ( DataLen > 0 );
  125. //可变报头
  126. mqtt_txbuf[mqtt_txlen++] = 0; //消息标识符 MSB
  127. mqtt_txbuf[mqtt_txlen++] = 0x01; //消息标识符 LSB
  128. //有效载荷
  129. mqtt_txbuf[mqtt_txlen++] = BYTE1(topiclen);//主题长度 MSB
  130. mqtt_txbuf[mqtt_txlen++] = BYTE0(topiclen);//主题长度 LSB
  131. memcpy(&mqtt_txbuf[mqtt_txlen],topic,topiclen);
  132. mqtt_txlen += topiclen;
  133. if(whether)
  134. {
  135. mqtt_txbuf[mqtt_txlen++] = qos;//QoS级别
  136. }
  137. for(i=0;i<10;i++)
  138. {
  139. memset(mqtt_rxbuf,0,mqtt_rxlen);
  140. MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);
  141. for(j=0;j<10;j++)
  142. {
  143. delay_ms(50);
  144. if((USART3_RX_STA&(1<<15))==1)
  145. {
  146. USART3_RX_BUF[USART3_RX_STA&0X7FFF]='\0';
  147. sprintf((char *)mqtt_rxbuf,"%s",USART3_RX_BUF);
  148. USART3_RX_STA=0;
  149. }
  150. if(mqtt_rxbuf[0]==parket_subAck[0] && mqtt_rxbuf[1]==parket_subAck[1]) //订阅成功
  151. {
  152. return 0;//订阅成功
  153. }
  154. }
  155. }
  156. return 1; //失败
  157. }
  158. //MQTT发布数据打包函数
  159. //topic 主题
  160. //message 消息
  161. //qos 消息等级
  162. u8 MQTT_PublishData(char *topic, char *message, u8 qos)
  163. {
  164. int topicLength = strlen(topic);
  165. int messageLength = strlen(message);
  166. static u16 id=0;
  167. int DataLen;
  168. mqtt_txlen=0;
  169. //有效载荷的长度这样计算:用固定报头中的剩余长度字段的值减去可变报头的长度
  170. //QOS为0时没有标识符
  171. //数据长度 主题名 报文标识符 有效载荷
  172. if(qos) DataLen = (2+topicLength) + 2 + messageLength;
  173. else DataLen = (2+topicLength) + messageLength;
  174. //固定报头
  175. //控制报文类型
  176. mqtt_txbuf[mqtt_txlen++] = 0x30; // MQTT Message Type PUBLISH
  177. //剩余长度
  178. do
  179. {
  180. u8 encodedByte = DataLen % 128;
  181. DataLen = DataLen / 128;
  182. // if there are more data to encode, set the top bit of this byte
  183. if ( DataLen > 0 )
  184. encodedByte = encodedByte | 128;
  185. mqtt_txbuf[mqtt_txlen++] = encodedByte;
  186. }while ( DataLen > 0 );
  187. mqtt_txbuf[mqtt_txlen++] = BYTE1(topicLength);//主题长度MSB
  188. mqtt_txbuf[mqtt_txlen++] = BYTE0(topicLength);//主题长度LSB
  189. memcpy(&mqtt_txbuf[mqtt_txlen],topic,topicLength);//拷贝主题
  190. mqtt_txlen += topicLength;
  191. //报文标识符
  192. if(qos)
  193. {
  194. mqtt_txbuf[mqtt_txlen++] = BYTE1(id);
  195. mqtt_txbuf[mqtt_txlen++] = BYTE0(id);
  196. id++;
  197. }
  198. memcpy(&mqtt_txbuf[mqtt_txlen],message,messageLength);
  199. mqtt_txlen += messageLength;
  200. MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);
  201. return mqtt_txlen;
  202. }
  203. void MQTT_SentHeart(void)
  204. {
  205. MQTT_SendBuf((u8 *)parket_heart,sizeof(parket_heart));
  206. }
  207. void MQTT_Disconnect(void)
  208. {
  209. MQTT_SendBuf((u8 *)parket_disconnet,sizeof(parket_disconnet));
  210. }
  211. void MQTT_SendByte(u8 val)
  212. {
  213. USART_SendData(USART3, val);
  214. while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); //等待发送完成
  215. }
  216. void MQTT_SendBuf(u8 *buf,u16 len)
  217. {
  218. while(len--) MQTT_SendByte(*buf++);
  219. }

(4)aliyun_mqtt.h

  1. #ifndef __ALIYUN_MQTT_H_
  2. #define __ALIYUN_MQTT_H_
  3. #include "string.h"
  4. #include "stdio.h"
  5. #include "stdlib.h"
  6. #include "stm32f4xx_conf.h"
  7. #include "usart3.h"
  8. #include "delay.h"
  9. #define BYTE0(dwTemp) (*( char *)(&dwTemp))
  10. #define BYTE1(dwTemp) (*((char *)(&dwTemp) + 1))
  11. #define BYTE2(dwTemp) (*((char *)(&dwTemp) + 2))
  12. #define BYTE3(dwTemp) (*((char *)(&dwTemp) + 3))
  13. //阿里云用户名初始化
  14. void Aliyun_LoginInit(char *ProductKey,char *DeviceName,char *DeviceSecret);
  15. //MQTT协议相关函数声明
  16. u8 MQTT_PublishData(char *topic, char *message, u8 qos);
  17. u8 MQTT_SubscribeTopic(char *topic,u8 qos,u8 whether);
  18. void MQTT_Init(void);
  19. u8 MQTT_Connect(char *ClientID,char *Username,char *Password);
  20. void MQTT_SentHeart(void);
  21. void MQTT_Disconnect(void);
  22. void MQTT_SendBuf(u8 *buf,u16 len);
  23. #endif

(5)main.h

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "beep.h"
  6. #include "key.h"
  7. #include "esp8266.h"
  8. char *clientId = "k0wih08FdYq.ESP8266|securemode=2,signmethod=hmacsha256,timestamp=1710944829520|";
  9. char *username = "ESP8266&k0wih08FdYq";
  10. char *passwd = "7d293f515f969ddb5631f85eed895d823d32c6e9f865b0762957b519ab5b8c26";
  11. char *mqttHostUrl = "iot-06z00jb2hfkrh6y.mqtt.iothub.aliyuncs.com";
  12. int main(void)
  13. {
  14. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
  15. delay_init(168); //延时初始化
  16. uart_init(115200); //串口初始化波特率为115200
  17. LED_Init(); //初始化与LED连接的硬件接口
  18. usart3_init(115200);
  19. esp8266_init(mqttHostUrl);
  20. printf("esp8266初始化成功\r\n");
  21. MQTT_Init();
  22. if(MQTT_Connect(clientId,username,passwd))
  23. {
  24. printf("阿里云连接失败\r\n");
  25. }
  26. else
  27. {
  28. printf("阿里云连接成功\r\n");
  29. }
  30. while(1){}
  31. }

(6)完整工程代码

链接:https://pan.baidu.com/s/1LoOh5QivNyKUwPd3Mje0IA
提取码:生日

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/646657
推荐阅读
相关标签
  

闽ICP备14008679号