lvgl

lvgl

目录

lvgl

Lvgl移植到STM32

-- 1、下载LVGL源码

-- 2、将必要文件复制到工程目录

-- 3、修改配置文件

将lvgl与底层屏幕结合到一块

-- lvgl也需要有定时器,专门给自己做了一个函数,告诉lvgl经过了多长时间(ms(毫秒)级别)

编写代码

lvgl的中文教程手册网站

lvgl的基础知识

-- 重点是lvgl基础控件的使用

-- 如何用lvgl去制作软件

更改错误

-- 8、只要使用汉字,都按照下面这种方式修改

屏幕显示调用

如何实现界面刷新(界面中的数据如何变化)

总结


  • 主要用于界面设计

-- 我们在做的项目是空气质量检测仪,下面这些是项目在开发阶段分的模块

  • 分为项目硬件,项目软件,项目结构(产品外壳),UI(界面设计),APP,测试

-- 对于界面开发,有很多,如qt,但是qt开发出来的程序比较大,占用内存比较多,所以选择了lvgl

-- GUI:LVGL,emwin,qt,touchgfx,minigui,simplegui(嵌入式开发阶段的界面开发工具)


-- LVGL(轻巧而多功能的图形库)是一个免费的开放源代码图形库,它提供创建具有易于使用的图形元素,精美的视觉效果和低内存占用的嵌入式GUI所需的一切。

  • Lvgl官网:LVGL — Light and Versatile Embedded Graphics Library
  • Lvgl官方文档:LVGL: Light and Versatile Graphics Library — LVGL documentation
  • Lvgl源码网址:https://github.com/lvgl/lvgl

-- lvgl官方网站 

alt text


-- 硬件要求:
基本上,每个现代控制器(肯定必须要能够驱动显示器)都适合运行LVGL。LVGL的最低运行要求很低: 16、32或64位微控制器或处理器
最低 16 MHz 时钟频率
Flash/ROM::对于非常重要的组件要求 >64 kB(建议 > 180 kB)

-- Lvgl系统框架

alt text

-- 应用程序创建 GUI 并处理特定任务的应用程序。 -- LVGL 本身是一个图形库。我们的应用程序通过调用 LVGL 库来创建 GUI 。它包含一个 HAL (硬件抽象层)接口,用于注册显示和输入设备驱动程序。 驱动程序除特定的驱动程序外,它还有其他的功能,可驱动显示器到 GPU (可选)、读取触摸板或按钮的输入。

Lvgl移植到STM32

-- 1、下载LVGL源码
  • 我们使用的是Lvgl7.11版本,因此在Github上找到对应版本源码下载:https://github.com/lvgl/lvgl/tree/v7.11.0

alt text

-- 其中lvgl/src文件夹内存放的是LVGL的核心源码,lvgl/examples/porting文件夹内存放的是lvgl与底层的接口函数,这些函数需要我们根据自己的项目进行修改。

-- 源码在文件夹中可以找到

alt text

-- 2、将必要文件复制到工程目录

-- 1、在个人的工程目录下创建一个名为Lvgl的文件夹,并将lvgl/src目录复制到Lvgl目录下,将lvgl/examples/porting文件夹复制到Lvgl目录下,同时将lvgl/lvgl.h文件以及lvgl/lv_conf_template.h文件复制到Lvgl目录下。如下图所示:

alt text

-- 2、将lv_conf_template.h文件更名为lv_conf.h,如下图所示:

alt text

-- 3、修改port目录下所需要的文件名字,我们只使用了屏幕的显示功能,因此我们只修改显示接口的文件名字,将lv_port_disp_template.c/.h更名为lv_port_disp.c/.h如下图所示:

alt text

alt text

-- 4、在Lvgl目录下再创建一个app目录,用于存放我们后期自己写的应用层界面代码,具体操作如下图所示:

alt text

alt text

-- 5、打开工程,在工程目录下新建三个分组,分别为Lvgl/app、Lvgl/porting、Lvgl/src三个目录,具体操作如下图所示:

alt text

-- 6、添加文件到工程目录中,porting目录下只添加lv_port_disp.c,以及Lvgl目录下的lv_conf.h文件,这两个文件后面需要修改。 

alt text

 在src目录下,添加Lvgl/src目录下除去gpu文件夹外的所有文件夹内的c文件。

alt text

