基于STM32的ESP8266获取天气数据(HAL库)

本文介绍了ESP8266模块的使用,包括如何通过AT指令刷写固件,解决无法进入AT模式的问题。接着讲解了ESP8266的STA、AP和AP+STA三种工作模式,并提供了连接WiFi的示例。然后,通过单片机驱动ESP8266获取天气数据的过程,展示了从配置连接到发送HTTP请求的步骤。最后,分享了在实现过程中遇到的细节问题和解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.介绍

进入主题,下图正是购买的esp8266模块请添加图片描述
对于esp01,引脚图如下

在这里插入图片描述

二.刷固件

在使用AT指令时,有时候会无法进入AT模式,也就是在串口发送指令,无应答。除了检查引脚和TTL模块是否接错,还可能是需要刷固件,在接线时要注意TTL要与ESP8266共地,可以用面包板拓展出来一个GND
1.在安信可官网下载刷固件工具
安信可官网
在这里插入图片描述
2.选择8266系列
在这里插入图片描述
3.在这里插入图片描述
提示框中出现这样代表固件下载完成。

三.AT指令

ESP8266与TTL连接图如下(一定要连接正确,别问为什么)
在这里插入图片描述

在波特率为115200的情况下,向串口发送AT,会出现一段乱码,最后一行出现ready,表示模块已经进入AT模式
在这里插入图片描述
这位博主的AT指令集很详细,我就不赘述了AT指令
下面介绍三种工作方式
1.sta模式(即模块作为客户端,可以连接其他局域网)
向串口发送以下指令
1.AT+CWMODE=1
2.AT+CWJAP=“newifi_F8A0”,“anxinke123”
注意WiFi名称必须为10字节,否则连接不上在这里插入图片描述
2.AP模式(WiFi模块作为服务端,相当于一个热点)
1.AT+CWMODE=2
2.AT+CWSAP=“esp8266”,“12345678”,11,3
请添加图片描述

3.AP+sta模式
1. AT+CWMODE=3
2.AT+CWSAP=“esp8266”,“12345678”,11,3
3.AT+CWJAP=“abc”,“qwertyui”
在这里插入图片描述
esp8266同时支持配网,但是由于模块无法连接5G路由器,所以不做演示。

四.单片机驱动模块获取天气

在得到天气之前,首先要连接热点,然后连接TCP,再向网址提出请求,具体过程在C文件里面,下面的代码是自己根据顺序写的,大家也可以自己编写。

1.首先是cubemx的配置

在这里插入图片描述
这里打开两个串口,一个开启中断,开启中断的串口与ESP8266通信,另一个串口用作数据监视。注意单片机与ESP8266的连接方法请添加图片描述

2.代码层

首先大家按照这位博主的方法在心知天气网进行注册
完成之后,将

GET https://api.seniverse.com/v3/weather/now.json?key=私钥&location=城市&language=zh-Hans&unit=c

这里的私钥,城市替换进去
CUBEMX生成代码后,在
在这里插入图片描述
添加中断开启函数,在main函数下方添加回调函数(我这里使用串口1与ESP8266通信,串口2检测数据)

 //ES8266驱动串口接收中断处理函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//uint8_t res;
	if(huart->Instance == USART1)	// 判断是由哪个串口触发的中断
	{
	//	HAL_UART_Receive(&huart1, usart1_rxone, 1, 0xffff);
		//将接收到的数据放入接收usart1接收数组
		usart1_rxbuf[usart1_rxcounter] =usart1_rxone[0];
		usart1_rxcounter++;	//接收数量+1

		//重新使能串口1接收中断
		HAL_UART_Receive_IT(&huart1,usart1_rxone,1);		
	}
}

下面是驱动函数

#include "esp8266.h"
#include "stdio.h"
#include "stdint.h"



uint8_t usart1_txbuf[256];
uint8_t usart1_rxbuf[512];
uint8_t usart1_rxone[1];
uint8_t usart1_rxcounter;


//查找字符串1中是否包含字符串2
uint8_t Find_Str(char* str1,char* str2)
{
	if(strstr(str1,str2)==0)//str只能返回字符串
	{		
		return 0;           //不包含返回0
	}                       
	else return 1;   //包含返回1
}

uint8_t ESP8266_Check(void)
{
	HAL_UART_Transmit(&huart1,(uint8_t*)"AT\r\n", strlen("AT\r\n"), 100);
	if(Find_Str((char* )usart1_rxbuf,"OK"))
	{
		return 1;
	}
	else return 0;
}

void ESP8266_WIFI_Connect(char* ssid,char* pswd)
{
	HAL_UART_Transmit(&huart1,(uint8_t*)"AT+CWMODE=1\r\n", strlen("AT+CWMODE=1\r\n"), 0xffff);
	sprintf((char*)usart1_txbuf,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pswd);
	HAL_UART_Transmit(&huart1,(uint8_t*)usart1_txbuf, strlen((char*)usart1_txbuf), 0xffff);
	HAL_Delay(1000);
  if(Find_Str((char* )usart1_rxbuf,"CONNECT"))
	{
		printf("WIFI OK");
	}
	else printf("WIFI NO");
}

