【STM32+ESP8266连接腾讯云物联网开发平台 2】STM32+ESP8266-01S连接腾讯云
文章目錄
- 前言
- 一、硬件準備
- 1.ESP8266-01S
- 2. STM32F103C8T6核心板或者小開發板及其程序下載器
- 二、軟件準備
- 1.STM32CubeMX
- 2. MDK (Keil v5)
- 3.程序實現流程
- 三、STM32CubeMX 配置工程
- 1.根據芯片信號創建工程
- 2.配置LED驅動引腳
- 3.配置串口驅動
- 4.FreeRTOS配置
- 5.FreeRTOS的定時器配置
- 6.工程配置
- 四、串口中斷驅動編寫
- 五、ESP8266的數據顯示
- 六、AT指令配置ESP8266連接WiFi和騰訊云
- 1.連接WiFi
- 2.連接騰訊云并訂閱主題
- 七、處理JSON數據并控制LED
- 1.分割出Topic 和JSON數據
- 2.JSON數據處理
- 八、騰訊連連App控制LED燈演示
- 源碼請到轉跳:
前言
???????昨天已經用ESP-12S成功連接上騰訊云物聯網開發平臺,并且還能用手機控制了,但是畢竟是在電腦上位機做的連接,還沒有在STM32連接。博主經過一天的努力。成功給STM32接上了騰訊云物聯網開發平臺,先說明幾點:
???????1. 博主用的是RTOS實時操作系統,為的是更快捷的讀取云的數據;
???????2. 博主也是第一次使用RTOS實時操作系統,對一些API還不是特別熟悉;
???????3. 本文雖然大部分介紹怎么實現功能,小部分需要同學們要有點動手能力,比如換SOP芯片啥的。
???????4. 如果沒有看過第一篇 的同學,請移步【STM32+ESP-12S連接騰訊云物聯網開發平臺 1】云平臺的創建和AT固件燒錄,能做到成功連接騰訊云物聯網平臺再看本文,不然這篇博文對大家連接云平臺的幫助不會很大。
聲明一下:博主是第一次使用HAL庫給STAM32編程,所以有不足之處還請見諒!!
一、硬件準備
1.ESP8266-01S
???????如果大家看過 STM32+ESP-12S連接騰訊云物聯網開發平臺 1 都應該還記得:ESP8266-01S因為Flash太小的原因,無法燒錄至少需要2M Flash(ESP8266-01S一般只有1MFlash)的AT固件,這時候就需要各位同學的動手能力了。
???????不就是Flash 太小嗎?換一個大的就是了,所以大家可以把那個8腳的芯片拆了,換成2M以上的Flash芯片。然后燒錄:QCloud_IoT_AT_ESP8266_v2.0.0_20200617_UART_1_3.bin 這個版本的固件,記住不要燒錄錯誤,怎么燒錄請移步: STM32+ESP-12S連接騰訊云物聯網開發平臺 1。
2. STM32F103C8T6核心板或者小開發板及其程序下載器
???????在STM32芯片價格暴漲的年代,用STM32真是為難大家了,但是STM32F103C8T6的最小開發板的價格還是可以接受滴,博主推薦能夠直插ESP8266-01S的,省得大家接線麻煩。
???????程序下載器大家可以根據燒錄方式來選擇:
???????1. 串口燒錄的可以用USB轉TTL模塊就行;
???????2 仿真調試方式下載,大家可以用STLink,或者Jlink都行。
二、軟件準備
1.STM32CubeMX
`???????博主玩這么多年的STM32,也是第一次用這個軟件,不得不說,比起自己搭開發環境來說,這個真是太省時間了。
2. MDK (Keil v5)
??????? 這個軟件,博主只用來學習,不做任何商業用途。推薦使用正版MDK。
3.程序實現流程
三、STM32CubeMX 配置工程
???????博主也是第一次使用這個軟件來配置工程,有什么不足之處非常歡迎指正,
1.根據芯片信號創建工程
???????到這里就需要開始配置功能引腳了。
2.配置LED驅動引腳
3.配置串口驅動
4.FreeRTOS配置
5.FreeRTOS的定時器配置
??????? FreeRTOS是要使用定時器來管理任務的并行關系,所以要對定時器進行更改:
6.工程配置
??????? 配置完引腳之后,還要對工程輸出進行配置:
這樣,我們的工程就配置好了,下面就能編寫功能代碼了。
四、串口中斷驅動編寫
??????? STM32CubeMx生成的代碼使用HAL庫寫的,而且對串口中斷做了一下改變,現在并不是說直接就可以在串口中斷函數中處理數據。目前,串口中斷函數中只有一個函數:
void USART1_IRQHandler(void) {/* USER CODE BEGIN USART1_IRQn 0 *//* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 *//* USER CODE END USART1_IRQn 1 */ }??????? 這個 HAL_UART_IRQHandler(&huart1) 函數只是判斷中斷類型而已,并沒有處理數據的相關代碼在里面。有興趣的同學可以到函數里面看看。
??????? 那既然這個函數并沒有做數據處理,那肯定是有個函數專門負責接收串口數據的:
串口中斷接收函數: HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
這個函數的功能:這個函數是把husart 串口接收到的 Size數據量的字節存到pData中, 并且關掉中斷。
也就說,當我們接受完數據之后,要重新使用這個函數來開啟中斷。另外還要介紹另一個和這個函數息息相關的函數:
串口接收回調函數: void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
這個函數默認不會自動生成,需要我們自己寫。
函數功能:當HAL_UART_Receive_IT函數結束后,會進來這個函數當中,用戶可以在這個函數中對數據進行處理。
方便大家,給各位同學貼出我自己寫的函數HAL_UART_RxCpltCallback
相關宏結構體:
typedef struct usart {unsigned char UART_Data[512]; unsigned char UART_Flag;unsigned int UART_Cnt;unsigned char UART_DataBuf[1]; }USART_DataBuf;我把接收到的數據存在結構體當中進行同意處理,而且這個結構體是全局的,方便使用。
五、ESP8266的數據顯示
??????? 這個函數可以把ESP8266接收到的數據通過USART1打印出來,方便我們查看調試和了解AT指令的進度。這個函數我把它放在了一個獨立線程當中,這樣就可以不斷地讀取并顯示出來。
ESP8266DATATypedef esp8266data; //獲取串口數據 uint8_t *Esp8266GetData(void) {if (UART2_DATA.UART_Flag == 1){strcpy((char *)esp8266data.data, (const char *)UART2_DATA.UART_Data);esp8266data.data_size = UART2_DATA.UART_Cnt;printf("%s", UART2_DATA.UART_Data);for (; UART2_DATA.UART_Cnt > 0; UART2_DATA.UART_Cnt--)UART2_DATA.UART_Data[UART2_DATA.UART_Cnt] = 0;esp8266data.flag += 1; if(esp8266data.flag>16) esp8266data.flag=16;UART2_DATA.UART_Flag = 0;return esp8266data.data;}return esp8266data.data; } void StartTask02(void *argument) {/* USER CODE BEGIN StartTask02 *//* Infinite loop */uint8_t *sub_buf;HAL_UART_RxCpltCallback(&huart2);for (;;){sub_buf = Esp8266GetData();六、AT指令配置ESP8266連接WiFi和騰訊云
??????? 有了串口中斷及之前地AT指令流程,就可以連接騰訊云了:
1.連接WiFi
//連接WiFi void Esp8266LinkAp(uint8_t *ssid, uint8_t *passwd) {uint8_t *linkap;linkap = (uint8_t *)malloc(128);HAL_UART_Transmit(&huart2, " \r\n", 3, 1000);do{switch (esp8266data.flag){case 0: //復位ESP8266HAL_UART_Transmit(&huart2, "AT+RST\r\n", strlen("AT+RST\r\n"), 5000);osDelay(2000);break;case 2: //設置連接模式case 3:HAL_UART_Transmit(&huart2, "AT+CWMODE=1\r\n", strlen("AT+CWMODE=1\r\n"), 5000);osDelay(1000);break;//開始連接WiFicase 4:case 5:sprintf((char *)linkap, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, passwd);HAL_UART_Transmit(&huart2, (uint8_t *)linkap, strlen((const char *)linkap), 5000);osDelay(5000);break;default:break;}} while (esp8266data.flag < 7);free(linkap); }2.連接騰訊云并訂閱主題
void Esp8266LinkloTExplorer(void) {uint8_t *device_massage;device_massage = (uint8_t *)malloc(128);do{switch (esp8266data.flag){// case 7: //設置連接信息case 7:case 8:sprintf((char *)device_massage, "AT+TCDEVINFOSET=1,\"%s\",\"%s\",\"%s\"\r\n", PRODUCT_ID, DEVUICE_NAME, DEVICE_SECRET);HAL_UART_Transmit(&huart2, device_massage, strlen((const char *)device_massage), 5000);osDelay(1000);break;case 9:case 10:HAL_UART_Transmit(&huart2, "AT+TCMQTTDISCONN\r\n", strlen("AT+TCMQTTDISCONN\r\n"), 5000); //先斷開現有鏈接osDelay(500);break;case 11:HAL_UART_Transmit(&huart2, "AT+TCMQTTCONN=1,5000,240,0,1\r\n", strlen("AT+TCMQTTCONN=1,5000,240,0,1\r\n"), 5000);osDelay(500);break;case 12: //檢查是否已經連接HAL_UART_Transmit(&huart2, "AT+TCMQTTSTATE?\r\n", strlen("AT+TCMQTTSTATE?\r\n"), 5000);osDelay(100);break;case 13: //訂閱主題sprintf((char *)device_massage, "AT+TCMQTTSUB=\"$thing/down/property/%s/%s\",0\r\n", PRODUCT_ID, DEVUICE_NAME);HAL_UART_Transmit(&huart2, device_massage, strlen((const char *)device_massage), 5000);osDelay(500);break;default:esp8266data.flag = 16;break;}} while (esp8266data.flag < 15);free(device_massage); }七、處理JSON數據并控制LED
???????博主的騰訊云下發的數據在ESP8266中的打印是這樣的:
+TCMQTTRCVPUB:"$thing/down/property/C9N29PAEXK/LED",105, "{"method":"control","clientToken":"clientToken-d4c2c848-b930-44e7-bc4f-55c0226b0907","params":{"led1":1}}"1.分割出Topic 和JSON數據
???????根據打印出來的信息可以看出,只要使用字符串操作就能輕松分割出Topic和JSON:
void loTMessageHandler(void) {char *pub_buf;unsigned int i = 0;if (TCMQTTRCVPUB != 0){//分離出Topicpub_buf = strstr((const char *)TCMQTTRCVPUB, "$thing/down/property");if (pub_buf != NULL){while (*pub_buf != '\"'){Sub_Topic[i] = *pub_buf++;i++;}i = 0; #if LOT_Debugprintf("Topic=%s\r\n", Sub_Topic); #endif}//分離出數據pub_buf = strstr((const char *)TCMQTTRCVPUB, "{\"method\":\"control\"");if (pub_buf != NULL){while (*pub_buf != '\n'){Sub_Data[i] = *pub_buf++;i++;}//去掉結尾的雙引號Sub_Data[i - 2] = '\0'; #if LOT_Debugprintf("Data=%s\r\n", Sub_Data); #endifi = 0;}}2.JSON數據處理
???????處理JSON數據,大家可以去下載cJSON的庫,就兩個文件,cJSON.c和cJSON.h:cJson官網下載;把這兩個文件加入到自己的工程中,引用一下頭文件即可,下面是我代碼:
oid cJsonMessageHandler(uint8_t *cJsonDATA) {if (cJsonDATA != NULL){cJSON *_JsonRoot = cJSON_Parse((const char *)cJsonDATA);if (_JsonRoot == NULL)goto __cJSON_Delete;cJSON *cJSON_params = cJSON_GetObjectItem(_JsonRoot, "params");if (cJSON_params == NULL)goto __cJSON_Delete;cJSON *cJSON_led1 = cJSON_GetObjectItem(cJSON_params, "led1"); #if LOT_Debugprintf("led1=%d\r\n", cJSON_led1->valueint);#endifif (cJSON_led1->valueint == 1)HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);//亮燈elseHAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);//關燈__cJSON_Delete:cJSON_Delete(_JsonRoot);memset(Sub_Data, 0, sizeof(Sub_Data));} }八、騰訊連連App控制LED燈演示
源碼請到轉跳:
【STM32+ESP8266連接騰訊云物聯網開發平臺 3】STM32+ESP8266-01S在騰訊云上動態注冊設備(AT指令方式)–附帶源碼
總結
以上是生活随笔為你收集整理的【STM32+ESP8266连接腾讯云物联网开发平台 2】STM32+ESP8266-01S连接腾讯云的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Volley传输网络数据
- 下一篇: slickedit字体设置——使用 Ve