-- 7、配置头文件路径,把Lvgl文件夹下所有包含h文件的路径,在工程属性中进行配置,具体操作如下图: 

alt text

-- 3、修改配置文件

-- 1、打开lv_port_disp.c/.h文件,修改如下内容

alt text

alt text

-- 2、修改lv_conf.h文件如下图所示,修改后编译代码,这个时候代码就没有错误了。

alt text

-- 3、接下来适配屏幕接口到lvgl上,先修改lv_conf.h内的宏定义,通过它可以设置库的基本行为,裁剪不需要模块和功能,在编译时调整内存缓冲区的大小等等,我们先修改一些必须修改的定义,后期的功能我们在具体项目中再做裁剪。

alt text

-- 注:

-- 竖屏和横屏可以自己选择

alt text

-- 更改单片机分给lvgl的空间大小 

alt text

-- 是否要适配v6版本,我们这里选择v7版本,就不适配v6了,将宏定义改为0 

alt text

将lvgl与底层屏幕结合到一块

-- 更改初始化函数,进入初始化函数中

alt text

-- 将lcd初始化加进来,以后就不用lcd初始化了,直接调用lvgl的初始化函数即可

alt text

-- 绘制缓冲区,屏蔽其他两种方法

alt text

-- 更改参数

alt text

-- 找到lcd中的指定区域内填充指定颜色快的函数

alt text

-- 并在.h中声明

alt text

-- 将lv_port_disp.c中的函数进行修改

alt text

-- lvgl也需要有定时器,专门给自己做了一个函数,告诉lvgl经过了多长时间(ms(毫秒)级别)
  • 先将操作系统中的宏定义改变 

    alt text

  • 我们要写一个时钟节拍钩子函数 

    alt text

  • 参考我们之前写的任务栈溢出函数

alt text

编写代码

-- 创建任务句柄

TaskHandle_t xLvglTaskHandle = NULL;

-- 创建任务主题函数

void vLvglTaskFunction( void * pvParameters )
{
	TickType_t xLastWakeTime;
	const TickType_t xPeriod = pdMS_TO_TICKS( 5 );//5ms的延时
	xLastWakeTime = xTaskGetTickCount();  
	for(;;)
	{		
		lv_task_handler();//在裸机里放在while循环中即可
		vTaskDelayUntil( &xLastWakeTime, xPeriod );//绝对延时
	}
}

-- 创建任务(放在main函数中)

			
		xTaskCreate(vLvglTaskFunction, "lvgl_task", 512, NULL, 2, &xLvglTaskHandle);

-- 启动任务


if(xReturn == pdPASS)
					vTaskStartScheduler();//任务调度器			//当程序执行完这句话之后,正常情况下下面的代码不会再运行,只会运行任务主题函数

-- 上述内容我们就已经成功配置了lvgl的环境,下面我们写入一个测试代码,看看是否能够正常显示。写在初始化函数后面即可。

alt text

-- 完整代码

#include "lvgl.h"
#include "lv_port_disp.h"

TaskHandle_t xLvglTaskHandle = NULL;

void vLvglTaskFunction( void * pvParameters )
{
	TickType_t xLastWakeTime;
	const TickType_t xPeriod = pdMS_TO_TICKS( 5 );//5ms的延时
	xLastWakeTime = xTaskGetTickCount();  
	for(;;)
	{		
		lv_task_handler();//在裸机里放在while循环中即可
		vTaskDelayUntil( &xLastWakeTime, xPeriod );//绝对延时
	}
}


int main(void)
{

    lv_init();
	lv_port_disp_init();

	//测试代码--显示一个label
	lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
	lv_label_set_long_mode(label1, LV_LABEL_LONG_BREAK);     
	lv_label_set_recolor(label1, true);                      
	lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER);
	lv_label_set_text(label1, "#0000ff Re-color# #ff00ff words# #ff0000 of a# label "
																										"and  wrap long text automatically.");
	lv_obj_set_width(label1, 150);
	lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, -30);

    BaseType_t xReturn  = pdPASS;

    xTaskCreate(vLvglTaskFunction, "lvgl_task", 512, NULL, 2, &xLvglTaskHandle);
    //xTaskCreate(arc_loader, "lvgl_task", 512, NULL, 2, &xLvglTaskHandle);
            
    if(xReturn == pdPASS)
                vTaskStartScheduler();//任务调度器			//当程序执行完这句话之后,正常情况下下面的代码不会再运行,只会运行任务主题函数
}

