当前位置: 首页 > article >正文

ZYNQ学习记录FPGA(二)Verilog语言

一、Verilog简介

1.1 HDL(Hardware Description language)

        在解释HDL之前,先来了解一下数字系统设计的流程:逻辑设计 -> 电路实现  -> 系统验证。

逻辑设计又称前端,在这个过程中就需要用到HDL,正文名硬件描述语言,本文所要介绍的Verilog就时HDL中的一种,需要注意的是,一般我们说的编程语言如C,C++,Python等其实是在描述软件,而HDL是在描述硬件,这是HDL与其他编程语言的重要区别。

        HDL 是描述数字电路的结构和功能的语言,用HDL描述的电路的结构和功能可以通过综合工具(EDA工具)将其转换成门级电路网表(数字电路最基本的单元就是门,门机电路网表可以组合成几乎所有的高级数字电路),有了门级电路网表,再结合特定的工艺(不同厂商有不同的工艺,如FPGA和ASIC),将工艺中的元件和网表一一对应起来,再通过布局布线形成电路结构,就能完成电路的实现,又称后端。

        HDL中除了Verilog语言外还有VHDL,这两个HDL中,Verilog在中国和美国应用更加广泛,而VHDL在欧洲应用更广一点。

1.2 Verilog简介

        Verilog语育最初是于1983 年由Gateway Design Automation 公司为其模拟器产品开发的硬件建模语言。
        Verilog 语言于1995 年成为IEEE 标准,称为IEEE Std 1364-1995,也就是通常所说的Verilog-95。Verilog-2001是对Verilog-95的一个重大改进版本。

1.3 Verilog 和 C语言的区别

        Verilog 是硬件描述语言,在编译下载到FPGA之后,会生成电路,所以Verilog 是并行运行的;
C语言是软件编程语言,编译下载到单片机之后,是存储器中的一组指令而单片机处理软件指令需要取指、译码、执行,这个过程是串行执行的。

        Verilog和C的区别也是FPGA和 单片机/CPU的区别。FPGA由于全并行处理,处理速度非常快,这个是 FPGA 的最大优势,这一点是 单片机/CPU 替代不了的。

二、Verilog语法

2.1 逻辑值

        逻辑0表示低电平,对应电路中的GND;

        逻辑1表示高电平,对应电路中的VCC;

        逻辑X表示未知电平,可能是高也可能是低;

        逻辑Z表示高阻态,外部没有激励,处于悬空状态;

        注意逻辑Z和逻辑X的区分,逻辑X是可高可低的而逻辑Z是不能判断电平高低的是悬空的。

2.2 数字进制格式

        Verilog包括二进制(b)、八进制(o)、十进制(d)和十六进制(h),verilog中定义常量需要说明位数和进制,如4‘b1101,4’o15,4d'13,4h'd都表示同一个数值但是不同进制

2.3 标识符(identifier)

        标识符类似于C语言中的变量名,它是用来定义模块名、端口名、信号名等的。

        定义标识符时应该注意一下三点:

        1)标识符可以是任意一组字母、数字、$符号和(下划线)符号的组合;

        2)标识符的第一个字符必须是字母或者下划线; 

        3)标识符是区分大小写的;

        一般定义标识符可以遵循以下规则:

        1)大小写不混合使用;2)普通内部信号小写表示;3)信号名应该体现信号的含义且应该简洁清晰。

        一些标识符举例:sum、cpu_addr、clk_10、clk_4、clk_cpu等

2.4 数据类型

        在 Verilog 语言中,主要有三大类数据类型:寄存器数据类型、线网数据类型和参数数据类型。前两者是要映射到实际电路中去的,是真正对电路进行描述的数据类型

