记录项目基于HAL+STM32+Freertos的天气桌面(暂时就叫这个了)(day1)
简介主控STM32F103C8T6元器件ESP01S。主频为72mhz开启usart1与usart2usart1用于回传esp01s发送的信息usart2用于连接esp01s。freertos新建1个任务大小128*41个用于获取心知天气内的数据。GPIO配置图Freertos配置ESP8266.c// ESP8266.c // // Created by 25479 on 2026/3/15. // #include esp8266.h #include main.h #include usart.h #include string.h // 接收ESP8266数据调试串口 #define USART_DEBUG huart1 // WIFI连接信息 #define ESP8266_WIFI_INFO ATCWJAP\R\,\srj12345678\\r\n #define ESP8266_TCP_INFO ATCIPSTART\TCP\,\api.seniverse.com\,80\r\n uint8_t Get_Weather_IP[] GET https://api.seniverse.com/v3/weather/now.json?keyS_P6u0GEsr6Jmz4mGlocationbeijinglanguagezh-Hansunitc\r\n; // esp8266数据缓冲区 uint8_t esp8266_buf[ESP8266_BUF_SIZE]; uint16_t esp8266_cnt 0, esp8266_cntPre 0; uint8_t aRxBuffer; // 串口接收中断缓冲区 // 清空ESP8266接收缓冲区 void ESP8266_Clear(void) { memset(esp8266_buf, 0, sizeof(esp8266_buf)); // 清零缓冲区 esp8266_cnt 0; // 重置接收计数器 } // 检查数据接收状态 _Bool ESP8266_WaitRecive() { if (esp8266_cnt 0) return REV_WAIT; // 检查是否接收完成 if (esp8266_cnt esp8266_cntPre) { esp8266_cnt 0; return REV_OK; } esp8266_cntPre esp8266_cnt; return REV_WAIT; } // 发送AT指令并检查响应 _Bool ESP8266_SendCmd(char *cmd, char *res) { uint8_t timeOut 200; // 通过串口2发送AT指令 Usart_SendString(huart2, cmd, strlen(cmd)); // HAL_UART_Transmit(huart2, cmd, strlen(cmd), 1000); // 等待响应 while (timeOut--) { if (ESP8266_WaitRecive() REV_OK) { // 检查是否包含预期响应 if (strstr((char *)esp8266_buf, res) ! NULL) { ESP8266_Clear(); return 0; // 成功 } } HAL_Delay(10); // 延时10ms } return 1; // 失败 } // ESP8266初始流程 void ESP8266_Init(void) { ESP8266_Clear(); // 清空接收缓冲区 // 1. 测试AT指令 UsartPrintf(USART_DEBUG, 0. AT\r\n, strlen(0. AT\r\n)); UsartPrintf(USART_DEBUG, 1. AT\r\n, strlen(1. AT\r\n)); while (ESP8266_SendCmd(AT\r\n, OK)) HAL_Delay(500); UsartPrintf(USART_DEBUG, 0. AT\r\n, strlen(0. AT\r\n)); // 2. 重启模块 UsartPrintf(USART_DEBUG, 1. RST\r\n, strlen(1. RST\r\n)); ESP8266_SendCmd(ATRST\r\n, ); HAL_Delay(500); // 3. 设置为STA模式客户端模式 UsartPrintf(USART_DEBUG, 2. STA模式\r\n, strlen(2. STA模式\r\n)); while (ESP8266_SendCmd(ATCWMODE1\r\n, OK)) HAL_Delay(500); // 4. 关闭多路连接 UsartPrintf(USART_DEBUG, 3. 关闭多路连接\r\n, strlen(3. 关闭多路连接\r\n)); while (ESP8266_SendCmd(ATCIPMUX0\r\n, OK)) HAL_Delay(500); // 5. 连接 WiFi UsartPrintf(USART_DEBUG, 4. 连接WiFi\r\n, strlen(4. 连接WiFi\r\n)); while (ESP8266_SendCmd(ESP8266_WIFI_INFO, OK)) HAL_Delay(500); } // ESP8266获取天气数据 void ESP8266_GetWeather(void) { // 0. 清空接收缓冲区 ESP8266_Clear(); // 1 重启esp8266 // UsartPrintf(USART_DEBUG, 0. RST\r\n, strlen(0. RST\r\n)); // ESP8266_SendCmd(ATRST\r\n, ); // HAL_Delay(1000); // 2. 设置透传模式 UsartPrintf(USART_DEBUG, 1. 设置透传模式\r\n, strlen(1. 设置透传模式\r\n)); while (ESP8266_SendCmd(ATCIPMODE1\r\n, OK)) HAL_Delay(500); // 3. 创建TCP连接 UsartPrintf(USART_DEBUG, 2. 连接TCP\r\n, strlen(2. 连接TCP\r\n)); while (ESP8266_SendCmd(ESP8266_TCP_INFO, OK)) HAL_Delay(500); // 2. 透传数据 UsartPrintf(USART_DEBUG, 3. 进入发送模式\r\n, strlen(3. 进入发送模式\r\n)); // ESP8266_SendCmd(ATCIPSEND\r\n, ); HAL_UART_Transmit(huart2, ATCIPSEND\r\n, strlen(ATCIPSEND\r\n), 100); HAL_Delay(500); // 3. 发送数据 UsartPrintf(USART_DEBUG, 4. 发送GET请求\r\n, strlen(4. 发送GET请求\r\n)); // ESP8266_SendCmd(Get_Weather_IP, ); HAL_UART_Transmit(huart2, Get_Weather_IP, strlen(Get_Weather_IP), 1000); // ESP8266_SendCmd(GET https://api.seniverse.com/v3/weather/daily.json?keyS_P6u0GEsr6Jmz4mGlocationbeijinglanguageenunitcstart-1days5, ); HAL_Delay(500); } // 串口接收中断回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart huart2) { // 检查缓冲区空间 if (esp8266_cnt ESP8266_BUF_SIZE - 1) { esp8266_buf[esp8266_cnt] aRxBuffer; // 存入数据 } else { // 缓冲区溢出处理 esp8266_cnt 0; memset(esp8266_buf, 0, ESP8266_BUF_SIZE); } // esp8266_cnt; // 重启接收中断 HAL_UART_Receive_IT(huart2, (uint8_t *)aRxBuffer, 1); } }ESP8266.h// // Created by 25479 on 2026/3/15. // #ifndef ESP8266_WATCH_ESP8266_H #define ESP8266_WATCH_ESP8266_H // PA3 - TX // PA2 - RX #include main.h #define ESP8266_BUF_SIZE 512 #define REV_OK 0 // 数据接收完成标志 #define REV_WAIT 1 // 数据接收未完成标志 extern uint8_t esp8266_buf[ESP8266_BUF_SIZE]; void ESP8266_Clear(void); _Bool ESP8266_WaitRecive(); _Bool ESP8266_SendCmd(char *cmd, char *res); void ESP8266_Init(void); void ESP8266_GetWeather(void); #endif //ESP8266_WATCH_ESP8266_H在usart.c中添加一下两行代码void Usart_SendString(UART_HandleTypeDef USARTx, uint8_t *str, uint16_t len) { HAL_UART_Transmit(USARTx ,(uint8_t *)str,len,HAL_MAX_DELAY); } void UsartPrintf(UART_HandleTypeDef USARTx, uint8_t *str, uint16_t len) { HAL_UART_Transmit (USARTx ,(uint8_t *)str,len,HAL_MAX_DELAY); }wifi_task.c// // Created by 25479 on 2026/3/15. // #include cmsis_os2.h #include esp8266.h #include main.h #include usart.h #include string.h void StartWIFITask(void *argument) { // ESP8266_Init(); ESP8266_GetWeather(); HAL_UART_Transmit(huart1, esp8266_buf, strlen(esp8266_buf), 1000); for (;;) { // 处理函数只需调用一次 osDelay(10); } }usart1回传显示数据显示成功后续处理注意需要在main函数中提前开始一次中断测试时出现了一个问题在反复重启单片机或者反复烧录之后导致卡死排查原因是回传函数无法触发导致esp8266_cnt一直为0但是在main.c中已经开启了中断。暂时没找出来是为什么我的解决方法是注释掉main.c中的HAL_UART_Receive_IT()烧录一次然后在取消注释再烧录一次。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2423438.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!