-- 注意:这里用了lvgl的初始化函数,不用再用lcd的初始化了,前面已经把lcd初始化函数写在了lvgl的初始化函数里面了。

-- 测试效果图

alt text

lvgl的中文教程手册网站

-- 该网站包含各种事例代码和图形库

-- 英文 Layers — LVGL documentation

-- 中文 基础对象(lv_obj) — 百问网LVGL中文教程手册文档 1.0 文档

alt text

lvgl的基础知识

-- lvgl是一个图形库

-- 那么什么叫做图形库呢?

alt text

-- 这些就是一个一个的图形

-- 每个图形又可以称为对象

alt text

-- 对象的属性:假如要绘制一个仪表盘,那么他的大小设置多大,位置放在哪里。能不能拖动呢?是否被拖动?

alt text

-- 对象的层级:父子,小介面基于大介面的基础上创建出来的,例如在大介面上点击一个按钮导致小介面生成。

alt text

-- 事件:点击,拖动,长按,松开,滚动等等

alt text

-- 这个事件怎么处理呢?

  • 当事件发生时,lvgl会跟根据提前定义好的回调函数进行处理,回调函数可以自己定义,也可以使用lvgl提供的回调函数。

  • 不同的对象所对应的事件也不同

alt text

-- 还有特殊的事件,键盘或者事件编码

alt text

-- 输入设备:触摸屏,键盘,鼠标,编码器等等

alt text

-- 显示:

-- 字体:LVGL 支持 UTF-8 编码的 Unicode 字符。需要配置的编辑器,以将的代码/文本保存为 UTF-8 (通常是默认值)

-- 在lvgl里面,只要显示汉字,一定要在UTF-8格式下写汉字

alt text

-- lvgl是有自己的一个操作系统的,只是目前我们还没有使用

-- 重点是lvgl基础控件的使用

-- 例子:圆弧展示进度条

alt text

alt text

-- 首先将代码复制到咱们的程序里面

static void arc_loader(lv_task_t * t)
    {
            static int16_t a = 270;

            a+=5;

            lv_arc_set_end_angle(t->user_data, a);

            if(a >= 270 + 360) {
                    lv_task_del(t);
                    return;
            }
    }

int main()
{

    lv_init();
	lv_port_disp_init();

    //显示一个圆弧(进度条)
/*Create an Arc*/
    lv_obj_t * arc = lv_arc_create(lv_scr_act(), NULL);
    lv_arc_set_bg_angles(arc, 0, 360);
    lv_arc_set_angles(arc, 270, 270);
// lv_obj_align(arc, NULL, LV_ALIGN_CENTER, 0, 0);//改变了对象的位置
    lv_obj_set_pos(arc,20,60);//设置起点位置
    lv_obj_set_size(arc,200,200);//设置对象大小

    /* Create an `lv_task` to update the arc.
* Store the `arc` in the user data*/
    lv_task_create(arc_loader, 20, LV_TASK_PRIO_LOWEST, arc);
	
}

-- 结果图太小了,需要找个能改变自身大小的

alt text

  • 相关api

  • 设置位置

lv_obj_set_pos(arc,20,60);//设置起点位置
  • 设置对象大小
lv_obj_set_size(arc,200,200);//设置对象大小

-- 至此就可以添加一个圆弧图形了,但是这个圆弧是静态的,需要添加一个定时器,让圆弧动起来。所以前面写的时钟钩子函数就可以派上用场了。

-- 如何用lvgl去制作软件

-- 安装软件

-- 1、先安装Java环境(注意一定要先安装java环境)

alt text

-- 2、安装软件

alt text

-- 3、打开软件,点击创建,选择v7

-- 4、工程的名字和路径都不能出现中文,屏幕的类型如果选项中没有的话,可以自己定义

alt text

-- 5、创建成功后,会跳转新的界面,将右上角英文切换成中文,界面的颜色也可以选择,可以改为深蓝色或者其他颜色

-- 6、可以先选择一个图片当作背景,将图片拖拽过来,可以通过更改参数让它显示在全屏

alt text

alt text

-- 7、新增界面 

alt text

-- 8、可以更改背景的颜色

alt text

-- 9、也可以更改图片的透明度,255是不透明,0是完全透明

alt text

-- 10、设置文本

alt text

alt text

-- 11、将表格拖进界面

alt text

alt text

-- 12、有些是不能用的 