2.4.1寄存器数据类型

        定义寄存器数据的关键字为 reg ,举例如下:

        

        这里定义了两个寄存器变量,也可以叫reg变量,分别为delay_cnt和key_reg,其中delay_cnt还指定了该寄存器变量的位宽为32位(0-31),值得注意的是每一个寄存器变量定义结束时都要有分号,位宽的定义为从大到小且定义reg变量时是禁止给予初始值的。

        reg类型的数据只能在 always 语和initial 语句中被赋值。

        如果该过程语句描述的是时序逻辑,即always语句带有时钟信号,则该寄存器变量对应的物理意义为触发器
        如果该过程语句描述的是组合逻辑,即always语句不带有时钟信号,则该寄存器变量对应的物理意义为硬件连线

2.4.2 线网数据类型

        定义线网数据的关键字为 wire 或 tri,两者用法是一致的,但一般用wire,举例如下:

        

        线网数据类型表示结构实体(例如门)之间的物理连线

        线网类型的变量不能储存值,它的值是由驱动它的元件所决定的。那能够驱动线网类型变量的元件有门、连续赋值语句、assign等,如果没有驱动元件连接到线网类型的变量上,则该变量就是高阻的,即其值为z。 

        需要注意的是在举例中没有指定wire变量的位宽,则默认是1位的位宽,当然位宽的定义和reg变量的定义格式相同。

2.4.3 参数数据类型

         定义参数数据的关键字为 parameter,实际就是定义常量,举例如下:

                

       参数型数据常用于定义状态机的状态、数据位宽和延迟大小等采用标识符来代表一个常量可以提高程序的可读性和可维护性在模块调用时,可通过参数传递来改变被调用模块中已定义的参数。

2.5 运算符

        Verilog的运算符主要有算术运算符、关系运算符、逻辑运算符、条件运算符、位运算符、移位运算符、拼接运算符。

2.5.1 算术运算符

        

需要注意的是除法运算只能整除,%为取余的操作。

2.5.2 关系运算符

2.5.3 逻辑运算符

从上到下分别为非、与、或运算

2.5.4 条件操作符

        条件操作符(条件运算符)是Verilog特有的运算符:

        用法举例如下:

result=(a >= b)? a:b;

        表示如果a>=b成立则将a的值赋给result否则将b的值赋给result,即取a和b中的最大值。

2.5.5 位运算符

位运算符就是对数据进行按位进行计算并将每一位之间的计算结果合并后返回,当然位运算符只针对二进制数据有效。

        需要注意的是当a和b的位宽不一致时,位运算会自动对位宽较小的数据的前面进行补零,补零到位宽一致再进行运算。对于异或操作,可以借助之前的条件操作符来理解:异或就可以写成result=(a!=b)?1:0

2.5.6 移位运算符

        需要注意的是两种移位运算都用0来填补移出的空位。当左移时,位宽增加。当右移时,位宽不变。

举例如下:

4'b1001<<2=6'b100100

4'b1001>>1=4 b0100

2.5.7 位拼接运算符

        

        举例如下:

c = {a[7:0],b[1:0]} 

        这样计算出来的c就应该是一个位宽为9的数据c[8:0]。

2.5.8 运算符优先级

        最后将前面介绍的运算符进行优先级排列:

 三、Verilog程序框架

3.1 注释

        Verilog有两种注释方式:注释单行内容“//”;注释范围内容起点用“/*”,结尾用“*/”。

3.2 关键字

        除了前面介绍的变量定义所用的关键字外,Verilog中还有许多关键字,定义标识符应该避免与这些关键字重名:

3.3 框架结构

3.3.1 模块结构(module)

        模块是Verilog中的基本设计单元,可以对照C语言中的函数来理解模块的含义。

        模块一般分为两部分,一部分描述模块的接口,一部分描述模块的逻辑功能。这两部分也同样可以参照C语言中的函数输入变量和函数内容来理解。这两部分可以细分为端口定义,IO说明,内部信号声明,功能定义四个部分,前两部分属于接口的描述,后面两个部分用于描述逻辑功能。

