改变嵌软开发思维方式之:状态机的三种实现方法

嵌入式大杂烩 2021-09-15 22:53

关注「嵌入式大杂烩」,选择「星标公众号」一起进步!

作者 | Alicedodo

上一篇推文:咱们是时候改变一下嵌入式软件开发思维方式了!提到了状态机。在之前的推文中:干货 | 嵌入式之状态机编程。有简单介绍了状态机的示例。这次我们一起来学习C语言实现状态机的三种方法解析。

状态机的实现无非就是 3 个要素:状态事件响应。转换成具体的行为就 3 句话。

  • 发生了什么事?
  • 现在系统处在什么状态?
  • 在这样的状态下发生了这样的事,系统要干什么?

用 C 语言实现状态机主要有 3 种方法:switch—case 法表格驱动法函数指针法

switch—case 法

状态用 switch—case 组织起来, 将事件也用switch—case 组织起来, 然后让其中一个 switch—case 整体插入到另一个 switch—case 的每一个 case 项中  。

「程序清单 List4  :」

switch(StateVal)
{
    case S0:
  switch(EvntID)
  {
   case E1:
    action_S0_E1(); /*S0 状态下 E1 事件的响应*/
    StateVal = new state value;/*状态迁移,不迁移则没有此行*/
    break;
   case E2:
    action_S0_E2(); /*S0 状态下 E2 事件的响应*/
    StateVal = new state value;
    break;
   ......
   case Em:
    action_S0_Em(); /*S0 状态下 Em 事件的响应*/
    StateVal = new state value;
    break;
   default:
    break;
  }
  break;
    case S1:
  ......
  break;
    ......
    case Sn:
  ......
  break;
    default:
  break;
}

上面的伪代码示例只是通用的情况,实际应用远没有这么复杂。虽然一个系统中事件可能有很多种,但在实际应用中,许多事件可能对某个状态是没有意义的。

例如在程序清单 List4中,如果 E2、······ Em 对处在 S0 状态下的系统没有意义,那么在 S0 的 case 下有关事件E2、······ Em 的代码根本没有必要写,状态 S0 只需要考虑事件 E1 的处理就行了。

既然是两个 switch—case 之间的嵌套, 那么就有一个谁嵌套谁的问题, 所以说 switch—case法有两种写法:状态嵌套事件事件嵌套状态。这两种写法都可以, 各有利弊, 至于到底选用哪种方式就留给设计人员根据具体情况自行决断吧。

关于 switch—case 法还有最后一点要说明, 因为 switch—case 的原理是从上到下挨个比较,越靠后,查找耗费的时间就越长,所以要注意状态和事件在各自的 switch 语句中的安排顺序,不推荐程序清单 List4 那样按顺序号排布的方式。出现频率高或者实时性要求高的状态和事件的位置应该尽量靠前。

表格驱动法

如果说 switch—case 法是线性的,那么表格驱动法则是平面的。表格驱动法的实质就是将状态和事件之间的关系固化到一张二维表格里, 把事件当做纵轴,把状态当做横轴,交点[Sn , Em]则是系统在 Sn 状态下对事件 Em 的响应  。

如图 4, 我把表格中的 Node_SnEm 叫做状态机节点, 状态机节点 Node_SnEm 是系统在 Sn状态下对事件 Em 的响应。这里所说的响应包含两个方面:输出动作和状态迁移。状态机节点一般是一个类似程序清单 List5 中的结构体变量 。

struct fsm_node
{

    void (*fpAction)(void* pEvnt);
    INT8U u8NxtStat;
};

程序清单 List5 中的这个结构体有两个成员:fpAction 和 u8NxtStat。fpAction 是一个函数指针, 指向一个形式为 void func(void * pEvnt)的函数, func 这个函数是对状态转移中动作序列的标准化封装。

也就是说, 状态机在状态迁移的时候, 不管输出多少个动作、操作多少个变量、调用多少个函数,这些行为统统放到函数 func 中去做。

把动作封装好了之后,再把封装函数 func 的地址交给函数指针 fpAction,这样,想要输出动作,只需要调用函数指针 fpAction 就行了。

