简单强大的时序图绘制工具

news2024/11/16 12:48:57

今天分享一个简单强大的时序图绘制工具——WaveDrom。

WaveDrom

Digital Timing Diagram everywhere

WaveDrom draws your Timing Diagram or Waveform from simple textual description.
It comes with description language, rendering engine and the editor.
WaveDrom editor works in the browser or can be installed on your system.
Rendering engine can be embeded into any webpage.

Wavedrom 是一款功能强大且简单易用的文本转图表工具,被广泛应用于生成时序图、波形图等交互式波形。其特点在于使用简单的文本语法,使得开发人员能够以可视化的方式表示数字信号和时间序列数据。Wavedrom 的优势在于其高度灵活性和可扩展性,使用户能够快速绘制复杂的波形和图表,并轻松与其他文档和代码进行整合。

Wavedrom 的基本语法相对简单,以 JSON 对象或简洁的文本描述波形和时序信息。开发人员只需编写简短的描述,即可生成直观的波形图。通过使用不同的标记和元素,用户可以定义时序图中的信号波形、时钟周期、状态转换等内容。Wavedrom 支持自定义样式和布局,用户可以根据需求美化波形图,增加标签和注释以增强可读性。

时序图是 Wavedrom 最常见的用途之一,通过 Wavedrom 绘制的时序图可以清晰地展示数字信号和数据的传输过程。例如,在硬件设计中,时序图可以用于描述寄存器读写、信号传输和时钟脉冲的情况,从而帮助开发人员更好地理解和分析系统的工作状态。

值得一提的是,Wavedrom 不仅可以独立使用,还可以与 Markdown 等文档格式无缝整合。通过将 Wavedrom 图表代码嵌入文档中,开发人员可以直接在文档中呈现交互式的波形图,提升文档的可读性和交互性。

总体来说,Wavedrom 是一个强大而简便的文本转图表工具,适用于各种应用场景,如硬件设计、软件开发、文档编写等。其简单的语法和可视化的输出,为开发人员提供了一个高效、直观的工具,帮助他们更好地表达和展示数字信号和时间序列数据。

用法和示例

WaveDrom是一个基于JavaScript的应用程序。WaveJSON是一种描述数字时序图的格式。WaveDrom可以直接在浏览器中渲染这些图表。"signal"元素是WaveLane的数组。每个WaveLane都有两个必填字段:“name"和"wave”。

WaveDrom是一个强大的工具,可用于可视化数字信号和时序数据。通过使用WaveJSON格式来描述信号波形,用户可以轻松地定义时序图的各个部分,包括信号波形的名称、周期和状态。WaveDrom支持多个WaveLane,可以同时显示多个信号波形,从而实现更复杂的时序图表。

“wave"字段是WaveLane的关键部分,用于定义信号波形。它由一系列字符组成,包括数字0和1,代表数字信号的高和低电平,以及”.",代表未定义或无效状态。此外,WaveDrom还支持其他特殊字符,如"p"代表时钟周期,“n"代表一个时钟周期内的半个周期,”|"用于分隔不同的时钟周期。

通过将这些WaveLane组合成一个"signal"数组,并为每个WaveLane指定名称和波形描述,用户可以创建详细且直观的数字时序图。WaveDrom渲染引擎会将这些描述解析并在浏览器中实时绘制出时序图形。

总的来说,WaveDrom提供了一种简单但强大的方式,通过WaveJSON格式和WaveLane的组织,使用户能够在浏览器中生成各种数字时序图。它在硬件设计、嵌入式系统开发、通信协议分析等领域中有着广泛的应用,帮助开发人员更好地理解和分析数字信号的行为和传输过程。

信号

从一个简单的例子开始。下面的代码将创建一个名为"Alfa"的1位信号,并随时间改变其状态。

{ "signal": [{ "name": "Alfa", "wave": "01.zx=ud.23.456789" }] }

在"wave"字符串中,每个字符代表一个时间周期。符号"."将前一个状态延续一个周期。现在,让我们看一下它的图示:

