当前位置:   article > 正文

最新!基于stm32+esp8266+mqtt连接最新版onenet云平台(非旧版本多协议接入)HAL库开发版本 文末附代码_新版onenet stm32 hal库

新版onenet stm32 hal库

写在前面:

因为最近帮一个朋友完成他的项目,就有了这样一个支线项目,主线项目基于stm32的HAL库开发学习以后有时间一定会继续更新,考虑到广大大学牲完成这样一个新版本无完整开发过程,资料的情况下,我就给大家仔细介绍一下我的开发历程,希望对大家的学习生涯有所帮助,也欢迎各位大佬批评指正!!!文末贴上本次项目的完整例程。

UP几乎踩完了所有的坑,最后终于可以连上onenet,先贴上效果图

分别是连接上服务器,以及stm32采集的数据传到了onenet云平台上 

一:硬件选择

本次使用单片机是stm32f103c8t6 选用是最小系统板,其中使用usart1与esp8266通信,而usart3将esp8266返回的数据打印出来,我们便可以通过pc的串口助手观潮我们发送的信息以及收到回复的信息是否正确。

而esp8266本次选择的是esp01-s,最好的优点就是便宜好用。

但是在使用前,需要注意的是,由于本次使用的mqtt协议连接上云,而esp01s刚出场时自带的固件是不支持mqtt协议,所以就需要重新烧录固件,这里根据这篇文章做就可以了。

这里的esp01s我选择的是某宝上的这一家的,这一家客服耐心回答问题售后良好,硬件质量优秀,完全不用担心被坑,闭眼入就完了!(关键是确实便宜啊)。

ESP8266-01 MQTT固件烧录并连接阿里云服务器_烧录mqtt固件接线-CSDN博客

这样硬件部分就准备好了,但我这里还是建议大家用串口助手先发送at指令和esp8266通信试试,为了避免时硬件本身的问题导致后面的过程都通过不了。

二:stm32与esp8266通信至连接wifi部分

如上文所说,我们使用串口1和esp8266进行通信,下面将展示cubemx的配置

首先时RCC和SYS这个自不必说,主要看usart1的配置,

同时,我也开了DMA,DMA这里就不具体展开了,后面有机会的话再来介绍。

波特率设置为115200,同时打开NVIC串口中断开关,以及添加DMA通道。

同理,usart3的配置也是如此,唯一的区别就是并未开启DMA通道,因为usart3的唯一作用就只是在串口DMA中断函数里将接收到的数据打印出来。