再看看上面的 func 函数,会发现函数有一个形参 pEvnt,这是一个类型为 void * 的指针, 在程序实际运行时指向一个能存储事件的变量,通过这个指针我们就能获知关于事件的全部信息,这个形参是很有必要的。事件一般包括两个属性:事件的类型和事件的内容。

例如一次按键事件,我们不仅要知道这是一个按键事件,还要知道按下的到底是哪个键。事件的类型和状态机当前的状态可以让我们在图 4 的表格中迅速定位,确定该调用哪个动作封装函数, 但是动作封装函数要正确响应事件还需要知道事件的内容是什么, 这也就是形参pEvnt 的意义。

由于事件的多样性,存储事件内容的数据格式不一定一样,所以就把 pEvnt 定义成了 void * 型,以增加灵活性。有关 fpAction 的最后一个问题:如果事件 Em 对状态 Sn 没有意义,那么状态机节点Node_SnEm 中的 fpAction 该怎么办?我的答案是:那就让它指向一个空函数呗!前面不是说过么,什么也不干也叫响应。

u8NxtStat 存储的是状态机的一个状态值。我们知道, 状态机响应事件要输出动作, 也就是调用函数指针 fpAction 所指向的那个封装函数, 函数调用完毕后程序返回主调函数, 状态机对事件的响应就算结束了, 下一步就要考虑状态迁移的问题了。

可能要保持本状态不变, 也可能要迁移到一个新的状态,该如何抉择呢?u8NxtStat 存储的状态就是状态机想要的答案!

图 4 的这张表格反映在 C 语言代码里就是一个二维数组,第 1 维就是状态机的状态,第 2维就是统一分类的事件,而数组的元素则是程序清单 List5 中的结构体常量。如果程序中使用表格驱动法,还需要注意一些特别的事项。要将状态当做表格的横轴,那么就要求状态值集合必须满足以下条件:

(1) 该集合是一个递增的等差整数数列

(2) 该数列初值为 0

(3) 该数列等差值为 1

“事件” 作为纵轴,其特点和要求与用来做横轴的“状态” 完全一致。在 C 语言提供的数据类型中, 没有比枚举更符合以上要求的可选项了, 极力推荐将状态集合和事件类型集合做成枚举常量表格驱动法的优点:调用接口统一 ,定位快速。

表格驱动法屏蔽了不同状态下处理各个事件的差异性,因此可以将处理过程中的共性部分提炼出来,做成标准统一的框架式代码,形成统一的调用接口。根据程序清单 List5 中的状态机节点结构体,做成的框架代码如程序清单 List6 所示。

表格驱动法查找目标实际上就是一次二维数组的寻址操作,所以它的平均效率要远高于switch—case 法。

「程序清单 List6  :」

extern struct fsm_node g_arFsmDrvTbl[][]; /*状态机驱动表格*/
INT8U u8CurStat = 0/*状态暂存*/
INT8U u8EvntTyp = 0/*事件类型暂存*/
void* pEvnt = NULL/*事件变量地址暂存*/
struct fsm_node stNodeTmp = {NULL0}; /*状态机节点暂存*/
u8CurStat = get_cur_state(); /*读取当前状态*/
u8EvntTyp = get_cur_evnt_typ(); /*读取当前触发事件类型*/
pEvnt = (void*)get_cur_evnt_ptr(); /*读取事件变量地址*/
stNodeTmp = g_arFsmDrvTbl[u8CurStat ][u8EvntTyp ];/*定位状态机节点*/
stNodeTmp.fpAction(pEvnt ); /*动作响应*/
set_cur_state(stNodeTmp.u8NxtStat); /*状态迁移*/
.....

表格驱动法好则好矣,但用它写出来的程序还有点儿小问题,我们先来看看按照表格驱动法写出来的程序有什么特点 。

前面说过,表格驱动法可以把状态机调度的部分做成标准统一的框架代码,这个框架适用性极强, 不管用状态机来实现什么样的应用, 框架代码都不需要做改动, 我们只需要根据实际应用场合规划好状态转换图,然后将图中的各个要素(状态、事件、动作、迁移,有关“条件”要素一会儿再说)用代码实现就行了,我把这部分代码称作应用代码。