"Alfa" 1位信号

时钟

数字时钟是一种特殊类型的信号。它在每个时间周期内变化两次,可以具有正极性或负极性。此外,它还可以在工作边沿上带有可选的标记。时钟的各个块可以与其他信号状态混合,以创建时钟门控效果。下面是代码和生成的图示:

{ "signal": [
  { "name": "pclk", "wave": "p......." },
  { "name": "Pclk", "wave": "P......." },
  { "name": "nclk", "wave": "n......." },
  { "name": "Nclk", "wave": "N......." },
  {},
  { "name": "clk0", "wave": "phnlPHNL" },
  { "name": "clk1", "wave": "xhlhLHl." },
  { "name": "clk2", "wave": "hpHplnLn" },
  { "name": "clk3", "wave": "nhNhplPl" },
  { "name": "clk4", "wave": "xlh.L.Hx" },
]}

渲染后的时钟图示如下:

时钟信号

合在一起

在典型的时序图中,我们通常会包含时钟信号和其他信号(线路)。对于多位信号,我们可以从"data"数组中获取相应的标签。

下面是一个例子,展示了一个包含时钟信号、多位信号和单位信号的典型时序图:

{ "signal": [
  { "name": "clk", "wave": "P......" },
  { "name": "bus", "wave": "x.==.=x", "data": ["head", "body", "tail", "data"] },
  { "name": "wire", "wave": "0.1..0." }
]}

在这个例子中,我们有三个信号:"clk"代表时钟信号,"bus"代表多位信号,"wire"代表单位信号。

  • 时钟信号"clk"用"P"表示,代表正极性的时钟边沿。
  • 多位信号"bus"用"x.==.=x"表示,其中"x"表示未定义的状态,"=“表示稳定的高电平或低电平,”."表示未稳定状态。"data"数组包含多位信号的标签,分别是:“head”、“body”、“tail"和"data”。
  • 单位信号"wire"用"0.1…0."表示,表示在时间周期内信号从低电平切换到高电平再切换回低电平。

渲染后的时序图如下:

典型时序信号

空白和间隙

在时序图中,我们有时需要添加间距和空白,以便更好地组织信号和使时序图更易于阅读。下面是一个带有间距和空白的时序图示例:

{ "signal": [
  { "name": "clk", "wave": "p.....|..." },
  { "name": "Data", "wave": "x.345x|=.x", "data": ["head", "body", "tail", "data"] },
  { "name": "Request", "wave": "0.1..0|1.0" },
  {},
  { "name": "Acknowledge", "wave": "1.....|01." }
]}

在这个例子中,我们添加了一些间距和空白,以便更好地分隔不同的信号。

  • “clk"信号用"p"表示,代表正极性时钟边沿,后面有3个间距”.“,然后是”|…",代表3个空白周期。
  • “Data"信号由"x”、“=”、“.“组成,数据数组"data"提供了多位信号各个部分的标签:“head”、“body”、“tail"和"data”。后面有一个间距”|”,然后是"=.",代表一个空白周期后紧跟着一个稳定高电平。
  • “Request"信号由"0”、“1”、“.“组成,代表低电平、高电平和未定义状态。后面有一个间距”|”,然后是"1.0",代表一个高电平后紧跟着一个空白周期。
  • 接着有一个空白行,表示两个信号之间的空白。
  • 最后,“Acknowledge"信号由"1”、“.“组成,后面有一个间距”|”,然后是"01.",代表一个高电平后紧跟着一个低电平和一个空白周期。

渲染后的时序图如下:

带间隙的时序图

在这个时序图中,我们可以看到信号之间的间距和空白,使得时序图更加整齐和易读。通过添加适当的间距和空白,我们可以更好地组织信号和时钟边沿,使时序图更具可视化效果。接下来,我们将继续探索WaveDrom的其他高级功能和实际应用,帮助您更好地运用这个强大的文本转图表工具。

分组