举例如下:

        这里描述模块功能时使用了assign关键字,这是给线网变量赋值的一种方法。只是这里没有声明内部信号,只利用了接口的信号就实现了功能。 

        需要注意的是每一个模块都必须以module关键字开头,以endmodule关键字结尾;input和output定义的变量默认时wire类型的变量;内容中的每一行结束都应该有分号结尾。

3.3.2 功能定义

        功能定义的方法有三种:assign关键字、always关键字、例化实例元件。其中assign只能用于描述组合逻辑功能,always可以描述组合和时序逻辑功能。需要注意的是这三种方式所定义的功能总是并行运行的,不论其在代码中的位置如何,这一点和C语言、python等软件描述语言的串行执行代码是完全不同的。

3.3.2.1 always关键字

下面对always关键字进行详细说明:

         其语法如下:

always @(信号) begin// 语句块
end

        这里的信号表示只有该信号触发时就执行语句块的内容(串行执行),信号可以是边沿触发,也可以是电平触发。边沿触发需要用到posedge(上升沿)和negedge(下降沿)关键字后面加信号名的方式来表示边沿触发的类型。电平触发只需信号名来表示,信号为高电平时触发always,低电平时就不触发always,举例如下:  

        如图中代码所示 ,always语句的功能内容由begin关键字标志开始,end关键字标志结束,begin和end之间的内容是串行进行的,即逐行运行。对于电平触发有一种简单的书写方式:

        用“*”代表所有的输入变量信号,这里“*”表示“a or b or c or d or e or f or g or h or p or m”
3.3.2.2 模块调用(模块例化)

        例化的语法如下:

被例化模块本来的名字 #(.常量参数名 (要赋给该常量参数的值)
)例化名(.被例化模块的接口变量名 (传入的与该接口相对应的变量名),
);

        可以把例化模块对比软件描述语言中的函数的调用,不外乎就是调用函数名、传入参数,只不过这里“调用函数名”还要给“函数”一个新的名字,称为例化名,传入参数时要传入模块的接口变量和模块中定义的常量的值,这样例化后就可以实现模块之间信号的传递了。下面举一个实列来帮助理解:

 

        左图是顶层模块对模块的例化,右图是被例化模块的定义。需要注意的是在例化时,被例化模块的输入接口可以连接reg和wire类型的变量,但是输出接口只能连接wire类型的变量,如在例化time_out模块时,在连接该模块的flag信号时就专门定义了一个wire类型的add_flag变量来连接。

四、进阶Verilog知识点

4.1 结构语句

        结构语句有initial和always两种语句分别由initial和always关键字来开始,区别在于initial语句在程序中只执行一次,而always语句是重复运行的。initial常用于测试文件的编写,用来产生仿真测试信号激励信号),或者用于对存储器变量赋初值。always则用来描述模块功能。举例如下:

         图中的#20这样的#+数字的组合表示延时,延时时间的单位由仿真文件的开头,如`timescale 1ns / 1ps决定,这里是ns为单位,#20就表示延时20ns。

4.2 赋值语句

        Verilog中的赋值包含阻塞赋值和非阻塞赋值两种模式,形式如下:

阻塞赋值b = a
非阻塞赋值b <= a

        我们把a叫做RHS(Right Hand Side),b叫做LHS(Left Hand Side)。那么对于阻塞赋值它实际上做的操作是计算RHS再更新LHS,当在always的语句块中执行时,由于执行过程是串行的,所以必须等阻塞赋值结束后,即更新完LHS后,才会进行下一段代码,这里可以看出阻塞赋值是将计算RHS和更新LHS作为一个整体,一段一段的运行的,颇有阻塞的感觉。对于非阻塞赋值,它把计算RHS和更新LHS两个部分拆开了,并且在计算非阻塞赋值的RHS以及更新LHS期间,允许其他的非阻塞赋值语句同时计算RHS和更新LHS,这样就做到了相较于阻塞赋值的非阻塞赋值。

        对于阻塞赋值和非阻塞赋值怎么选?什么时候用?这两个问题可以参照下面的规定:

                1)在描述组合逻辑的 always 块中用阻塞赋值“=”,综合成组合逻辑的电路结构;

        这种电路结构只与输入电平的变化有关系。
                2)在描述时序逻辑的 always 块中用非阻塞赋值<,综合成时序逻辑的电路结构;

        这种电路结构往往与触发沿有关系,只有在触发沿时才可能发生赋值的变化。
        注意:在同一个always块中不要既用非阻塞赋值又用阻塞赋值;不允许在多个always块中对同       一个变量进行赋值!

