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的界面,所以暂时不去美化界面了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值