前言:上一章节我们通过串口调试助手,成功获取到天气数据,这一节我们将通过MCU的串口发送、接收功能,实现MCU获取天气数据。
传送门:基于STM32F103的网络天气时钟(1)---------通过串口获取天气
单片机具有串口发送和接收功能,我们可以通过串口发送AT指令从而获取到知心天气的数据。并在另一个串口输出。
除了上一章使用的wifi模块还有USB转TTL模板外,我们还需要准备一块stm32单片机的最小系统板。
同上章节。
同上章节。
因为项目比较简单,所以使用哪一款单片机随意~
我使用的是在淘宝上买的stm32f103rct6的最小系统板。
最小系统板:购买链接
USB转TTL(种类有点多,随便选一个就行,我用的是CH340这个芯片的):购买链接
ESP8266:购买链接
OLED(我用的是0.96寸4针,I2C接口):购买链接
ST-Link V2下载线:购买链接
上一节收到的数据有部分是乱码,经查阅是因为编码方式不一致导致的,不过“QCOM”没有更改编码方式的功能,于是我就换成“XCOM”。使用方法和之前的大体一致。
下载链接
提取码:3mzd
MCU | ESP8266 |
---|---|
3.3V | VCC |
GND | GND |
PB10 | RXD |
PB11 | TXD |
3.3V | IO |
3.3V | RST |
MCU | USB转TTL |
---|---|
5V | VCC |
GND | GND |
PA9 | RXD |
PA10 | TXD |
基础功能的代码这里就不详细介绍了,主要讲解关键代码。
源代码在文末下载,大部分代码已经加上注释。
ESP8266初始化,实现建立WIFI连接的功能。
其实就是串口发送AT指令,然后等待ESP8266的回复而已,很简单的。
移植时需要更改的地方为wifi的账号(wifista_ssid)和密码(wifista_password),该定义在esp8266.c中更改。
本代码发送的AT指令有:
指令 | 回复 | 功能 |
---|---|---|
AT | OK | AT测试 |
AT+CWMODE=1 | OK | 设置wifi模式 |
AT+RST | OK | 重启模块 |
AT+CIPMUX=0 | OK | 设置连接模式 |
AT+CWJAP=“ssid”,“pwd” | WIFI GOT IP | 连接wifi |
void esp8266_start_trans(void)
{
u8 *p;
p=mymalloc(SRAMIN,50); //申请32字节内存,用于存wifista_ssid,wifista_password
printf("send:AT\r\n");
while(esp8266_send_cmd("AT","OK",20))//检查WIFI模块是否在线
{
}
//设置工作模式 1:station模式 2:AP模式 3:兼容 AP+station模式
printf("send:AT+CWMODE=1\r\n");
esp8266_send_cmd("AT+CWMODE=1","OK",50);
//Wifi模块重启
printf("send:AT+RST\r\n");
esp8266_send_cmd("AT+RST","OK",20);
delay_ms(1000); //延时3S等待重启成功
delay_ms(1000);
delay_ms(1000);
//设置连接到的WIFI网络名称/加密方式/密码,这几个参数需要根据您自己的路由器设置进行修改!!
printf("send:AT+CIPMUX=0\r\n");
esp8266_send_cmd("AT+CIPMUX=0","OK",20); //0:单连接,1:多连接
sprintf((char*)p,"AT+CWJAP=\"%s\",\"%s\"",wifista_ssid,wifista_password);//设置无线参数:ssid,密码
printf("send:AT+CWJAP=\"%s\",\"%s\"\r\n",wifista_ssid,wifista_password);
while(esp8266_send_cmd(p,"WIFI GOT IP",300)); //连接目标路由器,并且获得IP
myfree(SRAMIN,p);
}
这段代码和wifi初始化的分开,因为初始化代码只需要运行一次,而天气获取,是需要多次运行的。分开的话可以避免重复设置ESP8266的一些功能。
移植时需要更改的地方为代码中u3_printf中的私钥和地点。
本代码发送的AT指令有:
指令 | 回复 | 功能 |
---|---|---|
AT+CIPSTART=“TCP”,“api.seniverse.com”,80 | OK | 建立TCP连接 |
AT+CIPMODE=1 | OK | 开启通透模式 |
AT+CIPSEND | OK | 开始透传 |
GET https://api.seniverse.com/v3/weather/now.json?key=私钥&location=城市&language=zh-Hans&unit=c\n\n | 天气数据 | 提出请求 |
+++ | 退出透传 |
//获取一次实时天气
//返回:0---获取成功,1---获取失败
u8 get_current_weather(void)
{
u8 res;
p=mymalloc(SRAMIN,40); //申请40字节内存
sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",WEATHER_SERVERIP,WEATHER_PORTNUM); //配置目标TCP服务器
printf("send:AT+CIPSTART=\"TCP\",\"%s\",%s\r\n",WEATHER_SERVERIP,WEATHER_PORTNUM);
res = esp8266_send_cmd(p,"OK",200);//连接到目标TCP服务器
if(res==1)
{
myfree(SRAMIN,p);
return 1;
}
delay_ms(300);
printf("send:AT+CIPMODE=1\r\n");
esp8266_send_cmd("AT+CIPMODE=1","OK",100); //传输模式为:透传
USART3_RX_STA=0;
printf("send:AT+CIPSEND\r\n");
esp8266_send_cmd("AT+CIPSEND","OK",100); //开始透传
printf("start trans...\r\n");
u3_printf("GET https://api.seniverse.com/v3/weather/now.json?key=私钥&location=城市&language=zh-Hans&unit=c\n\n");
delay_ms(20);//延时20ms返回的是指令发送成功的状态
USART3_RX_STA=0; //清零串口3数据
delay_ms(1000);
if(USART3_RX_STA&0X8000) //此时再次接到一次数据,为天气的数据
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
}
printf("USART3_RX_BUF=%s\r\n",USART3_RX_BUF);
atk_8266_quit_trans();//退出透传
printf("send:AT+CIPCLOSE\r\n");
esp8266_send_cmd("AT+CIPCLOSE","OK",50); //关闭连接
myfree(SRAMIN,p);
return 0;
}
将代码烧入后,可在串口调试器中查看到接收到的状态信息以及天气数据。
当按下按键(PA0),可再次获取天气数据。
链接:
https://pan.baidu.com/s/1sd00hF-RVmsDbEoMfnqdBQ
提取码:sgek
传送门:
基于STM32的ESP8266天气时钟(1)---------AT指令获取天气数据
基于STM32的ESP8266天气时钟(2)--------MCU获取天气数据
基于STM32的ESP8266天气时钟(3)--------MCU数据处理及显示
基于STM32F的ESP8266天气时钟(4)--------MCU获取时间及显示(完结)