在应用代码的.c 文件中, 你会看到一个声明为 const 的二维数组, 也就是图 4 所示的状态驱动表格, 还会看到许多彼此之间毫无关联的函数, 也就是前面提到的动作封装函数。这样的一份代码, 如果手头上没有一张状态转换图, 让谁看了也会一头雾水, 这样的格式直接带来了代码可读性差的问题。

如果我们想给状态机再添加一个状态,反映到代码上就是给驱动表格再加一列内容,同时也要新添加若干个动作封装函数。如果驱动表格很大, 做这些工作是很费事儿的, 而且容易出错。如果不小心在数组中填错了位置, 那么程序跑起来就和设计者的意图南辕北辙了,

远没有在 switch—case 法中改动来得方便、安全。上面说的只是小瑕疵, 其实最让我不爽的是表格驱动法不能使用干货 | 嵌入式之状态机编程 中 g_stFSM那样的 Extended State Machine(对这个词组还有印象吧?)!Extended State Machine 的最大特点就是状态机响应事件之前先判断条件,根据判定结果选择执行哪些动作,转向哪个状态。

也就是说,系统在状态 Sn 下发生了事件 Em 后,转向的状态不一定是唯一的,这种灵活性是 Extended State Machine 的最有价值的优点。

回过头来看看程序清单 List5 中给出的状态机节点结构体,如果系统在状态 Sn 下发生了事件 Em, 状态机执行完 fpAction 所给出的动作响应之后, 必须转到 u8NxtStat 指定的状态。

表格驱动法的这个特性直接杜绝了 Extended State Machine 在表格驱动法中应用的可能性, 所以表格驱动法的代码实现中不存在“条件” 这个状态机要素。ESM,你是如此的优秀,我怎么舍得抛弃你 ?!

再看图 4 所示的表格驱动法示例图,如果我们把表格中的代表事件的纵轴去掉,只留下代表状态的横轴,将一列合并成一格,前文提到的问题是不是能得到解决呢?不错!这就是失传江湖多年的《葵花宝典》 ——阉割版表格驱动法 !!

阉割版表格驱动法,又名压缩表格驱动法,一维状态表格与事件 switch—case 的合体。压缩表格驱动法使用了一维数组作为驱动表格,数组的下标即是状态机的各个状态。

表格中的元素叫做压缩状态机节点, 节点的主要内容还是一个指向动作封装函数的函数指针, 只不过这个动作封装函数不是为某个特定事件准备的, 而是对所有的事件都有效的。

节点中不再强制指定状态机输出动作完毕后所转向的状态, 而是让动作封装函数返回一个状态, 并把这个状态作为状态机新的状态。

压缩表格驱动法的这个特点, 完美的解决了 Extended State Machine 不能在表格驱动法中使用的问题 。

程序清单 List7 中的示例代码包含了压缩状态机节点结构体和状态机调用的框架代码。

「程序清单 List7:」

struct fsm_node /*压缩状态机节点结构体*/
{

 INT8U (*fpAction)(void* pEvnt); /*事件处理函数指针*/
 INT8U u8StatChk; /*状态校验*/
};
......
u8CurStat = get_cur_state(); /*读取当前状态*/
......
if(stNodeTmp.u8StatChk == u8CurStat )
{
 u8CurStat = stNodeTmp.fpAction(pEvnt ); /*事件处理*/
 set_cur_state(u8CurStat ); /*状态迁移*/
}
else
{
 state_crash(u8CurStat ); /*非法状态处理*/
}
.....

对照程序清单 List5,就会发现程序清单 List7 中 struct fsm_node 结构体的改动之处。首先, fpAction 所指向函数的函数形式变了,动作封装函数 func 的模样成了这样的了:

INT8U func(void * pEvnt);

现在的动作封装函数 func 是要返回类型为 INT8U 的返回值的,这个返回值就是状态机要转向的状态, 也就是说, 压缩表格驱动法中的状态机节点不负责状态机新状态的确定, 而把这项任务交给了动作封装函数 func, func 返回哪个状态, 状态机就转向哪个状态。

