上一篇帖子介绍了体检界面实现过程,本篇介绍使用STM32H7B3I-DK开发板连接WiFi,并通过网站服务校时和获取天气。
本次作品UI共有两个页面,一个是体检界面,另一个是台历界面。这个台历界面计划显示时钟和当地天气情况。STM32H7B3I-DK开发板自带WiFi模块,计划采用WiFi联网同步时间,并通过高德天气接口获取天气信息。以下介绍设计过程。
一、熟悉WiFi模块
STM32H7B3I-DK开发板自带的WiFi模块为INVENTEK SYSTEMS的ISM43340_M4G_L44。该模块是一款嵌入式 2.4 和 5 GHz Wi-Fi 802.11 a/b/g/n、低功耗蓝牙 (BLE) 和蓝牙 4.0 模块。模块硬件包括一个赛普拉斯 CYW43340 Combo 无线IC、天线和一个带 1MB 闪存的 STM32F405 主处理器,支持 SPI 或 UART 主机接口。
Wi-Fi 模块无需操作系统,并集成了 TCP/IP 协议栈,只需简单的 AT 命令集即可为您的无线产品建立连接。该模块的表面贴装尺寸为 14.70mm x 34.22mm,具有完整的 FCC、IC 和 CE 模块认证。
该产品适用于低成本嵌入式无线应用,可为您的平台提供快速、简便、经济高效的 WiFi、蓝牙和 BLE 连接。
ISM43340_M4G_L44在开发板上的电路是这样的:
采用的SPI接口和MCU连接。
二、WiFi模块驱动程序编写
我从全网搜索实例程序,发现只有ST官方例程《ClockAndWeather》包含了这个模块的驱动,其他地方都没有找到太合适的。只好从这个例程下手研究。这个例程不支持STM32CubeMX,硬件部分是直接手工配置的,如下图:
要想和我的程序配套使用,最好还是做成STM32CubeMX自动配置的。我仔细研究了一下这个SPI初始化代码,然后在STM32CubeMX里面照着设置一番,然后就可以把这两个初始化函数中的内容注释掉了。具体配置如下。
如此配置好后,直接生成代码,就能和net_conf_es_wifi_spi.c这个文件里的驱动接口配合使用了。
除了配置SPI2接口,还要将用到的库代码移植一下。为了以后能和之前的体检代码整合,我用TouchGFX先建立了一个空的工程,然后参照例程《ClockAndWeather》里面调用的文件,把用到的文件都复制到新工程中,具体用到如下文件。
这些文件添加完成,改掉调用的一些小bug就可以连接WiFi路由器了。
我这里是魔改例程中的clock_weather_app.c文件,将其中部分代码注释掉,预先配置好路由器信息,如下图。
然后调用
int8_t WIFI_Connect(char *ssid, uint8_t *password, int32_t encryption )
WiFi连接函数,就可以连接WiFi路由器了,如果需要打印测试结果,需要提前配置好printf函数输出接口,这个在我上一篇帖子有介绍。具体的如下图。
三、网络校时
以前做网络校时程序,一般都是使用NTP客户端实现,但例程是采用http客户端连接worldtimeapi.org这个网站实现的。我读完代码后发现这个不但能获取时间,还能得到本地外网的IP地址,这个在后面读取天气还能用到,我就索性直接采用例程这个代码实现时间获取,同时还能得到外网IP。
我们从http获取到的JSON是这样的:
例程中使用int Get_Date_Time(char* date_time)这个函数连接服务器获取JSON数据段,然后调用jsmn进行解析,其中重点在解析字段,我在原来的基础上增加IP地址解析。
解析完的时间信息直接存入RTC模块,用于时钟计时。IP地址信息存到了一个全局变量,用于接下来获取天气地点信息。
以上就通过联网把时钟校准好了,需要用到时钟数据,只需调用:
HAL_RTC_GetTime(&hrtc,&RTC_Time,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc,&RTC_Date,RTC_FORMAT_BIN);
这两个函数就行。具体的可以参考附件完整项目代码。
四、获取天气信息
示例程序获取天气信息采用的是国外的服务器,做的功能比较多,但是对中国的城市支持比较少,以前我申请了高德接口的API KEY,这里我还是采用高德接口。
具体流程是这样的:先用IP地址获取当前的城市地址信息,然后用地址信息里面的adcode码获取天气信息,此时获取的天气信息是采用UTF-8格式编码的,最后需要转码成GBK格式,才能显示后打印出来。
获取adcode码的JSON字段比较固定,我就没有采用jsmn进行解析,直接截取字符串就搞定了,如下。
获取天气信息时,主要功夫花费在UTF-8转GBK码上面了。开始的没注意到获取到的是UTF-8码,直接打印出来是乱码,幸好IAR支持UTF-8码,调试查看内存信息,可以直接显示中文,发现一个汉字对应3个字节,才发现编码问题。
然后通过网络一通查找转码示例,最后锁定GitHub上一个例程:
感觉这个比较清晰简单,没有过多依赖库。
转换需要两步,先是sconv_utf8_to_unicode,然后sconv_unicode_to_gbk,才能实现,不能一次搞定。这个实例是采用查表方式实现的,一定记得要把表格那两个数组设成const格式,不然会放在RAM中,编译不通过。
各部分都调整好后,使用如下代码进行测试。
结果如下,可以看到,能够正常获取时间,IP地址,adcode码,天气。
这个WiFi调试过程中还是有很多沟沟坎坎的,帖子里面不能尽数说明,我把最终调好的工程代码附上,以供需要的人测评。
代码.zip
(83.86 MB)
(下载次数: 1, 2023-12-10 22:49 上传)
本帖最后由 sipower 于 2023-12-10 22:49 编辑