在时序图中,我们可以将WaveLane组合成具有名称的分组,分组表示为数组形式。['分组名称', {...}, {...}, ...] 数组的第一个条目是分组的名称。分组之间还可以嵌套。

下面是一个包含分组的时序图示例:

{ "signal": [
  { "name": "clk", "wave": "p..Pp..P" },
  ["Master",
    ["ctrl",
      { "name": "write", "wave": "01.0...." },
      { "name": "read", "wave": "0...1..0" }
    ],
    { "name": "addr", "wave": "x3.x4..x", "data": "A1 A2" },
    { "name": "wdata", "wave": "x3.x....", "data": "D1" },
  ],
  {},
  ["Slave",
    ["ctrl",
      { "name": "ack", "wave": "x01x0.1x" },
    ],
    { "name": "rdata", "wave": "x.....4x", "data": "Q2" },
  ]
]}

在这个例子中,我们使用了分组来组织不同的信号,将它们放在名为"Master"和"Slave"的两个分组中。

  • "clk"信号用"p…Pp…P"表示,代表正极性时钟边沿和负极性时钟边沿。
  • “Master"分组包含了三个子信号,它们分别在名称为"ctrl"的子分组中,表示控制信号"write"和"read”,以及名称为"addr"的信号,"data"数组提供了信号的标签。
  • 接着有一个空白行,表示两个分组之间的空白。
  • “Slave"分组包含了两个子信号,都在名称为"ctrl"的子分组中,表示控制信号"ack”,以及名称为"rdata"的信号,"data"数组提供了信号的标签。

渲染后的时序图如下:

分组时序图

在这个时序图中,我们可以看到不同分组内的信号在不同时间周期内的状态。使用分组可以更好地组织和显示复杂的时序图,帮助我们更好地理解和分析数字信号之间的时序关系。通过WaveDrom的强大功能,我们可以轻松地在时序图中添加分组,使其更具可视化效果和清晰度。

周期和相位

在时序图中,我们可以使用"period"和"phase"参数来调整每个WaveLane的周期和相位。

下面是一个DDR读取事务的时序图示例:

{ "signal": [
  { "name": "CK", "wave": "P.......", "period": 2 },
  { "name": "CMD", "wave": "x.3x=x4x=x=x=x=x", "data": "RAS NOP CAS NOP NOP NOP NOP", "phase": 0.5 },
  { "name": "ADDR", "wave": "x.=x..=x........", "data": "ROW COL", "phase": 0.5 },
  { "name": "DQS", "wave": "z.......0.1010z." },
  { "name": "DQ", "wave": "z.........5555z.", "data": "D0 D1 D2 D3" }
]}

在这个例子中,我们使用"period"参数来设置时钟信号"CK"的周期为2个时间周期。这意味着时钟信号每隔2个时间周期变化一次。

同时,我们使用"phase"参数来调整信号"CMD"和"ADDR"的相位。相位的值为0.5,表示信号的波形在时间轴上整体向右偏移了0.5个时间周期。这样做可以让信号在时钟边沿之前或之后发生状态变化。

"CMD"信号表示了DDR读取事务的命令序列,"ADDR"信号表示了地址序列。"data"数组提供了每个部分的标签。

"DQS"信号和"DQ"信号分别表示数据校验和数据信号。其中,"DQS"信号在时钟边沿之前有一个延迟,"DQ"信号在时钟边沿之后有一个延迟。

渲染后的时序图如下:

DDR读时序

在这个时序图中,我们可以看到时钟信号"CK"每隔2个时间周期发生一次变化。"CMD"和"ADDR"信号的波形整体向右偏移了0.5个时间周期,以达到与时钟信号的相位差。"DQS"信号在时钟边沿之前有一个延迟,"DQ"信号在时钟边沿之后有一个延迟。

通过调整"period"和"phase"参数,我们可以更灵活地控制时序图中各个信号的周期和相位,从而更好地表达复杂的数字信号行为。WaveDrom提供了丰富的功能,帮助我们创建详细和直观的数字时序图,用于硬件设计、嵌入式系统开发、通信协议分析等领域。