void ESP8266_Weather_Get(char* MODE,char* IP,uint16_t PORT)
{
	sprintf((char*)usart1_txbuf,"AT+CIPSTART=\"%s\",\"%s\",%d\r\n",MODE,IP,PORT);
	HAL_UART_Transmit(&huart1,(uint8_t*)usart1_txbuf, strlen((char*)usart1_txbuf), 0xffff);
	if(Find_Str((char* )usart1_rxbuf,"CONNECT"))
	{
		printf("TCP OK");
	}
	else printf("TCP NO");
	
	HAL_UART_Transmit(&huart1,(uint8_t*)"AT+CIPMODE=1\r\n", strlen("AT+CIPMODE=1\r\n"), 0xffff);
	HAL_Delay(1000);
	HAL_UART_Transmit(&huart1,(uint8_t*)"AT+CIPSEND\r\n", strlen("AT+CIPSEND\r\n"), 0xffff);
	HAL_Delay(1000);
	HAL_UART_Transmit(&huart1,(uint8_t*)"GET https://api.seniverse.com/v3/weather/now.json?key=SmDRsPvn-1fxNz97x&location=beijing&language=zh-Hans&unit=c\r\n", strlen("GET https://api.seniverse.com/v3/weather/now.json?key=SmDRsPvn-1fxNz97x&location=beijing&language=zh-Hans&unit=c\r\n"), 0xffff);
	HAL_Delay(1000);
	HAL_UART_Transmit(&huart1,(uint8_t*)"+++", strlen("+++"), 0xffff);
}


/*
得到天气的顺序
    HAL_UART_Transmit(&huart1,(uint8_t*)"AT\r\n", strlen("AT\r\n"), 100);
	  HAL_Delay(1000);
		HAL_UART_Transmit(&huart1,(uint8_t*)"AT+CWMODE=1\r\n", strlen("AT+CWMODE=1\r\n"), 0xffff);
		HAL_Delay(1000);
    HAL_UART_Transmit(&huart1,(uint8_t*)"AT+RST\r\n", strlen("AT+RST\r\n"), 0xffff);
		HAL_Delay(3000);
		HAL_UART_Transmit(&huart1,(uint8_t*)"AT+CIPMUX=0\r\n", strlen("AT+CIPMUX=0\r\n"), 0xffff);
		HAL_Delay(1000);
		HAL_UART_Transmit(&huart1,(uint8_t*)"AT+CWJAP=“abc”,qwertyui\r\n", strlen("AT+CWJAP=“abc”,“qwertyui”\r\n"), 0xffff);
		HAL_Delay(1000);
		HAL_UART_Transmit(&huart1,(uint8_t*)"AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n", strlen("AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n"), 0xffff);
		HAL_Delay(300);
		HAL_UART_Transmit(&huart1,(uint8_t*)"AT+CIPMODE=1\r\n", strlen("AT+CIPMODE=1\r\n"), 0xffff);
		HAL_Delay(1000);
		HAL_UART_Transmit(&huart1,(uint8_t*)"AT+CIPSEND=5\r\n", strlen("AT+CIPSEND=5\r\n"), 0xffff);
		HAL_Delay(1000);
		HAL_UART_Transmit(&huart1,(uint8_t*)"GET https://api.seniverse.com/v3/weather/now.json?key=SmDRsPvn-1fxNz97x&location=beijing&language=zh-Hans&unit=c\r\n", strlen("GET https://api.seniverse.com/v3/weather/now.json?key=SmDRsPvn-1fxNz97x&location=beijing&language=zh-Hans&unit=c\r\n"), 0xffff);
	 HAL_Delay(1000);
	 HAL_UART_Transmit(&huart1,(uint8_t*)"+++", strlen("+++"), 0xffff);
*/


#ifndef __ESP8266_H
#define __ESP8266_H

#include "stm32f1xx_hal.h"
#include "usart.h"
#include <string.h>
#include <stdio.h>


extern uint8_t usart1_txbuf[256];
extern uint8_t usart1_rxbuf[512];
extern uint8_t usart1_rxone[1];
extern uint8_t usart1_rxcounter;

void ESP8266_Weather_Get(char* MODE,char* IP,uint16_t PORT);
void ESP8266_WIFI_Connect(char* ssid,char* pswd);
uint8_t ESP8266_Check(void);
uint8_t Find_Str(char* str1,char* str2);

#endif

展示一下成果,
在这里插入图片描述
总结一下,这次对WIFI模块的探索中,耗费时间比较长在获取天气上,忽略掉了在引号里面显示引号要在前面加反斜杠还有换行这种小细节,以后还是要多多注意细节。加油,继续努力。
欢迎指正

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

地球先生_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值