alt text

-- 13、将图形界面设计完之后,点击编译,编译成功后就会将配置好的界面显示出来

alt text

-- 14、注意:这个编译默认编译的是第一个界面,如果向编译其他界面。

alt text

-- 都编译成功后,开始将代码放到工程中

-- 15、先找到工程所在地方

alt text

-- 16、

alt text

alt text

-- 17、了解这些文件的作用

alt text

alt text

-- 18、在工程中新建文件夹

alt text

-- 19、添加头文件路径

alt text

-- 20、之后编译,出现错误 

alt text

更改错误

-- 1、修改界面文件

alt text

alt text

-- 2、更改图模文件

alt text

-- 3、更改字模文件

alt text

-- 4、修改系统自带文件

alt text

alt text

alt text

alt text

-- 5、之后编译,然后有的电脑还会出现错误,有的没有

alt text

-- 6、添加一个定义

alt text

-- 7、修改错误,一般就是中文汉字编码的错误

alt text

  • 只要有汉字,就会报两个错
-- 8、只要使用汉字,都按照下面这种方式修改

-- 解决方案一:显示的字符串,最后不能以汉字结束。在字符串结束,加一个空格

  • 点击错误跳转到出错的地方,将字符串最后加一个空格
  • 其中这个摄氏度就是中文的。

alt text

-- 解决方案二:将keil的编码格式修改为utf-8,然后在这种编码格式下重新输入汉字

alt text

-- 然后在这个格式下重新输入汉字,为了保险起见,后面也加上空格

屏幕显示调用

-- 将代码复制到main函数中

alt text

-- 加上头文件

alt text

-- 这两个代码分别是创建和显示

alt text

-- 只有创建函数的话,只会创建,创建完之后不会显示

alt text

-- 要想在屏幕中显示,必须要调用显示函数

alt text

-- 此时显示的界面是screen1,如果想要显示其他界面,如screen,只需要将screen1改为screen即可

alt text

-- 但是如果两个显示函数都调用的话,只会显示后面调用的那个

-- 那么如何实现切换界面

  • 1、将创建函数写在main函数中

alt text

  • 2、然后在按键任务中调用显示函数

alt text

  • 3、加一个标志位,防止多次点击同一按键,导致界面反复切换同一个界面无意义

alt text

  • 3、代码
uint8_t GUI_flag = 0;
//2
void KETTaskCreat(void *pvParameters)
{
	uint8_t keyflag = 0;
	uint8_t buff[10]={0};
    while(1)
    {
				keyflag = get_key();
				switch(keyflag)
				{
					case 1:
						
					
						if(GUI_flag!=2)
						{
								lv_scr_load(guider_ui.screen);	//显示
							GUI_flag=2;
						}

					break;
					case 2: 

					if(GUI_flag!=1)
					{
						GUI_flag =1;
						lv_scr_load(guider_ui.screen_1);	//显示
					}
					break;
				}  
			vTaskDelay(50);				//在任务周期时可以释放cpu
    }
}

如何实现界面刷新(界面中的数据如何变化)

-- 1、实现文本数据刷新

-- 要想实现数据更新,必须要找到对应的对象,然后调用对应的赋值函数

-- 例如界面一的温度数值,先找到界面一对应的赋值函数,复制

alt text

-- 将函数复制到lcd显示任务函数中,直接将数值更改为变量,就可以实现动态更新数值了。

alt text

void LCDTaskCreat(void *pvParameters)//函数名称不固定,参数格式是固定的(任务一定是一个while循环,每个任务一定要有自己的任务周期)//设置任务周期的目的就是可以让任务可以主动释放cpu(指的是任务能够自动释放cpu)
{
	//BaseType_t xReturn = pdPASS;//有没有获取成功,再显示LCD
	EventBits_t r_event;
	while(1)
	{
		r_event = xEventGroupWaitBits(Event_Handle, /* 事件对象句柄 */
																	0x07,/* 接收任务感兴趣的事件 */
																	pdTRUE,/* 退出时清除事件位 */
																	pdFALSE,/* 满足感兴趣的所有事件 *///逻辑或
																	500);/* 指定超时事件,一直等 */
		//dht
		if(r_event &(0x1<<0))//判断这个数中的位0是否为真
		{

			sprintf(D_wen, "tem: %.2d鈩?",(int)dht.tem);
			
			 //实现数据更新
                        
       //找到对应对象的赋值函数
			
			lv_label_set_text(guider_ui.screen_1_label_1, D_wen);
			
		}

    }
    }