config{}属性

在时序图中,config{}属性用于控制渲染的不同方面。

hscale

config:{hscale:#}属性用于调整时序图的水平缩放比例。用户可以设置任何大于0的整数值。

下面是一个示例,展示了如何使用config{hscale:#}属性来调整时序图的水平缩放比例:

{ "signal": [
  { "name": "clk", "wave": "p...." },
  { "name": "Data", "wave": "x345x", "data": ["head", "body", "tail"] },
  { "name": "Request", "wave": "01..0" }
],
"config": { "hscale": 1 }
}

在这个例子中,我们使用config{hscale:1}属性将水平缩放比例设置为1。这意味着时序图将以原始比例进行渲染,每个时间周期占据一个单位宽度。

渲染后的时序图如下:

水平比例1

水平比例2

skin

在时序图中,我们可以使用config:{skin:'...'}属性来选择WaveDrom的皮肤样式。该属性仅在页面上的第一个时序图中起作用。WaveDrom编辑器包含两种标准皮肤:‘default’和’narrow’。

head/foot

head:{...}foot:{...}属性用于定义时序图上方和下方的内容区域。可以在这些属性中添加文本或其他元素。

tick/tock

tick属性可以添加与垂直标记对齐的时间线标签,而tock属性可以在垂直标记之间添加时间线标签。

text

text属性用于添加标题或说明文本。

every

every属性用于指定仅在每N个周期渲染一次标记和时间线标签。

下面是一个示例,展示了如何使用这些属性来定义一个时序图:

{ "signal": [
  { "name": "clk", "wave": "p...." },
  { "name": "Data", "wave": "x345x", "data": "a b c" },
  { "name": "Request", "wave": "01..0" }
],
"head": {
  "text": "WaveDrom example",
  "tick": 0,
  "every": 2
},
"foot": {
  "text": "Figure 100",
  "tock": 9
}
}

在这个例子中,我们添加了头部(head)和底部(foot)的文本内容。头部文本设置为"WaveDrom example",并使用tick属性指定不添加时间线标签。每隔2个周期渲染一次标记和时间线标签。底部文本设置为"Figure 100",并使用tock属性在垂直标记之间添加时间线标签。

渲染后的时序图如下:

属性示例

在WaveDrom中,head和foot属性用于定义时序图上方和下方的文本内容,这些文本内容支持SVG text的所有属性。可以使用JsonML标记语言来表示SVG文本内容,并且可以使用一些预定义的样式来设置文本的字体大小和颜色。除此之外,还可以使用其他SVG tspan属性来自由地定制文本的样式。

下面是一个示例,展示了如何使用不同的样式来设置时序图头部和底部的文本内容:

{ "signal": [
  { "name": "clk", "wave": "p.....PPPPp...." },
  { "name": "dat", "wave": "x....2345x.....", "data": "a b c d" },
  { "name": "req", "wave": "0....1...0....." }
],
"head": { "text":
  ["tspan",
    ["tspan", { "class": "error h1" }, "error "],
    ["tspan", { "class": "warning h2" }, "warning "],
    ["tspan", { "class": "info h3" }, "info "],
    ["tspan", { "class": "success h4" }, "success "],
    ["tspan", { "class": "muted h5" }, "muted "],
    ["tspan", { "class": "h6" }, "h6 "],
    "default ",
    ["tspan", { "fill": "pink", "font-weight": "bold", "font-style": "italic" }, "pink-bold-italic"]
  ]
},
"foot": { "text":
  ["tspan", "E=mc",
    ["tspan", { "dy": "-5" }, "2"],
    ["tspan", { "dy": "5" }, ". "],
    ["tspan", { "font-size": "25" }, "B "],
    ["tspan", { "text-decoration": "overline" }, "over "],
    ["tspan", { "text-decoration": "underline" }, "under "],
    ["tspan", { "baseline-shift": "sub" }, "sub "],
    ["tspan", { "baseline-shift": "super" }, "super "]
  ], "tock": -5
}
}

在这个例子中,我们使用JsonML标记语言来表示头部和底部的文本内容,并为每个文本段落设置了不同的样式。例如,我们使用了类名"h1"、“h2”、“h3"等来设置不同的字体大小。使用类名"error”、“warning”、“info”、“success”、"muted"等来设置不同的字体颜色样式。我们还可以使用其他SVG tspan属性来设置文本的斜体、粗体、填充颜色等。

渲染后的时序图如下:

head/foot文本属性示例

箭头

曲线

在WaveDrom中,我们可以使用箭头和曲线来连接不同的信号,以表示它们之间的关联和数据传递。

以下是一些常用的箭头和曲线符号:

  • ~:普通曲线
  • -~:从左到右的曲线箭头
  • <~>:双向曲线箭头
  • <~>:双向曲线箭头
  • ~>:从左到右的直线箭头
  • -~>:从左到右的实心箭头
  • ~->:从右到左的实心箭头

下面是一个示例,展示了如何使用箭头和曲线来连接不同的信号:

{ "signal": [
  { "name": "A", "wave": "01........0....", "node": ".a........j" },
  { "name": "B", "wave": "0.1.......0.1..", "node": "..b.......i" },
  { "name": "C", "wave": "0..1....0...1..", "node": "...c....h.." },
  { "name": "D", "wave": "0...1..0.....1.", "node": "....d..g..." },
  { "name": "E", "wave": "0....10.......1", "node": ".....ef...." }
],
"edge": [
  "a~b t1", "c-~a t2", "c-~>d time 3", "d~-e",
  "e~>f", "f->g", "g-~>h", "h~>i some text", "h~->j"
]
}

渲染后的时序图如下:

箭头和曲线

折线

在WaveDrom中,我们还可以使用尖锐的线条符号来表示不同信号之间的连接关系。这些尖锐的线条符号可以更直观地展示信号之间的交互和数据传递。

以下是一些常用的尖锐线条符号:

  • -:直线连接
  • -|:从左到右的尖锐连接
  • |->:从右到左的尖锐连接
  • <->:双向尖锐连接
  • <-|>:从左到右的双向尖锐连接
  • |-|:从左到右的尖锐连接(包含短横线)

下面是一个示例,展示了如何使用尖锐线条来连接不同的信号:

{ "signal": [
  { "name": "A", "wave": "01..0..", "node": ".a..e.." },
  { "name": "B", "wave": "0.1..0.", "node": "..b..d.", "phase": 0.5 },
  { "name": "C", "wave": "0..1..0", "node": "...c..f" },
  { "node": "...g..h" },
  { "node": "...I..J", "phase": 0.5 },
  { "name": "D", "wave": "0..1..0", "phase": 0.5 }
],
"edge": [
  "b-|a t1", "a-|c t2", "b-|-c t3", "c-|->e t4", "e-|>f more text",
  "e|->d t6", "c-g", "f-h", "g<->h 3 ms", "I+J 5 ms"
]
}

在这个例子中,我们有6个信号(A、B、C、D)和4个连接节点(e、g、h、I、J),它们之间通过尖锐线条连接起来。每个信号都有相应的波形图,而尖锐线条则通过edge属性来定义连接关系。

例如,b-|a t1表示从信号B到信号A的从左到右的尖锐连接,并在连接上方添加了文本标签"t1"。c-|->e t4表示从信号C到节点e的从左到右的尖锐连接,并在连接上方添加了文本标签"t4"。

渲染后的时序图如下:

箭头和折线

一些代码

在WaveDrom中,我们可以使用JavaScript代码来生成复杂的时序图。这些代码可以用来生成特定的信号和波形,以及自定义时序图的展示效果。

以下是一个示例代码,展示了如何使用JavaScript代码生成一个特定的时序图:

(function (bits, ticks) {
  var i, t, gray, state, data = [], arr = [];
  for (i = 0; i < bits; i++) {
    arr.push({name: i + '', wave: ''});
    state = 1;
    for (t = 0; t < ticks; t++) {
      data.push(t + '');
      gray = (((t >> 1) ^ t) >> i) & 1;
      arr[i].wave += (gray === state) ? '.' : gray + '';
      state = gray;
    }
  }
  arr.unshift('gray');
  return {signal: [
    {name: 'bin', wave: '='.repeat(ticks), data: data}, arr
  ]};
})(5, 16)

在这个例子中,我们使用了一个自执行函数来生成一个包含5个信号的时序图。每个信号的波形图都是根据格雷码(Gray code)生成的,其中bits参数表示信号的位数,ticks参数表示时间周期数。代码使用循环来生成信号的波形图,并将生成的数据存储在data数组中。

最终的时序图包含6个信号,其中一个是用来表示二进制计数的信号(bin),其波形图是一个等号序列。其他5个信号的波形图是根据格雷码生成的,分别对应0位、1位、2位、3位和4位格雷码的波形。

渲染后的时序图如下:

js代码生成时序图

公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue-7-vuex

一、Vuex 概述 目标&#xff1a;明确Vuex是什么&#xff0c;应用场景以及优势 1.是什么 Vuex 是一个 Vue 的 状态管理工具&#xff0c;状态就是数据。 大白话&#xff1a;Vuex 是一个插件&#xff0c;可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。例如&#xff1a;购…

浅谈内存函数以及模拟实现

1.memcpy void * memcpy ( void * destination, const void * source, size_t num ); 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。 这个函数在遇到 \0 的时候并不会停下来。 如果source和destination有任何的重叠&#xff0c;复制的结果都…

小白学习笔记—网络安全/黑客技术

作为一个合格的网络安全工程师&#xff0c;应该做到攻守兼备&#xff0c;毕竟知己知彼&#xff0c;才能百战百胜。 谈起黑客&#xff0c;可能各位都会想到&#xff1a;盗号&#xff0c;其实不尽然&#xff1b;黑客是一群喜爱研究技术的群体&#xff0c;在黑客圈中&#xff0c;一…

【HomeKit】HAT User Manual教程

前言&#xff1a;这篇文章是对于苹果协议文件《HomeKit Accessory Tester (HAT) User Manual》的学习&#xff0c;即 HomeKit配件测试仪(HAT) 用户手册&#xff0c;该版本是第11次修订 第一章 概述 本文档介绍了Apple HomeKit配件测试仪(HAT)的配置和使用方法。HAT是一个Mac应…

家政系统开发,家政保洁维修预约小程序开发;

家政系统是家政行业的专业管理系统软件&#xff0c;功能涉及到家政公司运营的方方面面&#xff0c;包括&#xff1a;推广、营销、管理、培训、周边服务等等&#xff1b; 家政系统功能介绍&#xff1a; 系统集成分销客户裂变、微信推广、团购引流、热文海报推广、短视频引流、搜…

Camera metadata

目录 背景 CameraMetadata基本概念 Google Metadata Google—Metadata结构 官方注释 Aandroid API cameraMetadata头部 : struct camera_metadata camera_metadata_buffer_entry struct camera_metadata_entry data区为什么是一个联合体&#xff1f; camera metadat…

什么是Fetch API?与传统的AJAX相比,有什么优势?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

3分钟学会批量查询快递秘籍

随着网购的普及&#xff0c;我们经常需要查询快递来了解自己的包裹状态。然而&#xff0c;如果一个个手动查询&#xff0c;不仅费时而且麻烦。这时候&#xff0c;一款能够批量查询快递的软件就变得尤为重要。今天&#xff0c;我将向大家介绍一款名为“固乔快递查询助手”的软件…

Linux知识点 -- 网络基础 -- 数据链路层

Linux知识点 – 网络基础 – 数据链路层 文章目录 Linux知识点 -- 网络基础 -- 数据链路层一、数据链路层1.以太网2.以太网帧格式3.重谈局域网原理4.MAC地址5.MTU6.查看硬件地址和MTU的命令7.ARP协议 二、其他重要协议或技术1.DNS&#xff08;Domain Name System&#xff09;2.…

2008-2020年中国区域二氧化氮产品

简介&#xff1a; 针对OMI 2008-2020年数据中因行异常或者云造成缺失的对流程NO2数据进行填补&#xff0c;利用面积权重法将OMI和GOME数据统一重采样至0.25度的空间分辨率。前言 – 人工智能教程 二氧化氮&#xff08;Nitrogen Dioxide&#xff0c;简称NO2&#xff09;是一种…

Java每日笔试题错题分析(1)

Java每日笔试题错题分析&#xff08;1&#xff09; 一、错题知识点前瞻第26题第29题第34题第41题第50题 二、错题展示及其解析第26题第29题第34题第41题第50题 一、错题知识点前瞻 第26题 多个catch块中子类异常放在前面&#xff0c;父类异常放在后面&#xff0c;否则会产生编…

ssm173基于SSM的养老院老人健康监护平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

保姆级微服务部署教程

大家好&#xff0c;我是鱼皮。 项目上线是每位学编程同学必须掌握的基本技能。之前我已经给大家分享过很多种上线单体项目的方法了&#xff0c;今天再出一期微服务项目的部署教程&#xff0c;用一种最简单的方法&#xff0c;带大家轻松部署微服务项目。 开始之前&#xff0c;…

《安富莱嵌入式周报》第324期:单对以太网技术实战,IROS2023迪士尼逼真机器人展示,数百万模具CAD文件下载,闭环步进电机驱动器,CANopen全解析

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 更新一期视频教程&#xff1a; 第8期ThreadX视频教程&#xff1a;应用实战&#xff0c;将裸机工程移植到RTOS的任务划分…

自助建站系统,一建建站系统api版,自动建站

安装推荐php7.2或7.2以下都行 可使用虚拟主机或者服务器进行搭建。 分站进入网站后台 域名/admin 初始账号123456qq.com密码123456 找到后台的网站设置 将主站域名及你在主站的通信secretId和通信secretKey填进去。 即可正常使用 通信secretId和通信secretKey在主站的【账号…

【Proteus仿真】【STM32单片机】病床呼叫系统设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用LCD1602液晶、按键、蜂鸣器LED、双机通信等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示开机界面&#xff0c;当从机病床按键按…

ExoPlayer架构详解与源码分析(4)——整体架构

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player ExoPlayer架构详解与源码分析&#xff08;3&#xff09;——Timeline ExoPlayer架构详解与源码分析&#xff08;4&#xff09;—…

0-1背包理论基础详解

0-1背包问题&#xff1a;有 n 种物品&#xff0c;每种物品只有1个&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 图片来自&#xff1a;代码随想录 0-1背包问题举例&#xff1a; 题目描述&#xff1a; 使用二维dp数组解决背包问题 动规五部曲&#xff1a; dp[i][j…

智能工厂MES系统,终端设备支持手机、PDA、工业平板、PC

一、开源项目简介 源计划智能工厂MES系统(开源版) 功能包括销售管理&#xff0c;仓库管理&#xff0c;生产管理&#xff0c;质量管理&#xff0c;设备管理&#xff0c;条码追溯&#xff0c;财务管理&#xff0c;系统集成&#xff0c;移动端APP。 二、开源协议 使用GPL-3.0开…

【python海洋专题十四】读取多个盐度nc数据画盐度季节变化图

本期内容 读取多个盐度文件&#xff1b;拼接数据在画盐度的季节分布图Part01. 使用数据 IAP 网格盐度数据集 数据详细介绍&#xff1a; 见文件附件&#xff1a; pages/file/dl?fid378649712527544320 全球温盐格点数据.pdf IAP_Global_ocean_gridded_product.pdf 全球温…