4.3 条件语句        

条件语句有if-else和case两种 ,if语句语法如下:

if(表达式1)语句1;
else if(表达式2)语句2;
else if(表达式3)语句3;
else语句4;
if(a) begin语句1;语句2;
end
else begin语句3;if(!b)语句4;else语句5;
end

         需要注意的是,在if进行值的判断时,0(低电平)、x(未知)、z(高阻态)均表示假。用begin,end的组合可以使得一个if或else包含多个语句。

        对于case语句,举例如下:

        case的内容中包含分支表达式和控制表达式,分支表达式表示需要被满足的条件,控制表达式则表示满足条件后执行的内容。需要注意的是在写分支表达式时,位宽必须和输入num的位宽一致且不能省略。default表示所有分支表达式都不满足时就执行default的内容。

        case在Verilog中还有两种写法casez和casex

        casez表示比较时不考虑高阻值,casex表示比较时不考虑高阻值和未知值。

五、总结

        在本篇学习过程中,我们深入了解了Verilog语言的基本概念、语法和应用,重点提到了Verilog作为硬件描述语言(HDL)与传统编程语言如C语言的差异,我们还详细解析了Verilog的语法,包括逻辑值的表示、常用的数据类型(如寄存器类型reg与线网类型wire)以及多种运算符的使用。

        然后讲解了Verilog的模块,Verilog的程序结构由模块(module)构成,每个模块定义了电路的功能和接口。模块的功能可以通过assign语句、always语句或模块实例化来实现。尤其需要注意的是,Verilog中的设计是并行执行的,与传统软件编程语言的串行执行方式不同,这一点也是其在硬件实现中的巨大优势。最后学习了Verilog的三种进阶的语句。

       

相关文章:

ZYNQ学习记录FPGA(二)Verilog语言

一、Verilog简介 1.1 HDL&#xff08;Hardware Description language&#xff09; 在解释HDL之前&#xff0c;先来了解一下数字系统设计的流程&#xff1a;逻辑设计 -> 电路实现 -> 系统验证。 逻辑设计又称前端&#xff0c;在这个过程中就需要用到HDL&#xff0c;正文…...

k8s从入门到放弃之Pod的容器探针检测

k8s从入门到放弃之Pod的容器探针检测 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;容器探测是指kubelet对容器执行定期诊断的过程&#xff0c;以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...

精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑

精益数据分析&#xff08;98/126&#xff09;&#xff1a;电商转化率优化与网站性能的底层逻辑 在电子商务领域&#xff0c;转化率与网站性能是决定商业成败的核心指标。今天&#xff0c;我们将深入解析不同类型电商平台的转化率基准&#xff0c;探讨页面加载速度对用户行为的…...

Java中HashMap底层原理深度解析:从数据结构到红黑树优化

一、HashMap概述与核心特性 HashMap作为Java集合框架中最常用的数据结构之一&#xff0c;是基于哈希表的Map接口非同步实现。它允许使用null键和null值&#xff08;但只能有一个null键&#xff09;&#xff0c;并且不保证映射顺序的恒久不变。与Hashtable相比&#xff0c;Hash…...

【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space

问题&#xff1a;IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案&#xff1a;将编译的堆内存增加一点 位置&#xff1a;设置setting-》构建菜单build-》编译器Complier...

【阅读笔记】MemOS: 大语言模型内存增强生成操作系统