新状态由原来的常量变成了现在的变量,自然要灵活许多。上面说到现在的动作封装函数 func 要对当前发生的所有的事件都要负责, 那么 func 怎么会知道到底是哪个事件触发了它呢?看一下 func 的形参 void * pEvnt 。

在程序清单 List5 中我们提到过,这个形参是用来向动作封装函数传递事件内容的,但是从前文的叙述中我们知道, pEvnt 所指向的内存包含了事件的所有信息, 包括事件类型和事件内容 , 所以通过形参 pEvnt , 动作封装函数 func 照样可以知道事件的类型。

程序清单 List7 中 struct fsm_node 结构体还有一个成员 u8StatChk , 这里面存储的是状态机 的一个状态,干什么用的呢?玩 C 语言数组的人都知道,要严防数组寻址越界

要知道,压缩表格驱动法的驱动表格是一个以状态值为下标的一维数组, 数组元素里面最重要的部分就是一个个动作封装函数的地址。

函数地址在单片机看来无非就是一段二进制数据, 和内存中其它的二进制数据没什么两样,不管程序往单片机 PC 寄存器里塞什么值,单片机都没意见。假设程序由于某种意外而改动了存储状态机当前状态的变量,使变量值变成了一个非法状态。

再发生事件时, 程序就会用这个非法的状态值在驱动表格中寻址, 这时候就会发生内存泄露,程序拿泄露内存中的未知数据当函数地址跳转,不跑飞才怪!

为了防止这种现象的发生, 压缩状态机节点结构体中又添加了成员 u8StatChk 。u8StatChk中存储的是压缩状态机节点在一维驱动表格的位置, 例如某节点是表格中的第 7 个元素, 那么这个节点的成员 u8StatChk 值就是 6。

看一下程序清单 List7 中的框架代码示例, 程序在引用函数指针 fpAction 之前, 先检查当前状态和当前节点成员 u8CurStat 的值是否一致,一致则认为状态合法,事件正常响应,如果不一致,则认为当前状态非法,转至意外处理,最大限度保证程序运行的安全。当然,如果泄露内存中的数据恰好和 u8CurStat 一致,那么这种方法真的就回天乏力了。

还有一个方法也可以防止状态机跑飞,如果状态变量是枚举,那么框架代码就可以获知状态值的最大值, 在调用动作封装函数之前判断一下当前状态值是否在合法的范围之内, 同样能保证状态机的安全运行。

压缩表格驱动法中动作封装函数的定义形式我们已经知道了,函数里面到底是什么样子的呢?程序清单 List8 是一个标准的示例。

「程序清单List8:」

INT8U action_S0(void* pEvnt)
{
 INT8U u8NxtStat = 0;
 INT8U u8EvntTyp = get_evnt_typ(pEvnt);
 switch(u8EvntTyp )
 {
  case E1:
   action_S0_E1(); /*事件 E1 的动作响应*/
   u8NxtStat = new state value; /*状态迁移,不迁移也必须有本行*/
   break;
   ......
  case Em:
   action_S0_Em(); /*事件 Em 的动作响应*/
   u8NxtStat = new state value; /*状态迁移,不迁移也必须有本行*/
   break;
  default:
   ; /*不相关事件处理*/
   break;
 }
 return u8NxtStat ; /*返回新状态*/
}

从程序清单 List8 可以看出, 动作封装函数其实就是事件 switch—case 的具体实现。函数根据形参 pEvnt 获知事件类型, 并根据事件类型选择动作响应, 确定状态机迁移状态, 最后将新的状态作为执行结果返回给框架代码。

有了这样的动作封装函数, Extended State Machine 的应用就可以完全不受限制了!到此,有关压缩表格驱动法的介绍就结束了。

个人认为压缩表格驱动法是相当优秀的,它既有表格驱动法的简洁、高效、标准,又有 switch—case 法的直白、灵活、多变,相互取长补短,相得益彰。

函数指针法