-- 2、实现表格数据刷新(折线图)

-- 找到对应的赋值函数

alt text

-- 在lcd函数中调用

alt text

将值改为变量

-- 效果图

alt text

总结

-- 1、进行界面设计,注意先考虑好布局(做几个界面,每个界面显示什么内容,如何规划)

-- 2、保证每个界面在屏幕上都能显示出来

-- 3、保证界面相互切换不会卡死

-- 4、界面刷新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/900556.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第三十篇:TCP连接断开过程,从底层说明白,TCP系列五

上一篇《第二十九篇&#xff1a;图解TCP三次握手&#xff0c;看过不会忘&#xff0c;从底层说清楚&#xff0c;TCP系列四》说了TCP的三次握手&#xff0c;接下来我将讲解TCP四次挥手。 既然有连接就有断开&#xff0c;谈到这里&#xff0c;有的同学可能会想&#xff0c;不就是…

log4j 和 logback 冲突解决

很多springboot starter自带logback 如果我们要用log4j就要把logback排除掉 点idea的maven侧栏工具的分析依赖关系 然后我们要选中我们有冲突的模块&#xff0c;搜索logback 这时候我们发现有logback相关的依赖&#xff0c;在点一下&#xff0c;我们就在右边发现&#xff0c;原…

STM32--I2C通信

对于I2C通信会分为两大块来讲解&#xff0c;第一块,就是介绍协议规则,然后用软件模拟的形式来实现协议&#xff0c;第二块,就是介绍STM32的12C外设,然后用硬件来实现协议&#xff0c;因为12C是同步时序,软件模拟协议也非常方便。 在学12C之前,我们已经学习了串口通信&#xff…

openlayers 封装加载本地geojson数据 - vue3

Geojson数据是矢量数据&#xff0c;主要是点、线、面数据集合 Geojson数据获取&#xff1a;DataV.GeoAtlas地理小工具系列 实现代码如下&#xff1a; import {ref,toRaw} from vue; import { Vector as VectorLayer } from ol/layer.js; import { Vector as VectorSource } fr…

蓄电池在线监测系统 各大UPS铅酸蓄电池监测 保障安全

蓄电池的不断普及&#xff0c;确实推动了蓄电池监控和管理技术的持续升级。蓄电池检测系统的研发为我们带来了诸多好处&#xff0c;这些好处主要体现在以下几个方面&#xff1a; 一、提高蓄电池管理的智能化水平 蓄电池检测系统通过实时监测蓄电池的电压、电流、温度等关键参数…

ZEISS ATOS Q蓝光三维扫描仪高效把控零件质量检测【上海沪敖3D】

位于Bengaluru的施耐德电气工厂拥有一流的计量设备&#xff0c;可以检测所有供应商的零件。当时&#xff0c;他们在使用一款激光扫描设备进行质量检测&#xff0c;但是&#xff0c;该设备不便于携带&#xff0c;且检测时需要喷涂大量的显影液。此外&#xff0c;它需要被安装在夹…

docker基础使用创建固定硬盘大小为40G的虚拟机

在docker中创建的服务器&#xff0c;匹配出容器id&#xff0c;服务器ip&#xff0c;服务器核数&#xff0c;服务器内存&#xff0c;服务器硬盘空间 for i in $(docker ps | grep -aiE web | awk {print $1});do echo $i; docker inspect $i|grep -aiE ipaddr|tail -1|grep -ai…

医院信息化与智能化系统(7)

医院信息化与智能化系统(7) 这里只描述对应过程&#xff0c;和可能遇到的问题及解决办法以及对应的参考链接&#xff0c;并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图&#xff0c;可以试试PlantUML&#xff0c;告诉GPT你的文件结构&#xff0c;让他给你对应的…

最新PHP网盘搜索引擎系统源码 附教程

最新PHP网盘搜索引擎系统源码 附教程&#xff0c;这是一个基于thinkphp5.1MySQL开发的网盘搜索引擎&#xff0c;可以批量导入各大网盘链接&#xff0c;例如百度网盘、阿里云盘、夸克网盘等。 功能特点&#xff1a;网盘失效检测&#xff0c;后台管理功能&#xff0c;网盘链接管…

使用freemarker实现在线展示文档功能开发,包括数据填充

