hal库,stm32+esp01s连接心知天气显示天气和温度

1.简介

用stm32的串口通信与esp01s连接,通过esp01s发送AT指令,连接心知天气,获取温度和时间,并在1.8寸的lcd屏幕上进行显示。

2.串口和esp01s

使用函数发送数据

HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)

修改中断接收数据,这里定义了一个数组buf1进行接收,也可以使用DMA。

uint8_t buf1[300];

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
    if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) == SET) {
        __HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清除空闲中断标志
            // 还原缓冲区
            huart1.RxXferCount = sizeof(buf1);
            huart1.pRxBuffPtr = buf1;
     // 重新启动中断接收
     HAL_UART_Receive_IT(&huart1, buf1, sizeof(buf1));
     return;
		}
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

3.esp01s的at指令

通过上面的串口发送如下指令,进行连接。

char mode[] = "AT+CWMODE=1\r\n";			//设置STA模式
char A_spots[] = "AT+CWJAP=\"WiFi名称\",\"密码\"\r\n";		//连接wifi
char startTCP[]= "AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n";			//连接心知服务器
char data2[]= "AT+CIPSEND=114\r\n";   //开启数据发送
char data3[]= "GET https://api.seniverse.com/v3/weather/now.json?key=你的密钥&location=地址&language=en&unit=c\r\n";//发送API访问

需要注意以下几点。

1.发送后要有延迟,等待at指令返回。可以将其显示在lcd上。

	HAL_Delay(2000);
	LCD_ShowString(1, 1, (const uint8_t *)buf1, 0xFFFF, 0x0000, 12, 0);
	memset(buf1, 0, sizeof(buf1));  //清空buf1

2.这里我用的是英文,因为后面返回中文的话会显示乱码。可修改对应en的位置改变语言。

char data3[]= "GET https://api.seniverse.com/v3/weather/now.json?key=SSvKGCGFa4n0Ej_1C&location=37.90:113.65&language=en&unit=c\r\n";//发送API访问
开启数据传输

AT+CIPSEND=?,等于的内容是你要发送的字符串长度。我的esp01s不能发送不定长的。

4.LCD的显示

我用的是修改的中景园给的1.8寸spi的代码,CubeMx上没有开启spi,是开了5个输出。直接用hal库函数替换了原先的标准库函数就可以了。

// LCD 控制引脚
#define LCD_SCLK_Clr() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET) // SCL = SCLK
#define LCD_SCLK_Set() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET)

#define LCD_MOSI_Clr() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET) // SDA = MOSI
#define LCD_MOSI_Set() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET)

#define LCD_RES_Clr()  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET) // RES
#define LCD_RES_Set()  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)

#define LCD_DC_Clr()   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET) // DC
#define LCD_DC_Set()   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET)

#define LCD_CS_Clr()   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET) // CS
#define LCD_CS_Set()   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET)

#define LCD_BLK_Clr()  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET) // BLK
#define LCD_BLK_Set()  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET)

5.提取返回的内容

用了一个提取内容的函数。

void displayWeatherInfo(const char *json_str) {			//提取内容
    char text[20] = {0};
    char code[10] = {0};
    char temperature[10] = {0};

    // 提取text字段
    const char *text_key = "\"text\":\"";
    char *text_start = strstr(json_str, text_key);
    if (text_start != NULL) {
        text_start += strlen(text_key);
        char *text_end = strchr(text_start, '"');
        if (text_end != NULL) {
            strncpy(text, text_start, text_end - text_start);
        }
    }

    // 提取code字段
    const char *code_key = "\"code\":\"";
    char *code_start = strstr(json_str, code_key);
    if (code_start != NULL) {
        code_start += strlen(code_key);
        char *code_end = strchr(code_start, '"');
        if (code_end != NULL) {
            strncpy(code, code_start, code_end - code_start);
        }
    }

    // 提取temperature字段
    const char *temperature_key = "\"temperature\":\"";
    char *temperature_start = strstr(json_str, temperature_key);
    if (temperature_start != NULL) {
        temperature_start += strlen(temperature_key);
        char *temperature_end = strchr(temperature_start, '"');
        if (temperature_end != NULL) {
            strncpy(temperature, temperature_start, temperature_end - temperature_start);
        }
    }

    // 在LCD上显示内容
		LCD_Fill(0, 0, LCD_W, 16, YELLOW);//指定区域填充颜色
    LCD_ShowString(10, 20, (const uint8_t *)text, 0xFFFF, 0x0000, 32, 0);         // 显示text
    LCD_ShowString(50, 50, (const uint8_t *)code, 0xFFFF, 0x0000, 32, 0);         // 显示code
    LCD_ShowString(80, 60, (const uint8_t *)temperature, 0xFFFF, 0x0000, 32, 0);  // 显示temperature
}