上面说过,用 C 语言实现状态机主要有 3 种方法(switch—case 法、表格驱动法、函数指针法), 其中函数指针法是最难理解的, 它的实质就是把动作封装函数的函数地址作为状态来看待。不过,有了之前压缩表格驱动法的铺垫,函数指针法就变得好理解了,因为两者本质上是相同的。

压缩表格驱动法的实质就是一个整数值(状态机的一个状态)到一个函数地址(动作封装函数)的一对一映射, 压缩表格驱动法的驱动表格就是全部映射关系的直接载体。在驱动表格中通过状态值就能找到函数地址,通过函数地址同样能反向找到状态值。

我们用一个全局的整型变量来记录状态值,然后再查驱动表格找函数地址,那干脆直接用一个全局的函数指针来记录状态得了,还费那劳什子劲干吗?!这就是函数指针法的前世今生。

用函数指针法写出来的动作封装函数和程序清单 List8 的示例函数是很相近的, 只不过函数的返回值不再是整型的状态值, 而是下一个动作封装函数的函数地址, 函数返回后, 框架代码再把这个函数地址存储到全局函数指针变量中。

相比压缩表格驱动法,在函数指针法中状态机的安全运行是个大问题,我们很难找出一种机制来检查全局函数指针变量中的函数地址是不是合法值。如果放任不管, 一旦函数指针变量中的数据被篡改,程序跑飞几乎就不可避免了。

小节

有关状态机的东西说了那么多,相信大家都已经感受到了这种工具的优越性,状态机真的是太好用了!其实我们至始至终讲的都是有限状态机(Finite State Machine 现在知道为什么前面的代码中老是有 fsm 这个缩写了吧!), 还有一种比有限状态机更 NB 更复杂的状态机, 那就是层次状态机(Hierarchical State Machine 一般简写为 HSM)。

通俗的说,系统中只存在一个状态机的叫做有限状态机,同时存在多个状态机的叫做层次状态机(其实这样解释层次状态机有些不严谨, 并行状态机也有多个状态机, 但层次状态机各个状态机之间是上下级关系,而并行状态机各个状态机之间是平级关系)。

层次状态机是一种父状态机包含子状态机的多状态机结构,里面包含了许多与面向对象相似的思想, 所以它的功能也要比有限状态机更加强大, 当一个问题用有限状态机解决起来有些吃力的时候, 就需要层次状态机出马了。

层次状态机理论我理解得也不透彻, 就不在这里班门弄斧了,大家可以找一些有关状态机理论的专业书籍来读一读。要掌握状态机编程,理解状态机(主要指有限状态机)只是第一步,也是最简单的一步,更重要的技能是能用状态机这个工具去分析解剖实际问题:划分状态、 提取事件、 确定转换关系、规定动作等等,形成一张完整的状态转换图,最后还要对转换图进行优化,达到最佳。

把实际问题变成了状态转换图, 工作的一大半就算完成了, 这个是具有架构师气质的任务,剩下的问题就是按照状态图编程写代码了,这个是具有代码工特色的工作。

本文来源网络版权归原作者所有。如涉及作品版权问题,请联系我进行删除。

往期推荐:

往期推荐



咱们是时候改变一下嵌入式软件开发思维方式了!

什么是不完全类型?

C语言、嵌入式中几个非常实用的宏技巧

干货 | 浅析程序开机自启动


