【例说Arm-2D界面设计】从不规则图标的显示说起

嵌入式资讯精选 2021-10-16 10:12


【说在前面的话】


Arm-2D是Arm公司为Cortex-M处理器平台量身打造的一款2D图形处理方案。针对已有的经典Cortex-M内核,诸如Cortex-M0/M0+/M3/M4/M7/M33等,Arm-2D提供了经过优化了的软件加速库——虽然在资源丰富的环境下,Arm-2D在这些传统处理器上无法与市面上各类GUI在同等条件下拉开性能差距,但在大部分GUI都无法覆盖的小资源处理器上,Arm-2D却提供了以极其低廉的手段实现智能手机级别GUI的可能性。当然更不用说在最新问世的Cortex-M55处理器上,借助Helium技术的加持,Arm-2D可以提供相较传统方案4倍以上的加速能力。

从这一系列文章开始,我将以范例的形式,一小步一小步的带领大家实现“从入门到精通”的跨越。每篇文章都不会追求内容的广度,但力求在一类具体的问题上为大家讲懂、讲透。

【前提和约定】

在开始今天的内容之前,为了让大家能站在一个较为统一的视角上看待问题,我觉得很有必要在出现因为立场不同而产生不必要的误解和争论之前,做出一些必要的约定:
  • 虽然Arm-2D本身同时支持资源丰富和资源受限的环境,但这一系列的文章主要从资源受限系统的角度出发做出设计上的考量

    • 目标处理器的系统频率在72MHz以内,覆盖从Cortex-M0到Cortex-M4F的处理器范围;

    • Flash的大小在128KByte以内;

    • SRAM的大小在4~32K的范围内;

    • 允许使用XIP将外部的SPI-FLASH映射到4G地址空间中

  • 目标应用场景主要为各类对动态效果没有要求的界面

    • 各类仪器仪表

    • 智能家居的控制面板

    • 手持设备的菜单界面

    • ……

  • 关于刷新率约定:

    • 当整个屏幕都进行完整刷新时,我们用 Frame-per-sec, FPS 来描述;

    • 当我们只刷新屏幕的局部时,我们用 Update-per-sec, UPS 来描述;

  • 目标应用场景在大部分情况下对帧率没有或只有较低的要求

    • 大部分情况下 1~3 FPS 即可满足要求

    • 部分场景下,在屏幕的局部可能会要求达到30 UPS的刷新率(比如动态进度条等等)

    • 在效果允许的情况下,尽可能减小 PFB的尺寸——在相同PFB面积的情况下,尽可能在确保Height不小于8时取Width所允许的最大值。

  • 本系列介绍的各类方法主要适用于无法负担起常规GUI协议栈(比如LVGL)的环境,如果您的条件允许,还是推荐直接使用常规GUI进行界面设计(这类GUI在底层仍然可以使用Arm-2D对一些算法进行加速)。

  • 本文假设读者已经完成了Arm-2D在本地平台的移植:

    • 如果您还没有完成这一步骤,请先移步《【教程更新】一网打尽Arm-2D的资料和傻瓜部署教程》

    • 如果您想跳过移植的步骤,直接进入Arm-2D的使用和学习环节,可以参考文章《懒人玩Arm-2D究竟有几种姿势》

      为了便于讲解,本文将主要使用 example 目录下的 [template][cmsis-rtos2][pfb] 模板作为起点。截图来自FastModel。

    • 因为我们主要考虑资源有限的环境,因此推荐使用 -Omin(或-Oz) 优化等级、开启 Link-Time-Optimisation、并使用microLib:



注意

当你使用 [template][cmsis-rtos2][pfb] 或 [template][bare-metal][pfb] 模板时,别忘记正确设置 Dirty Region List哦,否则你将永远只能看到屏幕中央一块 80*80 见方大小的区域。具体方法如下:

1、找到 main.c

2、在函数 display_task() 中找到以下内容:

void display_task(void){    ...//! call partial framebuffer helper servicewhile(arm_fsm_rt_cpl != arm_2d_helper_pfb_task(                                 &s_tExamplePFB,                                 (arm_2d_region_list_item_t *)s_tDirtyRegions));    ...}

3、将其修改为:

void display_task(void){    ...//! call partial framebuffer helper servicewhile(arm_fsm_rt_cpl != arm_2d_helper_pfb_task(                                 &s_tExamplePFB, NULL));    ...}

其本质是完全不使用Dirty Region List,从而迫使 PFB Helper服务完整的刷新整个屏幕。




【API的异步工作模式】


Arm-2D的API同时支持RTOS和裸机环境。

RTOS环境下,用户以异步的方式使用API——简单来理解,当用户调用API时,只是给后台的2D流水线下达了一个任务,且还未等任务执行完成就从函数已经退出了。任务的实际内容是在另外一个线程上来实现的。

在这种情况下,如果一个API要使用一些具有“时效性”的资源——比如某些局部变量,显然,就要把这些变量的生命周期考虑在内——不能只在调用API的时候内容有效,结果当另外一个线程实际干活的时候却发现对应的内容已经“物是人非”了。

为了解决这类问题,最无脑的方式就是在调用API后通过下面的函数来等待任务完成。
arm_2d_op_wait_async(NULL);
这里,arm_2d 是函数前缀,op是操作(operation)的缩写,wait_async 是等待异步任务完成(wait-asynchronous)的意思。至于括号里的NULL,说来话长,暂时就当做格式来记忆吧。

举个例子:
/*! \note arm_2d_align_centre generate a region '__centre_region' based *!       on the given target tile (frame buffer) and the size of the  *!       target area of your following drawing. *!       Use '__centre_region' when required as the target region in *!       2D operations inside the {...} . */ arm_2d_align_centre(tTempPanel, c_tileCMSISLogo.tRegion.tSize) {    //!< copy CMSIS logo (with masks) to the centre of the right panel    arm_2d_rgb565_tile_copy_with_masks(                                &c_tileCMSISLogo,                                &c_tileCMSISLogoMask,                                &tTempPanel,                                &c_tileFadeMask,                                &__centre_region,                               //!< generated by arm_2d_align_centre()
/*! remove ARM_2D_CP_MODE_FILL and only keeps *! mirroring mode */ ptLayers[0].wMode &~ ARM_2D_CP_MODE_FILL);
arm_2d_op_wait_async(NULL);}
上述例子中,arm_2d_align_centre()的作用是根据用户给定的目标显示缓冲区(比如tTempPanel)和区域大小(比如c_tileCMSISLogo.tRegion.tSize)生成一个能将给定大小的区域居中的arm_2d_region_t对象——局部变量 __centre_region——它的生命周期仅限于arm_2d_align_centre()后的花括号内。

姑且不论 arm_2d_rgb565_tile_copy_with_masks() 实际用 __centre_region 做了什么,但考虑到它的生命周期有限,因此必须在退出花括号之前调用 arm_2d_op_wait_async(NULL) 来等待操作完成。


虽然裸机环境下,所有arm-2d的API都是以同步模式来工作的(即退出API就意味着任务完成或者出现了错误),理论上的确完全无需arm_2d_op_wait_async(NULL)调用来实现所谓的同步,但以“异步工作模式”使用API写出来的代码拥有最高的兼容性——可以同时在RTOS环境和裸机环境下使用,因此,本系列文章统一以异步模式为蓝本来讲解后续的内容



【背景和命题】

随便打开一部手机或是平板电脑,我们就可以很容易的看到:在现代的界面设计中,圆角矩形是搭建界面所需的重要基础要素。无论是凸显面板上重要的区域(如下图所示):


(图片来自我自己iPad的截图)

还是作为图表的背景(如下图所示):


(图片资源来自网络:侵删)

很多情况下,我们都可以从目标控件中拆解出圆角矩形来:

(图片资源来自网络:侵删)
聪明的小伙伴很快会发现,其实借助贴图技术,只要我们事先规定好背景的颜色(比如黑色),再准备好对应控件的图片,那么无论你是圆角矩形还是普通四边形,其实都没有区别——直接进行像素级的拷贝即可——对应到Arm-2D的API就是 arm_2d_rgb565_tile_copy()。此前的文章《【Arm-2D】不整活儿玩啥GUI?》对具体的API和使用细节已经介绍的非常详细,这里就不再赘述了。

然而,上述方法的弊端也已经写的非常清楚,即:圆角矩形范围以外的部分不应该覆盖背景。这么说也许有些抽象,我们不妨以一个简单的例子加以说明。
已知一个白底的圆角矩形:


它其实保存在一个四方四正的像素数组里(红色边框是我加的,用来让指示范围更加清晰):



当目标背景的颜色也是白色时,复制该贴图,并无异样。就像你们现在看到的那样(假设您阅读本文时使用的是白色背景)。但假设背景是一个不同于白色的其它颜色,甚至是一个墙纸时:



使用直接贴图的方式,就会显露出它的弊端:


因为我们期望的效果是这样的:


简单说,就是我们希望圆角矩形的贴图中,原本背景的白色不是真正的白色,而是所谓的“透明色”:

也就是这里,红色边界范围内的“白色”应该是一种类似透明玻璃的颜色——目标背景是什么像素内容,这里就能“透过去”。


然而,“透明色”是一种不存在的颜色。在传统的RGB体系中,无论你是16bit的全彩色还是24bit的真彩色,都没有“透明色”的生存空间——每一个bit都被用来编码颜色还嫌不够呢。实际上“透明”不仅仅只有“全透明”这一种情况,还有以百分比计的透明度的概念——比如以下是25%、50%、75%透明的效果:


所以,透明度(Transparency)实际上是一类与颜色独立的信息,在传统的RGB体系中,往往会占用独立的通道来保存,如下图所示:

(图片来自维基百科:https://en.wikipedia.org/wiki/RGBA_color_model)

一个经典的 32位 ARGB32 颜色,实际上除了R、G、B三个颜色通道分别占用了一个字节外,还利用最高字节保存了一个所谓的Alpha通道——这个Alpha就是透明度相关的信息,只不过这里保存的不是透明度(Transparency),而是不透明度(Opacity):

  • Transparency:0表示完全不透明,255表示完全透明;

  • Opacity:0表示完全透明,255表示完全不透明。


此外,Alpha也并不固定的保存在最高字节,在不同的尾端下,Alpha通道也可能保存在最低字节——此时同样是32bit的RGB颜色体系,就被称为RGBA32:

(图片来自维基百科:https://en.wikipedia.org/wiki/RGBA_color_model)


搞清楚了上述原理后,我们实际上很容易发现,对实现各类圆角矩形来说,具体像素里的RGB部分其实我们并不关心——真正有用的是Alpha通道。一般来说,PNG格式是携带Alpha通道信息的常见格式。大量界面设计的素材也是以PNG来保存的。

那么Arm-2D是如何应对PNG类的图片素材的呢?

【神奇的Alpha-Mask】

前面我们提到,对常见的携带了Alpha通道的颜色格式来说,无论是ARGB32还是RGBA32,Alpha信息都是与RGB颜色信息放在一起的。如果我们的屏幕所使用的像素是32bit的还好说,但对成本极其敏感的嵌入式系统中广泛使用的LCD屏幕很多都是 使用RGB565(16bit)颜色格式的,这意味着:
  • 每个像素是16bit,其中R、G、B分别对应5、6、5个二进制位

  • ARGB32中,RGB888占用24个bit,相对RGB565来说,每个像素多占用了8个bit。

  • 在同时需要保留Alpha信息的情况下,RGB565比RGB888节省了25%的空间。


问题来了:PNG格式的文件在解码后往往以ARGB32形式保存,我们如何将其连同Alpha信息一起应用到一个RGB565的屏幕上呢

为了解决这一问题,Arm-2D的思路非常直接:

  • 将Alpha信息从像素中提取出来,单独作为一个数组保存;

  • 在设计阶段,将RGB888转化为RGB565形式保存,从而节省资源的存储空间,也避免了在运行时刻进行颜色格式转换所造成的不必要的性能损失


这里,由单独提取出来的Alpha信息所构成的位图,我们称之为透明度蒙版(Alpha-Mask),很多时候简称蒙版(Mask)。

为了简化用户的设计工序,Arm-2D在仓库的tools文件夹下提供了一个专门的python脚本,用于帮助用户直接将给定的图片文件转化为Arm-2D可以直接使用的tile数据结构。


这是一个命令行工具,需要python3.x 版本,并安装以下的依赖:

pip install Pillowpip install numpy

具体使用方式如下:

python img2c.py <命令行选项>


选项
描述

-h, --help
显示命令行使用方法

-i <路径>
输入图片文件的路径(png, bmp, jpeg...)

-o <路径>
输出c源文件的路径
可选
-name <名称>
数组的名字
可选
-format <格式>
输出的颜色格式:rgb32, rgb565(默认)
可选
-dim <宽度>,<高度>
在输出前修改图片的尺寸可选
-rot <角度>
在输出前将图片旋转指定的角度可选


比如,在 examples/benchmark/asset 目录下有一个png图片 CMSIS_Logo_Final.png,我们可以借助命令行将其转化为 tile 数据结构:

python img2c.py -i ..\examples\benchmark\asset\CMSIS_Logo_Final.png --name CMSISLogo

运行成功后,由于我们没有指定输出的路径,因此直接在tools所在目录下生成了一个与图片文件同名(扩展名不同)的c文件 CMSIS_Logo_Final.c



打开文件,我们可以看到img2c.py按照默认的颜色格式 RGB565 自动生成了对应的像素数组 c_bmpCMSISLogo 和arm-2d的API可以直接使用的arm_2d_tile_t对象c_tileCMSISLogo


static const uint16_t c_bmpCMSISLogo[163*65] = {    ...};
extern const arm_2d_tile_t c_tileCMSISLogo;const arm_2d_tile_t c_tileCMSISLogo = { .tRegion = { .tSize = { .iWidth = 163, .iHeight = 65, }, }, .tInfo = { .bIsRoot = true, .bHasEnforcedColour = true, .tColourInfo = { .chScheme = ARM_2D_COLOUR_RGB565, }, }, .phwBuffer = (uint16_t*)c_bmpCMSISLogo,};

关于 arm_2d_tile_t 数据结构的详细内容,大家可以参考文章《【Arm-2D】不整活儿玩啥GUI?》,这里大家“望文生义”即可,容易发现c_tileCMSISLogo:

  • 描述了图片的尺寸信息:163 * 65

  • 描述了图片的颜色信息:ARM_2D_COLOUR_RGB565

  • 由于直接提供了像素数组的地址,因此这是一个Root tile。


既然拿到了Tile,我们不妨赶快试它一试:


1、将生成的CMSIS_Logo_Final.c加入MDK工程参与编译

2、在example_gui.c中加入对应的引用声明:

extern const arm_2d_tile_t c_tileCMSISLogo;

3、在修改 example_gui.c 中的界面绘制函数 example_gui_refresh():

void example_gui_refresh(const arm_2d_tile_t *ptFrameBuffer, bool bIsNewFrame){    arm_2d_rgb16_fill_colour(ptFrameBuffer, NULL, GLCD_COLOR_WHITE);
arm_2d_rgb16_tile_copy( &c_tileCMSISLogo, ptFrameBuffer, NULL,                            ARM_2D_CP_MODE_COPY);}

这里,我们首先通过 arm_2d_rgb16_fill_colour() 向整个屏幕填充了白色(GLCD_COLOUR_WHITE);紧接着以 arm_2d_rgb16_tile_copy() 将我们的额 c_tileCMSISLogo 拷贝到了屏幕左上角。运行结果如下:



怎么说呢……运行结果正常,却并不能让我们满意——由于缺乏透明度信息,原本应该是完全透明的部分,由于对应像素值为0x0000正好对应了RGB565下的黑色,因此呈现出一个黑色的背景色——这当然不是我们所需要的。


重新打开此前生成的 CMSIS_Logo_Final.c,我们注意到,其实Alpha信息已经被单独提取出来、独立保存并生成了专门的arm_2d_tile_t对象c_tileCMSISLogoMask


static const uint8_t c_bmpCMSISLogoAlpha[163*65] = {    ...};
extern const arm_2d_tile_t c_tileCMSISLogoMask;const arm_2d_tile_t c_tileCMSISLogoMask = { .tRegion = { .tSize = { .iWidth = 163, .iHeight = 65, }, }, .tInfo = { .bIsRoot = true, .bHasEnforcedColour = true, .tColourInfo = { .chScheme = ARM_2D_COLOUR_8BIT, }, }, .pchBuffer = (uint8_t *)c_bmpCMSISLogoAlpha,};

通过观察,容易发现:

  • c_tileCMSISLogoMask拥有与c_tileCMSISLogo相同的像素尺寸,都是163*65;

  • c_tileCMSISLogoMask的颜色是 8bit的 ARM_2D_COLOUR_8BIT

  • 它也是一个root tile。


借助专门的函数 arm_2d_rgb565_tile_copy_with_src_mask(),我们就可以轻松达成所需的效果。具体操作如下:

1、在example_gui.c中加入对应的引用声明:

extern const arm_2d_tile_t c_tileCMSISLogoMask;

2、在修改 example_gui.c 中的界面绘制函数 example_gui_refresh():

void example_gui_refresh(const arm_2d_tile_t *ptFrameBuffer, bool bIsNewFrame){    arm_2d_rgb16_fill_colour(ptFrameBuffer, NULL, GLCD_COLOR_WHITE);         arm_2d_rgb565_tile_copy_with_src_mask(  &c_tileCMSISLogo,                                            &c_tileCMSISLogoMask,                                             ptFrameBuffer,                                            NULL,                                            ARM_2D_CP_MODE_COPY);}

编译后运行效果如下:



如果你还记得本文开篇时的那个辅助函数 arm_2d_align_centre()的话,我们还可以借助它实现Logo居中的效果:

1、确保目标 c 文件中增加了 arm_2d_helper.h 的包含:

#include "arm_2d_helper.h"

2、修改 example_gui_refresh() 函数,加入 arm_2d_align_entre():


void example_gui_refresh(const arm_2d_tile_t *ptFrameBuffer, bool bIsNewFrame){    arm_2d_rgb16_fill_colour(ptFrameBuffer, NULL, GLCD_COLOR_WHITE);
arm_2d_align_centre(*ptFrameBuffer, c_tileCMSISLogo.tRegion.tSize) { arm_2d_rgb565_tile_copy_with_src_mask( &c_tileCMSISLogo, &c_tileCMSISLogoMask, ptFrameBuffer, &__centre_region, ARM_2D_CP_MODE_COPY); }
arm_2d_op_wait_async(NULL);}

运行效果如下:


关于 arm_2d_align_centre() 值得说明的有两点:

  • arm_2d_align_centre() 需要用户传递两类信息

    • 目标缓冲区的实例(注意是实例,不是地址)。在本例中,显示缓冲区由指针 ptFrameBuffer 保存,因此,传递给 arm_2d_align_centre() 时需要加入"*" 运算,即"(*ptFrameBuffer)"

    • 目标区域的大小信息。在本例中,因为我们希望将CMSIS Logo居中,因此目标区域的大小信息就保存在 c_tileCMSISLogo 中。具体写为 c_tileCMSISLogo.tRegion.tSize

    • 最终结果就是代码中所呈现的那样:

arm_2d_align_centre(*ptFrameBuffer,                      c_tileCMSISLogo.tRegion.tSize) {    ...}
  • arm_2d_align_centre() 会产生一个局部变量 __centre_region,它的生命周期仅限于 arm_2d_align_centre() 的花括号内,因此,当我们使用 __centre_region 进行绘图时,要将其生命周期考虑在内——必须在其生命结束前加入 arm_2d_op_wait_async() 以确保API执行的有效性:

void example_gui_refresh(const arm_2d_tile_t *ptFrameBuffer, bool bIsNewFrame){    arm_2d_rgb16_fill_colour(ptFrameBuffer, NULL, GLCD_COLOR_WHITE);
arm_2d_align_centre(*ptFrameBuffer, c_tileCMSISLogo.tRegion.tSize) { arm_2d_rgb565_tile_copy_with_src_mask( &c_tileCMSISLogo, &c_tileCMSISLogoMask, ptFrameBuffer, &__centre_region, ARM_2D_CP_MODE_COPY); arm_2d_op_wait_async(NULL);    }}


【说在后面的话】


回顾这篇文章,我们从“圆角矩形直接贴图那差强人意的问题”引入了充当“透明色”效果的“透明信息(Alpha)”的概念;介绍了arm-2d中所使用的透明蒙版(Alpha-Mask),并介绍了Arm-2D对PNG图片的支持方式。

然而这只是个开始。

透明蒙版的应用远比你想想的要广泛,其通用性和灵活性远远超越了RGBA32这类支持Alpha信息的图片格式。基于篇幅的限制,我们今天就暂时先讲到这里。在随后的文章中,我们将为您详细介绍透明蒙版所带来的的“无限可能”——为你展示其在现代界面设计中所占有的举足轻重的作用。

1.芯片都去哪了?美国SIA年度报告揭秘~

2.树莓派偷偷换上新SoC!

3.MCU从入门到躺平

4.车规级MCU国产替代下的选择题:车厂策略激进,直供能成为未来主流?

5.编程语言成功的几大要素

6.碳中和,不确定世界里的确定性

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。


嵌入式资讯精选 掌握最鲜资讯,尽领行业新风
评论
  • 艾迈斯欧司朗全新“样片申请”小程序,逾160种LED、传感器、多芯片组合等产品样片一触即达。轻松3步完成申请,境内免费包邮到家!本期热荐性能显著提升的OSLON® Optimal,GF CSSRML.24ams OSRAM 基于最新芯片技术推出全新LED产品OSLON® Optimal系列,实现了显著的性能升级。该系列提供五种不同颜色的光源选项,包括Hyper Red(660 nm,PDN)、Red(640 nm)、Deep Blue(450 nm,PDN)、Far Red(730 nm)及Ho
    艾迈斯欧司朗 2024-11-29 16:55 178浏览
  • 概述 说明(三)探讨的是比较器一般带有滞回(Hysteresis)功能,为了解决输入信号转换速率不够的问题。前文还提到,即便使能滞回(Hysteresis)功能,还是无法解决SiPM读出测试系统需要解决的问题。本文在说明(三)的基础上,继续探讨为SiPM读出测试系统寻求合适的模拟脉冲检出方案。前四代SiPM使用的高速比较器指标缺陷 由于前端模拟信号属于典型的指数脉冲,所以下降沿转换速率(Slew Rate)过慢,导致比较器检出出现不必要的问题。尽管比较器可以使能滞回(Hysteresis)模块功
    coyoo 2024-12-03 12:20 131浏览
  • 《高速PCB设计经验规则应用实践》+PCB绘制学习与验证读书首先看目录,我感兴趣的是这一节;作者在书中列举了一条经典规则,然后进行详细分析,通过公式推导图表列举说明了传统的这一规则是受到电容加工特点影响的,在使用了MLCC陶瓷电容后这一条规则已经不再实用了。图书还列举了高速PCB设计需要的专业工具和仿真软件,当然由于篇幅所限,只是介绍了一点点设计步骤;我最感兴趣的部分还是元件布局的经验规则,在这里列举如下:在这里,演示一下,我根据书本知识进行电机驱动的布局:这也算知行合一吧。对于布局书中有一句:
    wuyu2009 2024-11-30 20:30 134浏览
  • 最近几年,新能源汽车愈发受到消费者的青睐,其销量也是一路走高。据中汽协公布的数据显示,2024年10月,新能源汽车产销分别完成146.3万辆和143万辆,同比分别增长48%和49.6%。而结合各家新能源车企所公布的销量数据来看,比亚迪再度夺得了销冠宝座,其10月新能源汽车销量达到了502657辆,同比增长66.53%。众所周知,比亚迪是新能源汽车领域的重要参与者,其一举一动向来为外界所关注。日前,比亚迪汽车旗下品牌方程豹汽车推出了新车方程豹豹8,该款车型一上市就迅速吸引了消费者的目光,成为SUV
    刘旷 2024-12-02 09:32 123浏览
  •         温度传感器的精度受哪些因素影响,要先看所用的温度传感器输出哪种信号,不同信号输出的温度传感器影响精度的因素也不同。        现在常用的温度传感器输出信号有以下几种:电阻信号、电流信号、电压信号、数字信号等。以输出电阻信号的温度传感器为例,还细分为正温度系数温度传感器和负温度系数温度传感器,常用的铂电阻PT100/1000温度传感器就是正温度系数,就是说随着温度的升高,输出的电阻值会增大。对于输出
    锦正茂科技 2024-12-03 11:50 123浏览
  • 戴上XR眼镜去“追龙”是种什么体验?2024年11月30日,由上海自然博物馆(上海科技馆分馆)与三湘印象联合出品、三湘印象旗下观印象艺术发展有限公司(下简称“观印象”)承制的《又见恐龙》XR嘉年华在上海自然博物馆重磅开幕。该体验项目将于12月1日正式对公众开放,持续至2025年3月30日。双向奔赴,恐龙IP撞上元宇宙不久前,上海市经济和信息化委员会等部门联合印发了《上海市超高清视听产业发展行动方案》,特别提到“支持博物馆、主题乐园等场所推动超高清视听技术应用,丰富线下文旅消费体验”。作为上海自然
    电子与消费 2024-11-30 22:03 98浏览
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-30 14:30 80浏览
  • 当前,智能汽车产业迎来重大变局,随着人工智能、5G、大数据等新一代信息技术的迅猛发展,智能网联汽车正呈现强劲发展势头。11月26日,在2024紫光展锐全球合作伙伴大会汽车电子生态论坛上,紫光展锐与上汽海外出行联合发布搭载紫光展锐A7870的上汽海外MG量产车型,并发布A7710系列UWB数字钥匙解决方案平台,可应用于数字钥匙、活体检测、脚踢雷达、自动泊车等多种智能汽车场景。 联合发布量产车型,推动汽车智能化出海紫光展锐与上汽海外出行达成战略合作,联合发布搭载紫光展锐A7870的量产车型
    紫光展锐 2024-12-03 11:38 112浏览
  • TOF多区传感器: ND06   ND06是一款微型多区高集成度ToF测距传感器,其支持24个区域(6 x 4)同步测距,测距范围远达5m,具有测距范围广、精度高、测距稳定等特点。适用于投影仪的无感自动对焦和梯形校正、AIoT、手势识别、智能面板和智能灯具等多种场景。                 如果用ND06进行手势识别,只需要经过三个步骤: 第一步&
    esad0 2024-12-04 11:20 68浏览
  • 作为优秀工程师的你,已身经百战、阅板无数!请先醒醒,新的项目来了,这是一个既要、又要、还要的产品需求,ARM核心板中一个处理器怎么能实现这么丰富的外围接口?踌躇之际,你偶阅此文。于是,“潘多拉”的魔盒打开了!没错,USB资源就是你打开新世界得钥匙,它能做哪些扩展呢?1.1  USB扩网口通用ARM处理器大多带两路网口,如果项目中有多路网路接口的需求,一般会选择在主板外部加交换机/路由器。当然,出于成本考虑,也可以将Switch芯片集成到ARM核心板或底板上,如KSZ9897、
    万象奥科 2024-12-03 10:24 78浏览
  • 国产光耦合器正以其创新性和多样性引领行业发展。凭借强大的研发能力,国内制造商推出了适应汽车、电信等领域独特需求的专业化光耦合器,为各行业的技术进步提供了重要支持。本文将重点探讨国产光耦合器的技术创新与产品多样性,以及它们在推动产业升级中的重要作用。国产光耦合器创新的作用满足现代需求的创新模式新设计正在满足不断变化的市场需求。例如,高速光耦合器满足了电信和数据处理系统中快速信号传输的需求。同时,栅极驱动光耦合器支持电动汽车(EV)和工业电机驱动器等大功率应用中的精确高效控制。先进材料和设计将碳化硅
    克里雅半导体科技 2024-11-29 16:18 181浏览
  • 遇到部分串口工具不支持1500000波特率,这时候就需要进行修改,本文以触觉智能RK3562开发板修改系统波特率为115200为例,介绍瑞芯微方案主板Linux修改系统串口波特率教程。温馨提示:瑞芯微方案主板/开发板串口波特率只支持115200或1500000。修改Loader打印波特率查看对应芯片的MINIALL.ini确定要修改的bin文件#查看对应芯片的MINIALL.ini cat rkbin/RKBOOT/RK3562MINIALL.ini修改uart baudrate参数修改以下目
    Industio_触觉智能 2024-12-03 11:28 95浏览
  • 11-29学习笔记11-29学习笔记习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-02 23:58 81浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2024-12-02 10:40 130浏览
  • RDDI-DAP错误通常与调试接口相关,特别是在使用CMSIS-DAP协议进行嵌入式系统开发时。以下是一些可能的原因和解决方法: 1. 硬件连接问题:     检查调试器(如ST-Link)与目标板之间的连接是否牢固。     确保所有必要的引脚都已正确连接,没有松动或短路。 2. 电源问题:     确保目标板和调试器都有足够的电源供应。     检查电源电压是否符合目标板的规格要求。 3. 固件问题: &n
    丙丁先生 2024-12-01 17:37 102浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