核心速览 研究背景 ​​研究问题​​&#xff1a;这篇文章要解决的问题是当前大型语言模型&#xff08;LLMs&#xff09;在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色&#xff0c;但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成&#xff08;RA…...

Java中栈的多种实现类详解

Java中栈的多种实现类详解&#xff1a;Stack、LinkedList与ArrayDeque全方位对比 前言一、Stack类——Java最早的栈实现1.1 Stack类简介1.2 常用方法1.3 优缺点分析 二、LinkedList类——灵活的双端链表2.1 LinkedList类简介2.2 常用方法2.3 优缺点分析 三、ArrayDeque类——高…...

6.计算机网络核心知识点精要手册

计算机网络核心知识点精要手册 1.协议基础篇 网络协议三要素 语法&#xff1a;数据与控制信息的结构或格式&#xff0c;如同语言中的语法规则语义&#xff1a;控制信息的具体含义和响应方式&#xff0c;规定通信双方"说什么"同步&#xff1a;事件执行的顺序与时序…...

基于Uniapp的HarmonyOS 5.0体育应用开发攻略

一、技术架构设计 1.混合开发框架选型 &#xff08;1&#xff09;使用Uniapp 3.8版本支持ArkTS编译 &#xff08;2&#xff09;通过uni-harmony插件调用原生能力 &#xff08;3&#xff09;分层架构设计&#xff1a; graph TDA[UI层] -->|Vue语法| B(Uniapp框架)B --&g…...

【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录

#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...

五、jmeter脚本参数化

目录 1、脚本参数化 1.1 用户定义的变量 1.1.1 添加及引用方式 1.1.2 测试得出用户定义变量的特点 1.2 用户参数 1.2.1 概念 1.2.2 位置不同效果不同 1.2.3、用户参数的勾选框 - 每次迭代更新一次 总结用户定义的变量、用户参数 1.3 csv数据文件参数化 1、脚本参数化 …...

python基础语法Ⅰ

python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器&#xff0c;来进行一些算术…...

C++11 constexpr和字面类型:从入门到精通

文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用

摘要 神经影像技术对医学科学产生了深远的影响&#xff0c;推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下&#xff0c;基于神经血管耦合现象的多模态神经影像方法&#xff0c;通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里&#xff0c;本研…...

python打卡day49@浙大疏锦行

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...

Qt Quick Controls模块功能及架构

Qt Quick Controls是Qt Quick的一个附加模块&#xff0c;提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中&#xff0c;这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构&#xff0c;与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...

手动给中文分词和 直接用神经网络RNN做有什么区别

手动分词和基于神经网络&#xff08;如 RNN&#xff09;的自动分词在原理、实现方式和效果上有显著差异&#xff0c;以下是核心对比&#xff1a; 1. 实现原理对比 对比维度手动分词&#xff08;规则 / 词典驱动&#xff09;神经网络 RNN 分词&#xff08;数据驱动&#xff09…...

C++中vector类型的介绍和使用

文章目录 一、vector 类型的简介1.1 基本介绍1.2 常见用法示例1.3 常见成员函数简表 二、vector 数据的插入2.1 push_back() —— 在尾部插入一个元素2.2 emplace_back() —— 在尾部“就地”构造对象2.3 insert() —— 在任意位置插入一个或多个元素2.4 emplace() —— 在任意…...

计算机系统结构复习-名词解释2

1.定向&#xff1a;在某条指令产生计算结果之前&#xff0c;其他指令并不真正立即需要该计算结果&#xff0c;如果能够将该计算结果从其产生的地方直接送到其他指令中需要它的地方&#xff0c;那么就可以避免停顿。 2.多级存储层次&#xff1a;由若干个采用不同实现技术的存储…...

HTML中各种标签的作用