嵌入式大杂烩 专注于嵌入式技术,包括但不限于C/C++、嵌入式、物联网、Linux等编程学习笔记,同时,内包含大量的学习资源。欢迎关注,一同交流学习,共同进步!
评论
  • 近日,搭载紫光展锐W517芯片平台的INMO GO2由影目科技正式推出。作为全球首款专为商务场景设计的智能翻译眼镜,INMO GO2 以“快、准、稳”三大核心优势,突破传统翻译产品局限,为全球商务人士带来高效、自然、稳定的跨语言交流体验。 INMO GO2内置的W517芯片,是紫光展锐4G旗舰级智能穿戴平台,采用四核处理器,具有高性能、低功耗的优势,内置超微高集成技术,采用先进工艺,计算能力相比同档位竞品提升4倍,强大的性能提供更加多样化的应用场景。【视频见P盘链接】 依托“
    紫光展锐 2024-12-11 11:50 88浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-12 10:13 67浏览
  • 全球智能电视时代来临这年头若是消费者想随意地从各个通路中选购电视时,不难发现目前市场上的产品都已是具有智能联网功能的智能电视了,可以宣告智能电视的普及时代已到临!Google从2021年开始大力推广Google TV(即原Android TV的升级版),其他各大品牌商也都跟进推出搭载Google TV操作系统的机种,除了Google TV外,LG、Samsung、Panasonic等大厂牌也开发出自家的智能电视平台,可以看出各家业者都一致地看好这块大饼。智能电视的Wi-Fi连线怎么消失了?智能电
    百佳泰测试实验室 2024-12-12 17:33 105浏览
  • 应用环境与极具挑战性的测试需求在服务器制造领域里,系统整合测试(System Integration Test;SIT)是确保产品质量和性能的关键步骤。随着服务器系统的复杂性不断提升,包括:多种硬件组件、操作系统、虚拟化平台以及各种应用程序和服务的整合,服务器制造商面临着更有挑战性的测试需求。这些挑战主要体现在以下五个方面:1. 硬件和软件的高度整合:现代服务器通常包括多个处理器、内存模块、储存设备和网络接口。这些硬件组件必须与操作系统及应用软件无缝整合。SIT测试可以帮助制造商确保这些不同组件
    百佳泰测试实验室 2024-12-12 17:45 106浏览
  • 本文介绍瑞芯微RK3588主板/开发板Android12系统下,APK签名文件生成方法。触觉智能EVB3588开发板演示,搭载了瑞芯微RK3588芯片,该开发板是核心板加底板设计,音视频接口、通信接口等各类接口一应俱全,可帮助企业提高产品开发效率,缩短上市时间,降低成本和设计风险。工具准备下载Keytool-ImportKeyPair工具在源码:build/target/product/security/系统初始签名文件目录中,将以下三个文件拷贝出来:platform.pem;platform.
    Industio_触觉智能 2024-12-12 10:27 104浏览
  • 首先在gitee上打个广告:ad5d2f3b647444a88b6f7f9555fd681f.mp4 · 丙丁先生/香河英茂工作室中国 - Gitee.com丙丁先生 (mr-bingding) - Gitee.com2024年对我来说是充满挑战和机遇的一年。在这一年里,我不仅进行了多个开发板的测评,还尝试了多种不同的项目和技术。今天,我想分享一下这一年的故事,希望能给大家带来一些启发和乐趣。 年初的时候,我开始对各种开发板进行测评。从STM32WBA55CG到瑞萨、平头哥和平海的开发板,我都
    丙丁先生 2024-12-11 20:14 91浏览
  • 在智能化技术快速发展当下,图像数据的采集与处理逐渐成为自动驾驶、工业等领域的一项关键技术。高质量的图像数据采集与算法集成测试都是确保系统性能和可靠性的关键。随着技术的不断进步,对于图像数据的采集、处理和分析的需求日益增长,这不仅要求我们拥有高性能的相机硬件,还要求我们能够高效地集成和测试各种算法。我们探索了一种多源相机数据采集与算法集成测试方案,能够满足不同应用场景下对图像采集和算法测试的多样化需求,确保数据的准确性和算法的有效性。一、相机组成相机一般由镜头(Lens),图像传感器(Image
    康谋 2024-12-12 09:45 110浏览
  • 我的一台很多年前人家不要了的九十年代SONY台式组合音响,接手时只有CD功能不行了,因为不需要,也就没修,只使用收音机、磁带机和外接信号功能就够了。最近五年在外地,就断电闲置,没使用了。今年9月回到家里,就一个劲儿地忙着收拾家当,忙了一个多月,太多事啦!修了电气,清理了闲置不用了的电器和电子,就是一个劲儿地扔扔扔!几十年的“工匠式”收留收藏,只能断舍离,拆解不过来的了。一天,忽然感觉室内有股臭味,用鼻子的嗅觉功能朝着臭味重的方向寻找,觉得应该就是这台组合音响?怎么会呢?这无机物的东西不会腐臭吧?
    自做自受 2024-12-10 16:34 201浏览
  • 全球知名半导体制造商ROHM Co., Ltd.(以下简称“罗姆”)宣布与Taiwan Semiconductor Manufacturing Company Limited(以下简称“台积公司”)就车载氮化镓功率器件的开发和量产事宜建立战略合作伙伴关系。通过该合作关系,双方将致力于将罗姆的氮化镓器件开发技术与台积公司业界先进的GaN-on-Silicon工艺技术优势结合起来,满足市场对高耐压和高频特性优异的功率元器件日益增长的需求。氮化镓功率器件目前主要被用于AC适配器和服务器电源等消费电子和
    电子资讯报 2024-12-10 17:09 106浏览
  • 时源芯微——RE超标整机定位与解决详细流程一、 初步测量与问题确认使用专业的电磁辐射测量设备,对整机的辐射发射进行精确测量。确认是否存在RE超标问题,并记录超标频段和幅度。二、电缆检查与处理若存在信号电缆:步骤一:拔掉所有信号电缆,仅保留电源线,再次测量整机的辐射发射。若测量合格:判定问题出在信号电缆上,可能是电缆的共模电流导致。逐一连接信号电缆,每次连接后测量,定位具体哪根电缆或接口导致超标。对问题电缆进行处理,如加共模扼流圈、滤波器,或优化电缆布局和屏蔽。重新连接所有电缆,再次测量
    时源芯微 2024-12-11 17:11 128浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-11 17:58 105浏览
  • 铁氧体芯片是一种基于铁氧体磁性材料制成的芯片,在通信、传感器、储能等领域有着广泛的应用。铁氧体磁性材料能够通过外加磁场调控其导电性质和反射性质,因此在信号处理和传感器技术方面有着独特的优势。以下是对半导体划片机在铁氧体划切领域应用的详细阐述: 一、半导体划片机的工作原理与特点半导体划片机是一种使用刀片或通过激光等方式高精度切割被加工物的装置,是半导体后道封测中晶圆切割和WLP切割环节的关键设备。它结合了水气电、空气静压高速主轴、精密机械传动、传感器及自动化控制等先进技术,具有高精度、高
    博捷芯划片机 2024-12-12 09:16 101浏览
  • 一、SAE J1939协议概述SAE J1939协议是由美国汽车工程师协会(SAE,Society of Automotive Engineers)定义的一种用于重型车辆和工业设备中的通信协议,主要应用于车辆和设备之间的实时数据交换。J1939基于CAN(Controller Area Network)总线技术,使用29bit的扩展标识符和扩展数据帧,CAN通信速率为250Kbps,用于车载电子控制单元(ECU)之间的通信和控制。小北同学在之前也对J1939协议做过扫盲科普【科普系列】SAE J
    北汇信息 2024-12-11 15:45 125浏览
  • 天问Block和Mixly是两个不同的编程工具,分别在单片机开发和教育编程领域有各自的应用。以下是对它们的详细比较: 基本定义 天问Block:天问Block是一个基于区块链技术的数字身份验证和数据交换平台。它的目标是为用户提供一个安全、去中心化、可信任的数字身份验证和数据交换解决方案。 Mixly:Mixly是一款由北京师范大学教育学部创客教育实验室开发的图形化编程软件,旨在为初学者提供一个易于学习和使用的Arduino编程环境。 主要功能 天问Block:支持STC全系列8位单片机,32位
    丙丁先生 2024-12-11 13:15 73浏览
  • RK3506 是瑞芯微推出的MPU产品,芯片制程为22nm,定位于轻量级、低成本解决方案。该MPU具有低功耗、外设接口丰富、实时性高的特点,适合用多种工商业场景。本文将基于RK3506的设计特点,为大家分析其应用场景。RK3506核心板主要分为三个型号,各型号间的区别如下图:​图 1  RK3506核心板处理器型号场景1:显示HMIRK3506核心板显示接口支持RGB、MIPI、QSPI输出,且支持2D图形加速,轻松运行QT、LVGL等GUI,最快3S内开
    万象奥科 2024-12-11 15:42 109浏览
我要评论
1
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