单片机---HLK-W801图形框架LVGL下开发(四)

前文回顾

《单片机—HLK-W801并口驱动ST7789》
《单片机—HLK-W801驱动触摸屏》
《单片机—HLK-W801图形框架LVGL移植》
《单片机—HLK-W801图形框架LVGL下开发(一)》
《单片机—HLK-W801图形框架LVGL下开发(二)》
《单片机—HLK-W801图形框架LVGL下开发(三)》

2022年3月24日效果,增加了汉化,APP包括温湿度,计算器,wifi连接,在wifi连接状态下,能够进行NTP时间同步及查询天气。

海凌科w801开发的单片机主机

本章重点

之前的版本,说是在w801下开发,也只是硬件是w801,而软件依旧用的是w806的代码框架,原因还是w806的代码框架逻辑十分清晰,使用起来也简单明了。
不过经过一天的奋战,还是将所有部分都移植到了w801的代码框架上了,为的就是能上网啊。
真是年轻人为了上网,啥都做得出来
单片机---HLK-W801图形框架LVGL下开发(四)_第1张图片

最新版本LVGL移植

还是简单的步骤,将源码和头文件放在到工程中,我放在了src下的app中
单片机---HLK-W801图形框架LVGL下开发(四)_第2张图片
然后就是编译,可能会报一些函数引用的问题,调整下头文件包含的顺序即可。别问我为什么调整一下就可以,这是我多年工作经验出来的结果。
单片机---HLK-W801图形框架LVGL下开发(四)_第3张图片

屏幕驱动

我用的是ST7789的并口屏幕,配合的是SPI的触摸屏接口。移植部分前面介绍过,是在w806上,在w801上,主要就是一个写并口的操作,这个在demo中并没有,所以还是通过修改单个gpio的方式,分析出了写8080并口的方式。

下面是关键的并口写入方式。

void P_WRITE_B0_B15(uint16_t data )
{
		u32 cpu_sr = 0;
		u32 reg;
		u32	reg_en;
		u32	setval=0;
	
		cpu_sr = tls_os_set_critical();
		
		reg_en = tls_reg_read32(HR_GPIO_DATA_EN + TLS_IO_AB_OFFSET);
		tls_reg_write32(HR_GPIO_DATA_EN + TLS_IO_AB_OFFSET, reg_en | P_DATA_PIN);

		reg = tls_reg_read32(HR_GPIO_DATA + TLS_IO_AB_OFFSET);
		setval=reg&0xFFFF0000;
		tls_reg_write32(HR_GPIO_DATA + TLS_IO_AB_OFFSET, setval | data);
	    tls_reg_write32(HR_GPIO_DATA_EN + TLS_IO_AB_OFFSET, reg_en);

		tls_os_release_critical(cpu_sr);
}

其他部分继续参考《单片机—HLK-W801并口驱动ST7789》即可

触摸屏

这里的移植没有什么区别,就是替换一下原来文档中的GPIO的操作。
继续参考《单片机—HLK-W801驱动触摸屏》

Port层代码

这部分几乎还是没有变化,继续参考《单片机—HLK-W801图形框架LVGL移植》
单片机---HLK-W801图形框架LVGL下开发(四)_第4张图片

主页功能

这里介绍一下我制作的这个主页
单片机---HLK-W801图形框架LVGL下开发(四)_第5张图片
其实就是简单的时钟,配合几个button,实现了一个类似桌面菜单的功能,这里值得学习的一点,就是关于win空间的使用,每个简单功能,可以理解为一个app,都是在一个win上面实现了,在点击一个button的时候,会先关闭桌面,释放桌面的资源,包括定时任务,然后启用一个新的win来绘制所有的app内容。退出的时候,也是类似,释放所有资源,然后再重新绘制桌面。
这样才能在单片机这种资源比较少的设备上创建这种多个app的桌面。
资源紧张,就得省着用啊
单片机---HLK-W801图形框架LVGL下开发(四)_第6张图片

WIFI联网

这里才是移植到w801上的最重要的目的。首先绘制了一个页面用来填写ssid和密码
单片机---HLK-W801图形框架LVGL下开发(四)_第7张图片
这个空间在官方的例子中就能找到。
然后再点击确认的时候,调用官方wifidemo的接口就可以联网,并且稍微做个小弹窗,就知道wifi是否连接成功了。
单片机---HLK-W801图形框架LVGL下开发(四)_第8张图片

下面是核心代码。

static void con_net_status_changed_event(u8 status )
{
    switch(status)
    {
    case NETIF_WIFI_JOIN_SUCCESS:
    	{
			mbox1 = lv_msgbox_create(NULL, "", "WIFI JOIN SUCCESS", NULL, true);
    		lv_obj_center(mbox1);
			wifi_on=true;
    	}
        break;
    case NETIF_WIFI_JOIN_FAILED:
    	{
			mbox1 = lv_msgbox_create(NULL, "", "WIFI JOIN FAILED", NULL, true);
    		lv_obj_center(mbox1);
			wifi_on=false;
       	}
	   	break;
    case NETIF_WIFI_DISCONNECTED:
       	{
			mbox1 = lv_msgbox_create(NULL, "", "WIFI DISCONNECTED", NULL, true);
    		lv_obj_center(mbox1);
			wifi_on=false;
        }
		break;
    case NETIF_IP_NET_UP:
    {
        struct tls_ethif *tmpethif = tls_netif_get_ethif();
		ip_addr_t *ip=&tmpethif->ip_addr;

	 	sprintf(wifi_ip,"%d.%d.%d.%d", ip4_addr1(ip_2_ip4(ip)),ip4_addr2(ip_2_ip4(ip)), ip4_addr3(ip_2_ip4(ip)), ip4_addr4(ip_2_ip4(ip)));	
		printf("wifi_ip:%s\n",wifi_ip);
#if TLS_CONFIG_IPV6
        print_ipaddr(&tmpethif->ip6_addr[0]);
        print_ipaddr(&tmpethif->ip6_addr[1]);
        print_ipaddr(&tmpethif->ip6_addr[2]);
#endif
    }
    break;
    default:
        //printf("UNKONWN STATE:%d\n", status);
        break;
    }
}