首先&#xff0c;在这个独属于程序员节日的这一天&#xff0c;祝大家节日快乐【求职的能找到心仪的工作&#xff0c;已经工作的工资翻倍】。 ---------------------------------------------------------------回到正文-----------------------------------------------------…

状态栏黑底白字后如何实现圆角以及固定状态栏

如何实现如下效果: 上述是将状态栏实现黑底白字+圆角+状态栏固定的逻辑 具体代码patch如下: From 6a3b8ed5d3f49a38d8f9d3e488314a66ef5576b8 Mon Sep 17 00:00:00 2001 From: andrew.hu <andrew.hu@quectel.com> Date: Fri, 18 Oct 2024 16:43:49 +0800 Subject: [P…

Next.js14快速上手

文章目录 ***客户端***什么是Next项目在线地址官方文档项目创建查看项目目录结构app属于根目录 ***服务端***vercel数据库prisma 客户端 什么是Next Next.js 是一个用于构建全栈 Web 应用程序的 React 框架。您可以使用 React Components 来构建用户界面&#xff0c;并使用 Ne…

Unity引擎:游戏开发的核心力量

目录 引言 Unity引擎的发展历程 早期发展 跨平台支持 Unity引擎的核心特性 易用性 社区支持 跨平台能力 Unity在游戏开发中的应用 移动游戏 独立游戏 3A游戏 Unity的未来展望 高级图形和渲染技术 扩展现实&#xff08;XR&#xff09;支持 云服务和多人游戏 结论…

excel中,将时间戳(ms或s)转换成yyyy-MM-dd hh:mm.ss或毫秒格式

问题 在一些输出为时间戳的文本中&#xff0c;按照某种格式显示更便于查看。 如下&#xff0c;第一列为时间戳(s)&#xff0c;第二列是转换后的格式。 解决方案&#xff1a; 在公式输入框中输入&#xff1a;yyyy/mm/dd hh:mm:ss TEXT((A18*3600)/8640070*36519, "yyy…

Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks

Abstract 图像到图像转换是一类视觉和图形问题&#xff0c;其目标是使用对齐图像对的训练集来学习输入图像和输出图像之间的映射。 然而&#xff0c;对于许多任务&#xff0c;配对训练数据将不可用。 我们提出了一种在没有配对示例的情况下学习将图像从源域 X 转换到目标域 Y …

Android 15自定义设置导航栏与状态栏,EdgeToEdge适配

背景&#xff1a;android api 35&#xff0c;activity设置EdgeToEdge.enable((ComponentActivity) this)前提下 一、设置导航栏与状态栏颜色 设置的状态栏颜色&#xff0c;只需要设置fitsSystemWindows跟setOnApplyWindowInsetsListener xml设置&#xff1a; 代码&#xff1a;…

没有AWS账号能不能在手机上使用AWS服务吗?

关于“没有AWS账号能不能在手机上使用AWS服务”这个问题&#xff0c;答案是不行的。要使用AWS&#xff08;亚马逊云服务&#xff09;提供的云服务&#xff0c;无论是在电脑还是手机上&#xff0c;都必须先创建一个AWS账号。AWS提供的各种云计算资源&#xff0c;比如EC2&#xf…

51单片机——OLED显示图片

取模软件&#xff1a;链接:https://pan.baidu.com/s/1UcrbS7nU4bsawNxsaaULfQ 提取码:gclc 1、如果图片大小和格式不合适&#xff0c;可以先用Img2Lcd软件进行调整图片大小&#xff0c;一般取模软件使用的是.bmp图片&#xff0c;可以进行输出.bmp格式。软件界面如下&#xff1…

ubuntu编译kaldi和vosk

文章目录 前言一、开源框架的选取二、kaldi编译三、编译vosk方案一方案二 前言 由于工作需要语音识别的功能&#xff0c;环境是在linux arm版上&#xff0c;所以想先在ubuntu上跑起来看一看&#xff0c;就找了一下语音识别的开源框架&#xff0c;选中了vosk这个开源库&#xf…

java控制台打印乘法口诀表

目录 前言具体代码完整代码 前言 背乘法口诀表我没记错话&#xff0c;应该是我们在上小学二年级的时候&#xff0c;相信大家对乘法表相当熟悉&#xff0c;那你知道如何用java打印这个漂亮的表吗&#xff1f;下面咱们一起来学习学习。 具体代码 数字乘法表 关键代码&#xf…