下面开始贴代码。

  1. #include "UART_DMA.h"
  2. #include <string.h>
  3. #include <stdarg.h>
  4. #include <stdio.h>
  5. #include "NumAndStr.h"
  6. #include "stm32f1xx_hal.h"
  7. #include "usart.h"
  8. #include "oled.h"
  9. uint8_t RxBuffer[UART_RX_BUF_SIZE] = {0};
  10. uint8_t TxBuffer[UART_RX_BUF_SIZE] = {0};
  11. uint8_t sendCompleteSign = 1;
  12. uint8_t flag,flag_wifi,flag_mqtt,flag_reset;
  13. uint8_t TxLen = 0;
  14. int32_t a,b,c;
  15. double d,e,f;
  16. extern uint8_t uart3_RX_Buffer[r3_length];
  17. extern uint8_t UART3_temp[REC_LENGTH];
  18. extern unsigned int UART3_Rx_cnt ;
  19. void DataProcess(void)
  20. {
  21. //在这里加入数据处理的函数
  22. a = str2int(RxBuffer, ' ', 1);
  23. b = str2int(RxBuffer, ' ', 2);
  24. c = str2int(RxBuffer, ' ', 3);
  25. str2double(RxBuffer, ' ', 4, &d);
  26. str2double(RxBuffer, ' ', 5, &e);
  27. str2double(RxBuffer, ' ', 6, &f);
  28. }
  29. //到USARTx_IRQHandler中添加,如:
  30. //void USART1_IRQHandler(void)
  31. //{
  32. // /* USER CODE BEGIN USART1_IRQn 0 */
  33. // if(__HAL_UART_GET_FLAG(&USB_Huart,UART_FLAG_IDLE))
  34. // {
  35. // HAL_UART_IdleCallback(&USB_Huart);
  36. // }
  37. //
  38. // /* USER CODE END USART1_IRQn 0 */
  39. // HAL_UART_IRQHandler(&huartx);
  40. //}
  41. void HAL_UART_IdleCallback(UART_HandleTypeDef *huart)
  42. {
  43. __HAL_UART_CLEAR_IDLEFLAG(huart);
  44. {
  45. HAL_UART_DMAStop(huart);
  46. ProcessData();
  47. StartUartRxDMA();
  48. }
  49. }
  50. void ProcessData()
  51. {
  52. uint32_t len = 0;
  53. //得到已经接收了多少个字节 = 总共要接收的字节数 - >NDTR F1为CNDTR F4为NDTR
  54. #ifdef __STM32F1xx_HAL_H
  55. len = UART_RX_BUF_SIZE - USB_Huart.hdmarx->Instance->CNDTR;
  56. #define ProcessDataOK
  57. #endif
  58. #ifdef __STM32F4xx_HAL_H
  59. len = UART_RX_BUF_SIZE - USB_Huart.hdmarx->Instance->NDTR;
  60. #define ProcessDataOK
  61. #endif
  62. #ifndef ProcessDataOK
  63. 增加所用芯片的版本
  64. #endif
  65. if(len > 0)
  66. {
  67. if(sendCompleteSign == 1)
  68. {
  69. #if UART_RXTX_Switch
  70. memset((void *)TxBuffer, 0, sizeof(TxBuffer));//将TxBuffer数组全部赋值为0
  71. memcpy(TxBuffer, RxBuffer, len);//将RxBuffer的内容全部复制到TxBuffer
  72. TxLen = len;
  73. StartUartTxDMA(); //串口回显
  74. #endif
  75. {
  76. //在这里面加入数据处理的函数
  77. DataProcess();
  78. }
  79. }
  80. }
  81. }
  82. void USB_DMA_printf(const char *format,...)
  83. {
  84. uint32_t length;
  85. va_list args;
  86. va_start(args, format);
  87. length = vsnprintf((char*)TxBuffer, sizeof(TxBuffer)+1, (char*)format, args);
  88. va_end(args);
  89. HAL_UART_Transmit_DMA(&USB_Huart,TxBuffer,length);
  90. }
  91. void USB_printf(const char *format,...)
  92. {
  93. uint32_t length;
  94. va_list args;
  95. va_start(args, format);
  96. length = vsnprintf((char*)TxBuffer, sizeof(TxBuffer)+1, (char*)format, args);
  97. va_end(args);
  98. HAL_UART_Transmit(&USB_Huart,TxBuffer,length,0xFFFF);
  99. }
  100. /**
  101. * @brief Tx Transfer completed callbacks.
  102. * @param huart Pointer to a UART_HandleTypeDef structure that contains
  103. * the configuration information for the specified UART module.
  104. * @retval None
  105. */
  106. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
  107. {
  108. /* Prevent unused argument(s) compilation warning */
  109. // UNUSED(huart);
  110. if(huart == &USB_Huart)
  111. {
  112. sendCompleteSign = 1;
  113. }
  114. /* NOTE: This function should not be modified, when the callback is needed,
  115. the HAL_UART_TxCpltCallback could be implemented in the user file
  116. */
  117. }
  118. /**
  119. * @brief Rx Transfer completed callbacks.
  120. * @param huart Pointer to a UART_HandleTypeDef structure that contains
  121. * the configuration information for the specified UART module.
  122. * @retval None
  123. */
  124. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  125. {
  126. /* Prevent unused argument(s) compilation warning */
  127. // UNUSED(huart;);
  128. if(huart == &huart3)
  129. {
  130. uart3_RX_Buffer[UART3_Rx_cnt]=UART3_temp[0];
  131. UART3_Rx_cnt++;
  132. // USB_printf("%s",uart3_RX_Buffer);
  133. HAL_UART_Receive_IT(&huart3,(uint8_t *)UART3_temp,REC_LENGTH);
  134. }
  135. if(huart == &USB_Huart)
  136. {
  137. ProcessData();
  138. StartUartRxDMA();
  139. }
  140. /* NOTE: This function should not be modified, when the callback is needed,
  141. the HAL_UART_RxCpltCallback could be implemented in the user file
  142. */
  143. }
  144. uint8_t UartTxData(UART_HandleTypeDef *huart, uint8_t *buf, const uint32_t len)
  145. {
  146. HAL_StatusTypeDef status;
  147. uint8_t ret = 1;
  148. if(sendCompleteSign == 0 || len == 0)
  149. {
  150. return 0;
  151. }
  152. sendCompleteSign = 0;
  153. status = HAL_UART_Transmit_DMA(huart, (uint8_t*)buf, len);
  154. if(HAL_OK != status)
  155. {
  156. ret = 0;
  157. }
  158. return ret;
  159. }
  160. //启动DMA发送
  161. uint8_t StartUartTxDMA()
  162. {
  163. return UartTxData(&USB_Huart, TxBuffer, TxLen);
  164. }
  165. uint8_t UartRxData(UART_HandleTypeDef *huart, uint8_t *buf, const uint32_t len)
  166. {
  167. HAL_StatusTypeDef status;
  168. uint8_t ret = 1;
  169. status = HAL_UART_Receive_DMA(huart, (uint8_t*)buf, len);
  170. {
  171. if(strstr(buf,"OK")!=NULL)
  172. {
  173. flag=1;
  174. }
  175. if(strstr(buf,"WIFI GOT IP")!=NULL)
  176. flag_wifi=2;
  177. if(strstr(buf,"MQTTCONNECTED")!=NULL)
  178. flag_mqtt=1;
  179. if(strstr(buf,"MQTTDISCONNECTED")!=NULL)
  180. flag_reset=1;
  181. // if(strstr(buf,"CLOUD CONNECTED")!=NULL)
  182. // flag=3;
  183. //if(strstr(buf,"led1off")!=NULL)
  184. // LED1_OFF();
  185. //if(strstr(buf,"led1on")!=NULL)
  186. // LED1_ON();
  187. // OLED_ShowStr(0+8,5,buf,1);
  188. uart3_printf("%s",buf);
  189. // LCD_ShowString(10,10,500,12,12,buf);
  190. //
  191. //
  192. // if(buf[0]==0x31)
  193. // {
  194. // flag=1;
  195. // }
  196. //else if(buf[0]==0x32)
  197. // {
  198. // flag=2;
  199. // }
  200. //else if(buf[0]==0x33)
  201. // {
  202. // flag=3;
  203. // }
  204. //else if(buf[0]==0x34)
  205. // {
  206. // flag=4;
  207. // }
  208. // i++;
  209. }
  210. //pulseWide=buf[0]*10+buf[1];
  211. if(HAL_OK != status)
  212. {
  213. ret = 0;
  214. }
  215. else
  216. {
  217. /* 开启空闲接收中断 */
  218. __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);
  219. }
  220. return ret;
  221. }
  222. //启动DMA接收
  223. uint8_t StartUartRxDMA()
  224. {
  225. return UartRxData(&USB_Huart, RxBuffer, UART_RX_BUF_SIZE);
  226. }
  227. /*开始本次的代码解释 首先是USART1的全局中断进行改写,在ISR里添加了代码,对于串口中断的信号位进行判断
  228. 判断之后,就开始中断,,其实这个函数集其实也是层层利用的,在TX(由存储器到外设,发送)的中断回调函数里
  229. 设置串口中断标志位,然后是RX(外设到存储器,接收)函数的中断回调函数里接受DMA初始化
  230. 进而开启DMA接收,在DMA接收函数里返回接收到的数据,其中还有一个数据处理函数,里面将串口数据回显*/

