完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
近期由于某些原因,玩了一下stm32+WiFi获取网络天气和网络时间。之前一直觉得这个东西会有点难度,其实,做完了才发现,其实那只是想象中的难而已。现在,将这几天的成果分享一下,做个学习记录,也分享给有需要的伙伴。 在文末有改良好的代码,问题肯定是有的,但是比之前,好很多,有需要的朋友可以自己下载。 上面链接给的代码其实是有问题的,经过测试,发现三点不足: 1.RTC时钟,仅仅只是RTC时间; 2.程序运行一段时间后(三个小时内),100%会死机,因此基本可以判断出,程序是有问题的具体原因不详,貌似是堆栈溢出导致的; 3.天气更新情况,在没有死机的情况下,看似是在更新,其实从串口调试助手可以看到,人机交互界面并没有更新。 经过改善,满足了以下要求: 1.开机获取网络时间,之后将会由这个时间借助RTC继续运行; 2.在测试的三个小时内没有再出现死机的情况; 3.在测试的三个小时内,天气每隔一段时间都会自动更新,并体现在LCD屏幕上。 ** 一、测试要求(只说我用到的) ** 1.硬件: ①stm32f103ZET6(我用的战舰板,请用容量尽量大的模块) ②TFTLCD屏(我的是4.3寸) ③ESP8266 WIFI串口模块(串口3) ④Jlink(程序烧录) ⑤串口线 ⑥路由器 2.软件 ①keil5 ②串口调试助手 ** 二、相关设置 ** 这里就不做过多的介绍,只做简单的说明,有疑问请参考上面给出的链接。 ①WiFi串口模块固件为AT固件 ②jlink需要安装对应的驱动,用于程序的调试和烧录 ③串口也需要对应的驱动,用于输出调试信息 ** 三、程序流程 ** 其实简单点说,就几个步骤而已,我把他转换成几条AT指令,只需要按照下面步骤控制WiFi模块,就可以获取到网络天气和时间信息,如下: 1.首先来看看获取当前天气情况 ①AT ack:OK //判断WiFi模块是否存在以及是否支持AT指令 ②ATE0 ack: OK //取消回显,可要可不要,为了方便接下来演示,这句我就不写进去了 ③AT+CWMODE=1 ack:OK //设置WiFi模块为STA模式 ④AT+RST ack:OK //复位WiFi模块 ⑥AT+CIPMUX=0 ack:OK //单连接模式 ⑦AT+CWJAP=“HUAWEI nova 5”,“b12345678” ack:WIFI GOT IP //连接热点,对应的是热点名和热点密码,注意,务必等待该条指令返回WIFI GOT IP后再发送下面的指令 ⑧AT+CIPSTART=“TCP”,“api.seniverse.com”,80 ack:OK //建立TCP连接 ⑨AT+CIPMODE=1 ack:OK //透传模式 ⑩AT+CIPSEND ack:OK //AT+CIPMODE=1并且作为客户端模式下,进入透传模式(需要支持硬件流控,否则大量数据情况下会丢数据)模块收到指令后先换行返回”>”,然后会发送串口接收到的数据。 发送完上面的指令,并正确返回后,发送下面一串数据(不需要换行) GET https://api.seniverse.com/v3/weather/now.json?key=SWaCmu3LmzT_kS21g&location=changsha&language=zh-Hans&unit=c //发送获取天气信息的网址,记得前面的GET,不可少 最后,记得发送一条退出透传的指令,否则后面AT指令将无法发送: AT+CIPCLOSE ack:OK 为了方便大家查看,我保存了串口调试助手发送指令以及模块返回情况,如下图: 上图中,最后一行,就是发送指令联网后返回来的一串字符串,有些是乱码,乱码部分其实就是中文,只不多串口没有对应的协议,没办法解析而已。这一串就是当前天气情况,也是我们需要解析的部分,中文部分,我们是需要把它转换成utf8格式的(具体请看代码),整个解析过程代码(其实很简单的)如下: //解析当前天气 void parse_now_weather(void) { u16 i = 0,j = 0,line = 0; int len = 0; char gbkstr[50] = {0}; Now_Weather *weather_Structure = mymalloc(SRAMIN,sizeof(Now_Weather)); printf("jieshou->1dayjson = %srn",USART3_RX_BUF); for(i = 0; i < strlen((char *)USART3_RX_BUF); i++) { if(USART3_RX_BUF == 'n' && USART3_RX_BUF[i+1] == 'a' && USART3_RX_BUF[i+2] == 'm' && USART3_RX_BUF[i+3] == 'e') { while(USART3_RX_BUF[i+7] != '"') weather_Structure->m_CityName[j++] = USART3_RX_BUF[7+(i++)]; weather_Structure->m_CityName[j] = ' |