int demo_connect_net(char *ssid, char *pwd)
{
    struct tls_param_ip *ip_param = NULL;
    u8 wireless_protocol = 0;

    if (!ssid)
    {
        return WM_FAILED;
    }

    printf("ssid:%s\n", ssid);
    printf("password:%s\n", pwd);
    tls_wifi_disconnect();

    tls_param_get(TLS_PARAM_ID_WPROTOCOL, (void *) &wireless_protocol, TRUE);
    if (TLS_PARAM_IEEE80211_INFRA != wireless_protocol)
    {
        tls_wifi_softap_destroy();
        wireless_protocol = TLS_PARAM_IEEE80211_INFRA;
        tls_param_set(TLS_PARAM_ID_WPROTOCOL, (void *) &wireless_protocol, FALSE);
    }

    tls_wifi_set_oneshot_flag(0);

    ip_param = tls_mem_alloc(sizeof(struct tls_param_ip));
    if (ip_param)
    {
        tls_param_get(TLS_PARAM_ID_IP, ip_param, FALSE);
        ip_param->dhcp_enable = TRUE;
        tls_param_set(TLS_PARAM_ID_IP, ip_param, FALSE);
        tls_mem_free(ip_param);
    }

    tls_netif_add_status_event(con_net_status_changed_event);
    tls_wifi_connect((u8 *)ssid, strlen(ssid), (u8 *)pwd, strlen(pwd));
    printf("\nplease wait connect net......\n");

    return WM_SUCCESS;
}

NTP功能

前面的版本时间是手动设置,我们有了wifi,那自然是更希望联网对时了。界面就很简单,一个button就可以。
单片机---HLK-W801图形框架LVGL下开发(四)_第9张图片
点击的时候,参考demo中的ntp操作,并且设置到实时时钟rtc中,就完成了
单片机---HLK-W801图形框架LVGL下开发(四)_第10张图片

核心操作函数。

static void ntp_process(lv_event_t * e)
{
	lv_obj_t * mbox1=NULL;
	char resultntp[128]={0};
    unsigned int t;	
    struct tm *tblock;
    t = tls_ntp_client();

    tblock = localtime((const time_t *)&t);	//switch to local time
    tblock->tm_mon+=1;
    tls_set_rtc(tblock);
	sprintf(resultntp,"time:%d.%d.%d %02d:%02d:%02d",tblock->tm_year,tblock->tm_mon,tblock->tm_mday,tblock->tm_hour,tblock->tm_min,tblock->tm_sec);
	mbox1 = lv_msgbox_create(NULL, "", resultntp, NULL, true);
	lv_obj_center(mbox1);
}

天气预报

这里就是简单的自动调用web的客户端程序,参考demo,访问一个天气预报的接口,需要是http的,然后解析一下返回的数据即可。

我这里返回的数据是json格式,只取了天气那一项,然后显示到界面上就可以。
单片机---HLK-W801图形框架LVGL下开发(四)_第11张图片
简陋是简陋了点,不过道理就是这样
单片机---HLK-W801图形框架LVGL下开发(四)_第12张图片

注意事项

联网与不联网,可以通过记录在全局变量中,控制桌面不同的app出现,当wifi不连接的时候,我这里只显示本地的日期和时间设置,不显示NTP与天气预报
单片机---HLK-W801图形框架LVGL下开发(四)_第13张图片

当网络连接之后,才显示联网的设置,并且不再显示本地设置时间和日期
单片机---HLK-W801图形框架LVGL下开发(四)_第14张图片
并且在设置的操作之后,尽量要添加msg box来提示操作结果。

另外。这个w801的资源也比较紧张,之前还能放张老师的照片,现在只能黑屏当背景了

单片机---HLK-W801图形框架LVGL下开发(四)_第15张图片

介绍硬件

这个单片机的主机,其实就是一块HLK W801的主板,加了一个触摸显示屏做的,被我焊接了一下,因为杜邦线实在是太容易掉了,反正也没别的屏幕了,然后加了一个DHT11模块,就被我塞到一个牙线盒子里了,
单片机---HLK-W801图形框架LVGL下开发(四)_第16张图片
感兴趣的可以自己做一个。

单片机---HLK-W801图形框架LVGL下开发(四)_第17张图片

代码下载

虽然是提供《代码下载地址》,
不过按照前面的步骤,还是自己一步一步搞一下更有成就感。因为关键的点基本都说清楚了。
最重要一点,毕竟下载还要花钱。
单片机---HLK-W801图形框架LVGL下开发(四)_第18张图片

结束语

今天还是分享一些暖心的事情,毕竟生活还是烦心的事多,需要些温暖。
单片机---HLK-W801图形框架LVGL下开发(四)_第19张图片
单片机---HLK-W801图形框架LVGL下开发(四)_第20张图片
我跟我夫人说,我是一个没有远虑的人,如果眼前没有近忧,我就会觉得生活很快乐。小孩子也是这样,如果不是正在挨批评,他也永远都是快乐的。

你可能感兴趣的:(单片机,IOT,操作系统,lvgl,hlk-801,wifi,APP)