如上代码是根据某一位佬的串口接收数据处理代码改了一下,使用的是DMA的空闲中断,所以需要在it.c里面将usart1_handler函数里面的内容改写一下。其中在UartRxdata里面出现的strtr函数就是比较esp8266返回的语句是否与我们预料的语句

例如

  1. if(strstr(buf,"OK")!=NULL)
  2. {
  3. flag=1;
  4. }

就是判断给esp8266发送AT的时候,是否能正确返回OK。

  1. #include "esp8266.h"
  2. extern uint8_t flag,flag_mqtt,flag_reset;
  3. extern uint8_t flag_wifi;
  4. uint8_t ssid[]={"xxx"};
  5. uint8_t psd[]={"xxxx"};
  6. uint8_t devicename[]={"test"};
  7. uint8_t productid[]={"xxxxxxxx"};
  8. uint8_t deviceid[]={"xxxx"};
  9. uint8_t subscribe[]={"$sys/xxxx/test/thing/property/post/reply"};
  10. uint8_t pubscribe[]={"$sys/xxxx/test/thing/property/post"};
  11. uint8_t fuc[]={"temperature"};
  12. //uint8_t data[]={"$sys/422b4zbv12/test/thing/property/post","{\"id\":\"123\"\,\"params\":{\"temperature\":{\"value\":30\}}}"};
  13. int flag_temp;
  14. extern int temp;
  15. void esp_reset()
  16. {
  17. int i=0;
  18. while(i<=6)
  19. {
  20. USB_printf("AT+RST\r\n");
  21. HAL_Delay(500);
  22. if(flag==1)
  23. {
  24. break;
  25. flag=0;
  26. }
  27. }
  28. }
  29. uint16_t esp_init(void)
  30. {
  31. int i=0;
  32. while(i<=6)
  33. { USB_printf("AT\r\n");
  34. HAL_Delay(500);
  35. i++;
  36. }
  37. if(flag==1)
  38. {
  39. //HAL_Delay(1000);
  40. return ESP8266_Result_OK;
  41. }
  42. else
  43. {
  44. return ESP8266_Result_Err;
  45. }
  46. }
  47. uint16_t esp_wifi_connect()
  48. {
  49. int i=0;
  50. while(1)
  51. {
  52. USB_printf("AT\r\n");
  53. HAL_Delay(500);
  54. if(flag==1)
  55. {
  56. break;
  57. flag=0;
  58. }
  59. }
  60. HAL_Delay(500);
  61. while(1)
  62. {
  63. USB_printf("AT+CWMODE=1\r\n");
  64. HAL_Delay(200);
  65. if(flag==1)
  66. break;
  67. else
  68. return ESP8266_Result_Err;
  69. }
  70. HAL_Delay(500);
  71. while(1)
  72. {
  73. USB_printf("AT+CWDHCP=1,1\r\n");
  74. HAL_Delay(200);
  75. if(flag==1)
  76. break;
  77. else
  78. return ESP8266_Result_Err;
  79. }
  80. while(1)
  81. {
  82. flag=0;
  83. USB_printf("AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,psd);
  84. HAL_Delay(200);
  85. if(flag_wifi==2)
  86. break;
  87. // else
  88. // return ESP8266_Result_Err;
  89. }
  90. }

如上,不像一般esp8266通信代码一样,会等待多长时间然后返回通过或者没有通过,我的逻辑很简单,就是while循环里一直esp8266发送消息,直到esp返回OK或者是“WIFI GOT IP”才break掉while循环结束发送的流程,就是一直暴力发送(手动狗头),可能函数写的不像一般开源的代码优美,但本人试过确实好用。

其中ssid是wifi名称,psd是wifi密码,上述代码在main函数里的while循环之前被执行。后面会继续讲所有的程序逻辑。待上述程序跑完后,不出意外的话这边你的串口就会给你提示WIFI GOT IP以及WIFI CONNECTED。

tips:这里有坑!!!你的WIFI一定得是2.4G网络,5G网络无法使用,这是因为esp8266的芯片设定,而且如果的esp8266返回了AT+CWJAP=3,这就代表你的wifi是5G的,这是你就需要更换的wifi了。

三:onenet云平台如何创建一个可以连接mqtt的界面

第一步:首先是创建一个onenet平台的账号,然后登录,登录之后,如图

在产品开发这里创建一个产品,然后

创建产品之后产品品类这里选择其他行业

产品名称自填,节点类型选择直连设备,接入协议选择mqtt,数据协议选择onejeson

开发方案选择标准方案,其他的东西都无所谓了就。

紧接着创建设备,当你创建好产品之后,就可以添加设备了,如图

右上角有一个添加设备,添加完设备,设备名最好写test(因为和下文中的token生成有关),点进详情就有如下界面。

记住产品ID和设备密钥,这是我们与平台交互需要的钥匙,

根据平台提供的文档:OneNET - 中国移动物联网开放平台 (10086.cn)

里面可以知道我们需要的指令形式

其中需要下一个token生成器

https://download5.mcloud.139.com/storageWeb/servlet/downloadServlet?code=TDAwMDExV2xBTXAxbTgyNzkxN3c4aTZTQXdJ&un=505808AAA2BC94B5F91FF8732C800E7A2EE72758AEF113513DCC9E0167B4B091&dom=D950&rate=0&txType=0

第一行最后一个/后是你的设备名,第一个/后是你的设备ID,ret是时间戳,key是设备密钥,点击generate,然后就会生成一串密钥。记住他,我们后面会用到

AT+MQTTUSERCFG=0,1,"test","422b4zbv12","version=2018-10-31&res=products%2F422b4zbv12%2Fdevices%2Ftest&et=2052911776&method=md5&sign=kSKpEHBa9KKDg%2FtfYQLKFQ%3D%3D",0,0,""

第二个引号里的内容是设备id,后面一长串则是刚刚生成的密钥。

AT+MQTTCONN=0,"mqtts.heclouds.com",1883,1

这一段代码直接无脑输入,是连接mqtt服务器的地址和端口。

AT+MQTTSUB=0,"$sys/422b4zbv12/test/thing/property/post/reply",1

这个是订阅mqtt服务器的消息,以上消息若成功发送,则会返回OK。这里建议大家用电脑串口助手测试一下。然后继续进行下一步的stm32代码编写。

四:通过串口给esp8266发送信息与onenet通信。

  1. void esp_mqtt_connect()
  2. {
  3. int i=0;
  4. flag=0;
  5. // if(flag_wifi==2)
  6. {
  7. while(1)
  8. {
  9. USB_printf("AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",devicename,productid,deviceid);
  10. HAL_Delay(200);
  11. if(flag==1)
  12. break;
  13. i++;
  14. }
  15. flag=0;
  16. HAL_Delay(200);
  17. while(1)
  18. {
  19. USB_printf("AT+MQTTCONN=0,\"mqtts.heclouds.com\",1883,1\r\n");
  20. HAL_Delay(200);
  21. if(flag==1)
  22. break;
  23. }
  24. flag=0;
  25. HAL_Delay(200);
  26. while(1)
  27. {
  28. i++;
  29. USB_printf("AT+MQTTSUB=0,\"%s\",1\r\n",subscribe);
  30. HAL_Delay(200);
  31. if(flag==1)
  32. {
  33. break;
  34. }
  35. }
  36. flag_temp=1;
  37. HAL_Delay(500);
  38. // while(1)
  39. // {
  40. // i++;
  41. // USB_printf("AT+MQTTPUB=0,\"%s\",\"{\\\"id\\\":\\\"123\\\"\\,\\\"params\\\":{\\\"%s\\\":{\\\"value\\\":%d}}}\",0,0\r\n",pubscribe,fuc,i);
  42. // HAL_Delay(1500);
  43. // }
  44. }
  45. }

以上代码逻辑和连接wifi代码逻辑相同,暴力发送直到他返回ok,大家自己测试的时候最好先把延时的时间改稍微长一点看回复,当最后一条语句订阅了服务器消息的语句发送完毕,并且返回OK的时候,这里你会惊喜的发现,onenet平台你的设备就会显示在线了。

在这里解释一下前面productid是设备ID,deviceid是用token生成的密钥,subscribe是订阅消息的指令。

这里面又有坑!因为esp8266有记住wifi的功能,就是当你上电后,可能wifi随之就连上了,但是你后面又重新发送连接wifi指令的时候,可能这个时候wifi会掉,这也是我目前 代码一个  bug,此时你并没有连上wifi或者因为其他的原因导致wifi没连上,但是走到了连接mqtt服务器这一步的时候,mqtt就会返回mqttdisconnected :0 error,在你发送连接服务器请求后是有一段这个响应时间,

一般情况下,AT MQTT命令会在10秒内响应,但AT+MQTTCONN命令除外。例如,如果路由器无法访问internet,则AT+MQTTPUB命令会在10秒内响应。但是AT+MQTTCONN命令可能需要更多的时间,因为在不良的网络环境中需要重传数据包。.如果AT+MQTTCONN基于TLS连接,每个包的超时为10秒,则根据握手包计数,总超时将长得多。

后面有时间会修复这个bug,也希望各位读者可以帮我修一修哈哈。一般来说打断点,一步步debug可以避免这个问题,脱机后就可能会出现连不上的情况。

五:当你前面所有的操作都完成之后,将stm32外设采集的消息传到onenet云平台。

如果你千帆过尽,走到这最后一步的时候,恭喜你,快要成功了。

我拿温度举例,如下图,点进产品开发,右边点击设置物模型,自定义功能点

如下图设置,读写类型设置读写。

设置完毕后就是指令,

AT+MQTTPUB=0,"$sys/422b4zbv12/test/thing/property/post","{\"id\":\"123\"\,\"params\":{\"temperature\":{\"value\":20\}}}",0,0

第二个引号之后是你的产品ID,需要改的就是你的这个变量的标识符,与onenet云平台对应就好。

这里用电脑串口助手测试,回复ok,这个时候你就可以看到设备详情里的属性里的温度就会有你value后面的值了。

放在32里 是这样写的

  1. void send_temp()
  2. {
  3. if(flag_temp==1)
  4. {
  5. // while(1)
  6. {
  7. USB_printf("AT+MQTTPUB=0,\"%s\",\"{\\\"id\\\":\\\"123\\\"\\,\\\"params\\\":{\\\"%s\\\":{\\\"value\\\":%d}}}\",0,0\r\n",pubscribe,fuc,temp);
  8. // HAL_Delay(1500);
  9. }
  10. }
  11. }

如果代码跑下来一切顺利的话,电脑的串口助手应该会有如下图样

到这里就大功告成了!

最后:补充main.c以及串口3发送函数代码

main.c

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2024 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "dma.h"
  22. #include "i2c.h"
  23. #include "tim.h"
  24. #include "usart.h"
  25. #include "gpio.h"
  26. /* Private includes ----------------------------------------------------------*/
  27. /* USER CODE BEGIN Includes */
  28. #include "UART_DMA.h"
  29. #include "esp8266.h"
  30. #include "bsp_ds18b20.h"
  31. #include "oled.h"
  32. /* USER CODE END Includes */
  33. /* Private typedef -----------------------------------------------------------*/
  34. /* USER CODE BEGIN PTD */
  35. /* USER CODE END PTD */
  36. /* Private define ------------------------------------------------------------*/
  37. /* USER CODE BEGIN PD */
  38. uint8_t uart3_RX_Buffer[r3_length]={0};
  39. uint8_t UART3_temp[REC_LENGTH] = {0};
  40. unsigned int UART3_Rx_cnt;
  41. int temp,temp_set=15;
  42. int flag_ds;
  43. float m_water=0.15;
  44. /* USER CODE END PD */
  45. /* Private macro -------------------------------------------------------------*/
  46. /* USER CODE BEGIN PM */
  47. /* USER CODE END PM */
  48. /* Private variables ---------------------------------------------------------*/
  49. /* USER CODE BEGIN PV */
  50. /* USER CODE END PV */
  51. /* Private function prototypes -----------------------------------------------*/
  52. void SystemClock_Config(void);
  53. /* USER CODE BEGIN PFP */
  54. /* USER CODE END PFP */
  55. /* Private user code ---------------------------------------------------------*/
  56. /* USER CODE BEGIN 0 */
  57. /* USER CODE END 0 */
  58. /**
  59. * @brief The application entry point.
  60. * @retval int
  61. */
  62. int main(void)
  63. {
  64. /* USER CODE BEGIN 1 */
  65. /* USER CODE END 1 */
  66. /* MCU Configuration--------------------------------------------------------*/
  67. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  68. HAL_Init();
  69. /* USER CODE BEGIN Init */
  70. /* USER CODE END Init */
  71. /* Configure the system clock */
  72. SystemClock_Config();
  73. /* USER CODE BEGIN SysInit */
  74. /* USER CODE END SysInit */
  75. /* Initialize all configured peripherals */
  76. MX_GPIO_Init();
  77. MX_DMA_Init();
  78. MX_USART1_UART_Init();
  79. MX_USART3_UART_Init();
  80. MX_TIM1_Init();
  81. MX_TIM2_Init();
  82. MX_TIM3_Init();
  83. MX_I2C1_Init();
  84. /* USER CODE BEGIN 2 */
  85. HAL_TIM_Base_Start(&htim2);
  86. HAL_TIM_Base_Start(&htim3);
  87. HAL_TIM_Base_Start(&htim1);
  88. HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  89. //__HAL_UART_ENABLE_IT(&huart3,UART_IT_RXNE);
  90. //HAL_UART_Receive_IT(&huart3,(uint8_t *)UART3_temp,REC_LENGTH);
  91. Ds18b20_Init();
  92. StartUartRxDMA();
  93. OLED_Init();
  94. USB_DMA_printf("AT+RST\r\n");
  95. HAL_Delay(100);
  96. //uart3_printf("666");
  97. //esp_init();
  98. esp_wifi_connect();
  99. HAL_Delay(100);
  100. esp_mqtt_connect();
  101. /* USER CODE END 2 */
  102. /* Infinite loop */
  103. /* USER CODE BEGIN WHILE */
  104. while (1)
  105. {
  106. /* USER CODE END WHILE */
  107. /* USER CODE BEGIN 3 */
  108. }
  109. /* USER CODE END 3 */
  110. }
  111. /**
  112. * @brief System Clock Configuration
  113. * @retval None
  114. */
  115. void SystemClock_Config(void)
  116. {
  117. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  118. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  119. /** Initializes the RCC Oscillators according to the specified parameters
  120. * in the RCC_OscInitTypeDef structure.
  121. */
  122. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  123. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  124. RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  125. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  126. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  127. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  128. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  129. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  130. {
  131. Error_Handler();
  132. }
  133. /** Initializes the CPU, AHB and APB buses clocks
  134. */
  135. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  136. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  137. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  138. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  139. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  140. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  141. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  142. {
  143. Error_Handler();
  144. }
  145. }
  146. /* USER CODE BEGIN 4 */
  147. /* USER CODE END 4 */
  148. /**
  149. * @brief This function is executed in case of error occurrence.
  150. * @retval None
  151. */
  152. void Error_Handler(void)
  153. {
  154. /* USER CODE BEGIN Error_Handler_Debug */
  155. /* User can add his own implementation to report the HAL error return state */
  156. __disable_irq();
  157. while (1)
  158. {
  159. }
  160. /* USER CODE END Error_Handler_Debug */
  161. }
  162. #ifdef USE_FULL_ASSERT
  163. /**
  164. * @brief Reports the name of the source file and the source line number
  165. * where the assert_param error has occurred.
  166. * @param file: pointer to the source file name
  167. * @param line: assert_param error line source number
  168. * @retval None
  169. */
  170. void assert_failed(uint8_t *file, uint32_t line)
  171. {
  172. /* USER CODE BEGIN 6 */
  173. /* User can add his own implementation to report the file name and line number,
  174. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  175. /* USER CODE END 6 */
  176. }
  177. #endif /* USE_FULL_ASSERT */

如你所见,我的esp8266函数在main里的while循环前执行,在所有的模块初始化我完成之后,而且每一个与esp8266有关的函数都是一个while循环,这样写是因为之前frertos写多了,想每个功能都单独开一个任务完成,但f1的性能不足以支持这样玩,我这样的写法也是不合适的,像大多数开源等待响应返回函数值执行下一步,放在while循环里写才是正道,这时候你可能会问我的其他外设写在哪儿了,相信佬一定猜出来了,我开了四个定时器,其他的事件都放在定时器里刷新了。

串口3打印函数

  1. void uart3_printf(char *fmt, ...)
  2. {
  3. uint32_t length;
  4. va_list args;
  5. va_start(args, fmt);
  6. length = vsnprintf((char*)uart3_tx_buf,sizeof(uart3_tx_buf)+1, (char*)fmt, args);
  7. va_end(args);
  8. HAL_UART_Transmit(&huart3,uart3_tx_buf,length,0xFFFF);
  9. }

到这里,全文就结束了,如果有什么问题,欢迎大家批评指正!

拜谢!

如果想要完整工程代码,请务必一键三连私信up,或者评论区,谢谢大家!!!最后祝大家都能成功实现,不踩坑!

链接:https://pan.baidu.com/s/12sCS9a8b8_6EFs6pVi8uPg?pwd=wifi 
提取码:wifi 
--来自百度网盘超级会员V2的分享

所有工程均在链接中~

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

闽ICP备14008679号