一、HTML文件主要标签结构及说明 1. <&#xff01;DOCTYPE html> 作用&#xff1a;声明文档类型&#xff0c;告知浏览器这是 HTML5 文档。 必须&#xff1a;是。 2. <html lang“zh”>. </html> 作用&#xff1a;包裹整个网页内容&#xff0c;lang"z…...

CVE-2023-25194源码分析与漏洞复现(Kafka JNDI注入)

漏洞概述 漏洞名称&#xff1a;Apache Kafka Connect JNDI注入导致的远程代码执行漏洞 CVE编号&#xff1a;CVE-2023-25194 CVSS评分&#xff1a;8.8 影响版本&#xff1a;Apache Kafka 2.3.0 - 3.3.2 修复版本&#xff1a;≥ 3.4.0 漏洞类型&#xff1a;反序列化导致的远程代…...

统计学(第8版)——统计抽样学习笔记(考试用)

一、统计抽样的核心内容与问题 研究内容 从总体中科学抽取样本的方法利用样本数据推断总体特征&#xff08;均值、比率、总量&#xff09;控制抽样误差与非抽样误差 解决的核心问题 在成本约束下&#xff0c;用少量样本准确推断总体特征量化估计结果的可靠性&#xff08;置…...

Copilot for Xcode (iOS的 AI辅助编程)

Copilot for Xcode 简介Copilot下载与安装 体验环境要求下载最新的安装包安装登录系统权限设置 AI辅助编程生成注释代码补全简单需求代码生成辅助编程行间代码生成注释联想 代码生成 总结 简介 尝试使用了Copilot&#xff0c;它能根据上下文补全代码&#xff0c;快速生成常用…...

Axure零基础跟我学:展开与收回

亲爱的小伙伴,如有帮助请订阅专栏!跟着老师每课一练,系统学习Axure交互设计课程! Axure产品经理精品视频课https://edu.csdn.net/course/detail/40420 课程主题:Axure菜单展开与收回 课程视频:...

Docker、Wsl 打包迁移环境

电脑需要开启wsl2 可以使用wsl -v 查看当前的版本 wsl -v WSL 版本&#xff1a; 2.2.4.0 内核版本&#xff1a; 5.15.153.1-2 WSLg 版本&#xff1a; 1.0.61 MSRDC 版本&#xff1a; 1.2.5326 Direct3D 版本&#xff1a; 1.611.1-81528511 DXCore 版本&#xff1a; 10.0.2609…...

RabbitMQ 各类交换机

为什么要用交换机&#xff1f; 交换机用来路由消息。如果直发队列&#xff0c;这个消息就被处理消失了&#xff0c;那别的队列也需要这个消息怎么办&#xff1f;那就要用到交换机 交换机类型 1&#xff0c;fanout&#xff1a;广播 特点 广播所有消息​​&#xff1a;将消息…...

高保真组件库:开关

一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...

未授权访问事件频发,我们应当如何应对?

在当下&#xff0c;数据已成为企业和组织的核心资产&#xff0c;是推动业务发展、决策制定以及创新的关键驱动力。然而&#xff0c;未授权访问这一隐匿的安全威胁&#xff0c;正如同高悬的达摩克利斯之剑&#xff0c;时刻威胁着数据的安全&#xff0c;一旦触发&#xff0c;便可…...

Easy Excel

Easy Excel 一、依赖引入二、基本使用1. 定义实体类&#xff08;导入/导出共用&#xff09;2. 写 Excel3. 读 Excel 三、常用注解说明&#xff08;完整列表&#xff09;四、进阶&#xff1a;自定义转换器&#xff08;Converter&#xff09; 其它自定义转换器没生效 Easy Excel在…...

欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!

多连接 BLE 怎么设计服务不会乱&#xff1f;分层思维来救场&#xff01; 作者按&#xff1a; 你是不是也遇到过 BLE 多连接时&#xff0c;调试现场像网吧“掉线风暴”&#xff1f; 温度传感器连上了&#xff0c;心率带丢了&#xff1b;一边 OTA 更新&#xff0c;一边通知卡壳。…...