6.为什么不用json解析

因为我试了很多次都解析不了,即便删除了AT返回指令的开头和结尾都不行。

7.最终效果

因为准备学lvgl的界面,所以暂时不去美化界面了。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32是一款微控制器,ESP8266是一款Wi-Fi模块,MQTT是一种消息传输协议,HALSTM32的硬件抽象层。在使用STM32ESP8266进行MQTT通信时,可以使用HAL来简化开发过程。 ### 回答2: STM32 ESP8266 MQTT HAL是一种为嵌入式系统设计的,包括STM32微控制器,ESP8266 Wi-Fi模块和MQTT协议。HAL是ST公司开发的,可广泛应用于STM32系列微控制器的软件开发中。这个提供了许多便捷的API接口,可以使开发者快速高效地进行嵌入式系统的开发。 ESP8266 Wi-Fi模块是一种小型,低成本的智能设备,可将微控制器连接到互联网。通过使用HAL,可以轻松地将STM32微控制器和ESP8266 Wi-Fi模块进行集成,从而实现快速的网络连接。MQTT协议是基于发布/订阅模式的消息传递协议,可轻松地支持设备到设备的通信,以及设备到云的通信。这种协议可以降低通信成本和复杂性,同时提高设备之间通信的效率。 使用STM32 ESP8266 MQTT HAL可以实现许多不同的嵌入式系统应用。例如,可以使用该与传感器设备连接,从而实现远程监控和控制。还可以将其用于智能家居系统,实现灯光、温度、排气等等控制。 总之,STM32 ESP8266 MQTT HAL是一种非常有用的嵌入式系统开发,可以帮助开发者快速高效地开发网络连接的嵌入式系统应用。它的广泛适用性和易用性使得它成为嵌入式系统开发人员的首选工具之一。 ### 回答3: STM32ESP8266都是常用的嵌入式系统的微控制器,它们的应用范围非常广泛。在嵌入式系统中,使用STM32ESP8266进行MQTT通信时,可以使用HAL,该为开发人员提供了一个快速而简单的方式来实现这一目标。 MQTT是一种用于物联网通信的开放式、轻量级的消息协议,支持多种设备和应用程序之间的通信。在STM32单片机中使用MQTT时,可以利用HAL提供的函数进行配置,在ESP8266中,可以使用AT指令集和HAL。 使用HAL可以简化STM32ESP8266的开发过程,利用该提供的一些组件,例如网络接口、外设综合体和操作系统,可以轻松地实现MQTT通信。HAL还提供了一些常见的API,例如MQTT客户端、发布和订阅主题、消息体和QoS等,这些操作都可以在单片机上轻松实现。 在STM32ESP8266中使用HAL还可以提高代码的可读性和可重复性。由于HAL提供了众多函数和API,因此开发人员可以更容易地编写和调试代码。使用HAL还有一个巨大的好处,即减少了开发时间和成本,因为HAL提供了丰富的组件、函数和API,因此开发人员可以快速地开发和测试代码。 总之,STM32ESP8266可以轻松地实现MQTT通信,使用HAL可以进一步简化开发过程,提高代码的可读性和可重复性,从而节省时间和成本。源自以上原因,HAL是实现STM32ESP8266的MQTT通信的最佳选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值