悄悄告诉你哦,帮你整理了一份PCB设计的Checklist

一点电子 2023-09-23 09:31
点击👆一点电子👇关注我,右上角“...设为 星标★技术干货第一时间送达!

     No.1:资料输入阶段


  • 在流程上接收到的资料是否齐全(包括:原理图、*.brd文件、料单、PCB设计说明以及PCB设计或更改要求、标准化要求说明、工艺设计说明等文件)。
  • 确认PCB模板是最新的。
  • 时钟器件布局是否合理。
  • 确认模板的定位器件位置无误。
  • PCB设计说明以及PCB设计或更改要求、标准化是否明确。
  • 确认外形图上的禁止布放器件和布线区已在PCB模板上体现。
  • 比较外形图,确认PCB所标注尺寸及公差无误,金属化孔和非金属化孔定义准确。
  • 确认PCB模板准确无误后最好锁定该结构文件,以免误操作被移动位置。


No.2:布局后检查阶段


01

器件检查

  • 确认所有器件封装是否与公司统一库一致,是否已更新封装库(用viewlog检查运行结果)如果不一致,一定要更新Symbols。
  • 母板与子板,单板与背板,确认信号对应,位置对应,连接器方向及丝印标识正确,且子板有防误插措施,子板与母板上的器件不应产生干涉。
  • 元器件是否100%放置。
  • 打开器件TOP和BOTTOM层的place-bound, 查看重叠引起的DRC是否允许。
  • Mark点是否足够且必要。
  • 较重的元器件,应该布放在靠近PCB支撑点或支撑边的地方,以减少PCB的翘曲。
  • 与结构相关的器件布好局后最好锁住,防止误操作移动位置。
  • 压接插座周围5mm范围内,正面不允许有高度超过压接插座高度的元件,背面不允许有元件或焊点。
  • 确认器件布局是否满足工艺性要求(重点关注BGA、PLCC、贴片插座)。
  • 金属壳体的元器件,特别注意不要与其它元器件相碰,要留有足够的空间位置。
  • 接口相关的器件尽量靠近接口放置,背板总线驱动器尽量靠近背板连接器放置。
  • 波峰焊面的CHIP器件是否已经转换成波峰焊封装。
  • 手工焊点是否超过50个。
  • 在PCB上轴向插装较高的元件,应该考虑卧式安装。留出卧放空间。并且考虑固定方式,如晶振的固定焊盘。
  • 需要使用散热片的器件,确认与其它器件有足够间距,并且注意散热片范围内主要器件的高度。

02

功能检查

  • 数模混合板的数字电路和模拟电路器件布局时是否已经分开,信号流是否合理。
  • A/D转换器跨模数分区放置。
  • 时钟器件布局是否合理。
  • 高速信号器件布局是否合理。
  • 端接器件是否已合理放置(源端匹配串阻应放在信号的驱动端;中间匹配的串阻放在中间位置;终端匹配串阻应放在信号的接收端)
  • 信号线以不同电平的平面作为参考平面,当跨越平面分割区域时,参考平面间的连接电容是否靠近信号的走线区域。
  • 保护电路的布局是否合理,是否利于分割。单板电源的保险丝是否放置在连接器附近,且前面没有任何电路元件。
  • 确认强信号与弱信号(功率相差30dB)电路分开布设。
  • IC器件的去耦电容数量及位置是否合理。
  • 是否按照设计指南或参考成功经验放置可能影响EMC实验的器件。如:面板的复位电路要稍靠近复位按钮。

03

发热

  • 对热敏感的元件含液态介质电容、晶振尽量远离大功率的元器件、散热器等热源。
  • 布局是否满足热设计要求,散热通道(根据工艺设计文件来执行

04

电源

  • 是否IC电源距离IC过远。
  • LDO及周围电路布局是否合理。
  • 模块电源等周围电路布局是否合理。
  • 电源的整体布局是否合理。

05

规则设置

  • 是否所有仿真约束都已经正确加到Constraint Manager中。
  • 是否正确设置物理和电气规则(注意电源网络和地网络的约束设置
  • Test Via、Test Pin的间距设置是否足够。
  • 叠层的厚度和方案是否满足设计和加工要求。
  • 所有有特性阻抗要求的差分线阻抗是否已经经过计算,并用规则控制。

No.3:布线后检查阶段


01

数模

  • 数字电路和模拟电路的走线是否已分开,信号流是否合理。
  • A/D、D/A以及类似的电路如果分割了地,那么电路之间的信号线是否从两地之间的桥接点上走(差分线例外)。
  • 必须跨越分割电源之间间隙的信号线应参考完整的地平面。
  • 如果采用地层设计分区不分割方式,要确保数字信号和模拟信号分区布线。

02

时钟和高速部分

  • 高速信号线的阻抗各层是否保持一致。
  • 高速差分信号线和类似信号线,是否等长、对称、就近平行地走线。
  • 确认时钟线尽量走在内层。
  • 确认时钟线、高速线、复位线及其它强辐射或敏感线路是否已尽量按3W原则布线。
  • 时钟、中断、复位信号、百兆/千兆以太网、高速信号上是否没有分叉的测试点。
  • LVDS等低电平信号与TTL/CMOS信号之间是否尽量满足了10H(H为信号线距参考平面的高度)。
  • 时钟线以及高速信号线是否避免穿越密集通孔过孔区域或器件引脚间走线。
  • 时钟线是否已满足(SI约束)要求(时钟信号走线是否做到少打过孔、走线短、参考平面连续,主要参考平面尽量是GND;若换层时变换了GND主参考平面层,在离过孔200mil范围之内是GND过孔;若换层时变换不同电平的主参考平面,在离过孔200mil范围之内是否有去耦电容)。
  • 差分对、高速信号线、各类BUS是否已满足(SI约束)要求。

03

EMC与可靠性

  • 对于晶振,是否在其下布一层地;是否避免了信号线从器件管脚间穿越;对高速敏感器件,是否避免了信号线从器件管脚间穿越。
  • 单板信号走线上不能有锐角和直角(一般成 135 度角连续转弯,射频信号线最好采用圆弧形或经过计算以后的切角铜箔)。
  • 对于双面板,检查高速信号线是否与其回流地线紧挨在一起布线;对于多层板,检查高速信号线是否尽量紧靠地平面走线。
  • 对于相邻的两层信号走线,尽量垂直走线。
  • 避免信号线从电源模块、共模电感、变压器、滤波器下穿越。
  • 尽量避免高速信号在同一层上的长距离平行走线。
  • 板边缘还有数字地、模拟地、保护地的分割边缘是否有加屏蔽过孔;多个地平面是否用过孔相连;过孔距离是否小于最高频率信号波长的1/20。
  • 浪涌抑制器件对应的信号走线是否在表层短且粗。
  • 确认电源、地层无孤岛、无过大开槽、无由于通孔隔离盘过大或密集过孔所造成的较长的地平面裂缝、无细长条和通道狭窄现象。
  • 是否在信号线跨层比较多的地方,放置了地过孔(至少需要两个地平面)。

04

电源和地

  • 如果电源/地平面有分割,尽量避免分割开的参考平面上有高速信号的跨越。
  • 确认电源、地能承载足够的电流。过孔数量是否满足承载要求(估算方法:外层铜厚1oz时1A/mm线宽,内层0.5A/mm线宽,短线电流加倍)。
  • 对于有特殊要求的电源,是否满足了压降的要求。
  • 为降低平面的边缘辐射效应,在电源层与地层间要尽量满足20H原则(条件允许的话,电源层的缩进得越多越好)。
  • 如果存在地分割,分割的地是否不构成环路。
  • 相邻层不同的电源平面是否避免了交叠放置。
  • 保护地、-48V地及GND的隔离是否大于2mm。
  • -48V地是否只是-48V的信号回流,没有汇接到其他地;如果做不到请在备注栏说明原因。
  • 靠近带连接器面板处是否布10~20mm的保护地,并用双排交错孔将各层相连。
  • 电源线与其他信号线间距是否距离满足安规要求。

05

禁布区

  • 金属壳体器件和散热器件下,不应有可能引起短路的走线、铜皮和过孔。
  • 安装螺钉或垫圈的周围不应有可能引起短路的走线、铜皮和过孔。
  • 设计要求中预留位置是否有走线。
  • 非金属化孔内层离线路及铜箔间距应大于0.5mm(20mil),外层0.3mm(12mil),单板起拔扳手轴孔内层离线路及铜箔间距应大于2mm(80mil)。
  • 铜皮和线到板边 推荐为大于2mm 最小为0.5mm。
  • 内层地层铜皮到板边 1 ~ 2 mm, 最小为0.5mm。

06

焊盘出线

  • 对于两个焊盘安装的CHIP元件(0805及其以下封装),如电阻、电容,与其焊盘连接的印制线最好从焊盘中心位置对称引出,且与焊盘连接的印制线必须具有一样的宽度,对于线宽小于0.3mm(12mil)的引出线可以不考虑此条规定。
  • 与较宽印制线连接的焊盘,中间最好通过一段窄的印制线过渡(0805及其以下封装)。
  • 线路应尽量从SOIC、PLCC、QFP、SOT等器件的焊盘的两端引出。

07

丝印

  • 器件位号是否遗漏,位置是否能正确标识器件。
  • 器件位号是否符合公司标准要求。
  • 确认器件的管脚排列顺序、第1脚标志、器件的极性标志、连接器的方向标识的正确性。
  • 母板与子板的插板方向标识是否对应。
  • 背板是否正确标识了槽位名、槽位号、端口名称、护套方向。
  • 确认设计要求的丝印添加是否正确。
  • 确认已经放置有防静电和射频板标识(射频板使用)。

08

编码/条码

  • 确认PCB编码正确且符合公司规范。
  • 确认单板的PCB编码位置和层面正确(应该在A面左上方,丝印层)。
  • 确认背板的PCB编码位置和层面正确(应该在B右上方,外层铜箔面)。
  • 确认有条码激光打印白色丝印标示区。
  • 确认条码框下面没有连线和大于0.5mm导通孔。
  • 确认条码白色丝印区外20mm范围内不能有高度超过25mm的元器件。

09

过孔

  • 在回流焊面,过孔不能设计在焊盘上(常开窗的过孔与焊盘的间距应大于0.5mm (20mil),绿油覆盖的过孔与焊盘的间距应大于0.1 mm (4mil),方法:将Same Net DRC打开,查DRC,然后关闭Same Net DRC)。
  • 过孔的排列不宜太密,避免引起电源、地平面大范围断裂。
  • 钻孔的过孔孔径最好不小于板厚的1/10。

10

工艺

  • 器件布放率是否100%,布通率是否100%(没有达到100%的需要在备注中说明)。
  • Dangling线是否已经调整到最少,对于保留的Dangling线已做到一一确认。
  • 工艺科反馈的工艺问题是否已仔细查对。

11

大面积铜箔

  • 对于Top、bottom上的大面积铜箔,如无特殊的需要,应用网格铜(单板用斜网,背板用正交网,线宽0.3mm (12 mil)、间距0.5mm (20mil))。
  • 大面积铜箔区的元件焊盘,应设计成花焊盘,以免虚焊;有电流要求时,则先考虑加宽花焊盘的筋,再考虑全连接。
  • 大面积布铜时,应该尽量避免出现没有网络连接的死铜(孤岛)。
  • 大面积铜箔还需注意是否有非法连线,未报告的DRC。

12

测试点

  • 各种电源、地的测试点是否足够(每2A电流至少有一个测试点)。
  • 确认没有加测试点的网络都是经确认可以进行精简的。
  • 确认没有在生产时不安装的插件上设置测试点。
  • Test Via、Test Pin是否已Fix(适用于测试针床不变的改板)。

13

DRC

  • Test via 和Test pin 的Spacing Rule应先设置成推荐的距离,检查DRC,若仍有DRC存在,再用最小距离设置检查DRC。
  • 打开约束设置为打开状态,更新DRC,查看DRC中是否有不允许的错误。
  • 确认DRC已经调整到最少,对于不能消除DRC要一一确认。

14

光学定位点

  • 确认有贴装元件的PCB面已有光学定位符号。
  • 确认光学定位符号未压线(丝印和铜箔走线)。
  • 光学定位点背景需相同,确认整板使用光学点其中心离边≥5mm。
  • 确认整板的光学定位基准符号已赋予坐标值(建议将光学定位基准符号以器件的形式放置),且是以毫米为单位的整数值。
  • 管脚中心距<0.5mm的IC,以及中心距小于0.8 mm(31 mil)的BGA器件,应在元件对角线附近位置设置光学定位点

15

阻焊检查

  • 确认是否有特殊需求类型的焊盘都正确开窗(尤其注意硬件的设计要求)。
  • BGA下的过孔是否处理成盖油塞孔。
  • 除测试过孔外的过孔是否已做开小窗或盖油塞孔。
  • 光学定位点的开窗是否避免了露铜和露线。
  • 电源芯片、晶振等需铜皮散热或接地屏蔽的器件,是否有铜皮并正确开窗。由焊锡固定的器件应有绿油阻断焊锡的大面积扩散。

16

钻孔图

  • Notes的PCB板厚、层数、丝印的颜色、翘曲度,以及其他技术说明是否正确。
    叠板图的层名、叠板顺序、介质厚度、铜箔厚度是否正确;是否要求作阻抗控制,描述是否准确;叠板图的层名与其光绘文件名是否一致。
  • 将设置表中的Repeat code 关掉,钻孔精度应设置为2-5。
  • 孔表和钻孔文件是否最新(改动孔时,必须重新生成)。
  • 孔表中是否有异常的孔径,压接件的孔径是否正确;孔径公差是否标注正确。
  • 要塞孔的过孔是否单独列出,并标注“filled vias”。

17

光绘

  • 光绘文件输出尽量采用RS274X格式,且精度应设置为5:5。
  • art_aper.txt 是否已最新(274X可以不需要)。
  • 输出光绘文件的log文件中是否有异常报告。
  • 负片层的边缘及孤岛确认。
  • 使用光绘检查工具检查光绘文件是否与PCB 相符(改板要使用比对工具进行比对)。

18

文件齐套

  • PCB文件:产品型号_规格_单板代号_版本号.brd。
  • 背板的衬板设计文件:产品型号_规格_单板代号_版本号-CB[-T/B].brd。
  • PCB加工文件:PCB编码.zip(含各层的光绘文件、光圈表、钻孔文件及ncdrill.log;拼板还需要有工艺提供的拼板文件*.dxf),背板还要附加衬板文件:PCB编码-CB[-T/B].zip(含drill.art、*.drl、ncdrill.log)。
  • 工艺设计文件:产品型号_规格_单板代号_版本号-GY.doc。
  • SMT坐标文件:产品型号_规格_单板代号_版本号-SMT.txt(输出坐标文件时,确认选择 Body center,只有在确认所有SMD器件库的原点是器件中心时,才可选Symbol origin)。
  • PCB板结构文件:产品型号_规格_单板代号_版本号-MCAD.zip(包含结构工程师提供的.DXF与.EMN文件)。
  • 测试文件:产品型号_规格_单板代号_版本号-TEST.ZIP(包含testprep.log 和 untest.lst或者*.drl测试点的坐标文件)。
  • 归档图纸文件:产品型号规格-单板名称-版本号.pdf(包括:封面、首页、各层丝印、各层线路、钻孔图、背板含有衬板图)。

19

标准化

  • 确认封面、首页信息正确。
  • 确认图纸序号(对应PCB各层顺序分配)正确的。
  • 确认图纸框上PCB编码是正确的。 

—— End ——
免责声明:本号对所有原创、转载文章的陈述与观点均保持中立,推送文章仅供读者学习和交流。文章、图片等版权归原作者享有,如有侵权,联系删除。    

#推荐阅读#   点击蓝色字体即可跳转

  • 单片机按键如何进行硬件消抖?

  • 这元器件切开后,也太惊呆了吧!

  • 如何避免电源设计中的电感饱和

  • 好文分享--LDO基础知识详解(二)

  • 大厂毕业!找不到工作,要降薪去小厂吗?




长按识别二维码关注我

后台回复“加群,管理员拉你加入同行技术交流群。


点个在看让我知道你喜欢今天的内容



一点电子 一点电子,专注于电子硬件技术的学习和分享。分享技术,生活乐趣、职场百态,每天进步一点点!
评论 (0)
  • 托马斯微积分第十版中文
    电子书为扫描版本,自己手动添加书签作为目录供参考
  • RadarSensors_ARS408-21_cn数据手册
    RadarSensors_ARS408-21_cn数据手册
  • Geehy极海微控制器选型手册
    Geehy极海微控制器选型手册,产品基于Arm® Cortex®-M0+/M3/M4F/RISC-V内核,覆盖工业级/车规级/电机控制专用以及无线MCU,丰富的产品组合阵营,满足客户多样化产品应用需求!
  • RadarSensors_ARS308-21_cn数据手册
    RadarSensors_ARS308-21_cn数据手册
  • RadarSensors_ARS404-21_cn数据手册​
    RadarSensors_ARS404-21_cn数据手册
  • 首个基于Transformer的分割检测+视觉大模型视频课程(23年新课+源码+课件)
    自动驾驶是高安全型应用,需要高性能和高可靠的深度学习模型,Vision Transformer是理想的选摔。现在主流的自动驾驶感知算法基本都使用了Vision Transformer相关技术,比如分割、2D/3D检测,以及最近大火的大模型 (如SAM),Vision Transformer在自动驾驶领域的落地方面遍地开花。5一方面,在自动驾驶或图像处理相关算法岗位的面试题中,Vision Transformer是必考题,需要对其理论知识有深入理解,并且在项目中真实的使用过相关技术。

    Transformer出自于Google于2017年发表的论文《Attention is all you need》,最开始是用于机器翻译,并且取得了非常好的效果。但是自提出以来,Transformer不仅仅在NLP领域大放异彩,并且在CV、RS等领域也取得了非常不错的表现。尤其是2020年,绝对称得上是Transformer的元年,比如在CV领域,基于Transformer的模型横扫各大榜单,完爆基于CNN的模型。为什么Transformer模型表现如此优异?它的原理是什么?它成功的关键又包含哪些?本文将简要地回答一下这些问题。

    我们知道Transformer模型最初是用于机器翻译的,机器翻译应用的输入是某种语言的一个句子,输出是另外一种语言的句子。
    var i *int = nil
    fmt.Println("i.size:", unsafe.Sizeof(i)) //8

    var i8 *int8 = nil
    fmt.Println("i8.size:", unsafe.Sizeof(i8)) //8

    var s *string = nil
    fmt.Println("s.size:", unsafe.Sizeof(s)) //8

    var ps *struct{} = nil
    fmt.Println("ps.size:", unsafe.Sizeof(ps)) //8

    var si []int = nil
    var si1 []int = nil
    fmt.Println("si.size:", unsafe.Sizeof(si)) //24

    var ii interface{} = nil
    fmt.Println("ii.size:", unsafe.Sizeof(ii)) //16
    我们以生成我,爱,机器,学习,翻译成<bos>,i,love,machine,learning,<eos>这个例子做生成过程来解释。
    训练:

    把“我/爱/机器/学习”embedding后输入到encoder里去,最后一层的encoder最终输出的outputs [10, 512](假设我们采用的embedding长度为512,而且batch size = 1),此outputs 乘以新的参数矩阵,可以作为decoder里每一层用到的K和V;
    将<bos>作为decoder的初始输入,将decoder的最大概率输出词向量A1和‘i’做cross entropy(交叉熵)计算error。
    将<bos>,“i” 作为decoder的输入,将decoder的最大概率输出词 A2 和‘love’做cross entropy计算error。
    将<bos>,“i”,“love” 作为decoder的输入,将decoder的最大概率输出词A3和’machine’ 做cross entropy计算error。
    将<bos>,“i”,"love ",“machine” 作为decoder的输入,将decoder最大概率输出词A4和‘learning’做cross entropy计算error。
    将<bos>,“i”,"love ",“machine”,“learning” 作为decoder的输入,将decoder最大概率输出词A5和终止符做cross entropy计算error。
    那么并行的时候是怎么做的呢,我们会有一个mask矩阵在这叫seq mask,因为他起到的作用是在decoder编码我们的target seq的时候对每一个词的生成遮盖它之后的词的信息。
    func main() {
    s := []string{"a", "b", "c"}
    fmt.Println("s:origin", s)
    changes1(s)
    fmt.Println("s:f1", s)

    changes2(s)
    fmt.Println("s:f2", s)

    changes3(s)
    fmt.Println("s:f3", s)
    }

    func changes1(s []string) {
    var tmp = []string{"x", "y", "z"}
    s = tmp
    }

    func changes2(s []string) {
    // item只是一个副本,不能改变s中元素的值
    for i, item := range s {
    item = "d"
    fmt.Printf("item=%s;s[%d]=%s", item, i, s[i])
    }
    }

    func changes3(s []string) {
    for i := range s {
    s[i] = "d"
    }
    }

    首先我们需要为每个输入向量(也就是词向量)创建3个向量,分别叫做Query、Key、Value。那么如何创建呢?我们可以对输入词向量分别乘上3个矩阵来得到Q、K、V向量,这3个矩阵的参数在训练的过程是可以训练的。注意Q、K、V向量的维度是一样的,但是它们的维度可以比输入词向量小一点,比如设置成64,其实这步也不是必要的,这样设置主要是为了与后面的Mulit-head注意力机制保持一致(当使用8头注意力时,单头所处理的词向量维度为512/8=64,此时Q、K、V向量与输入词向量就一致了)。我们假设输入序列为英文的"Thinking Machines"
    想要深度理解Attention机制,就需要了解一下它产生的背景、在哪类问题下产生,以及最初是为了解决什么问题而产生。

    首先回顾一下机器翻译领域的模型演进历史:

    机器翻译是从RNN开始跨入神经网络机器翻译时代的,几个比较重要的阶段分别是: Simple RNN, Contextualize RNN,Contextualized RNN with attention, Transformer(2017),下面来一一介绍。

    「Simple RNN」 :这个encoder-decoder模型结构中,encoder将整个源端序列(不论长度)压缩成一个向量(encoder output),源端信息和decoder之间唯一的联系只是: encoder output会作为decoder的initial states的输入。这样带来一个显而易见的问题就是,随着decoder长度的增加,encoder output的信息会衰减。
    func main(){
    var c = make(chan int)
    fmt.Printf("c.pointer=%p\n", c) //c.pointer=0xc000022180
    go func() {
    c <- 1
    addChannel(c)
    close(c)
    }()

    for item := range c {
    //item: 1
    //item: 2
    fmt.Println("item:", item)
    }
    }

    func addChannel(done chan int) {
    done <- 2
    fmt.Printf("done.pointer=%p\n", done) //done.pointer=0xc000022180
    }
    在测试模型的时候,Test:decoder没有label,采用自回归一个词一个词的输出,要翻译的中文正常从encoder并行输入(和训练的时候一样)得到每个单词的embedding,然后decoder第一次先输入bos再此表中的id,得到翻译的第一个单词,然后自回归,如此循环直到预测达到eos停止标记
    type visit struct {
    a1  unsafe.Pointer
    a2  unsafe.Pointer
    typ Type
    }

    func deepValueEqual(v1, v2 Value, visited map[visit]bool) bool {
    if !v1.IsValid() || !v2.IsValid() {
    return v1.IsValid() == v2.IsValid()
    }
    if v1.Type() != v2.Type() {
    return false
    }

    // We want to avoid putting more in the visited map than we need to.
    // For any possible reference cycle that might be encountered,
    // hard(v1, v2) needs to return true for at least one of the types in the cycle,
    // and it's safe and valid to get Value's internal pointer.
    hard := func(v1, v2 Value) bool {
    switch v1.Kind() {
    case Pointer:
    if v1.typ.ptrdata == 0 {
    // not-in-heap pointers can't be cyclic.
    // At least, all of our current uses of runtime/internal/sys.NotInHeap
    // have that property. The runtime ones aren't cyclic (and we don't use
    // DeepEqual on them anyway), and the cgo-generated ones are
    // all empty structs.
    return false
    }
    fallthrough
    case Map, Slice, Interface:
    // Nil pointers cannot be cyclic. Avoid putting them in the visited map.
    return !v1.IsNil() && !v2.IsNil()
    }
    return false
    }

    if hard(v1, v2) {
    // For a Pointer or Map value, we need to check flagIndir,
    // which we do by calling the pointer method.
    // For Slice or Interface, flagIndir is always set,
    // and using v.ptr suffices.
    ptrval := func(v Value) unsafe.Pointer {
    switch v.Kind() {
    case Pointer, Map:
    return v.pointer()
    default:
    return v.ptr
    }
    }
    addr1 := ptrval(v1)
    addr2 := ptrval(v2)
    if uintptr(addr1) > uintptr(addr2) {
    // Canonicalize order to reduce number of entries in visited.
    // Assumes non-moving garbage collector.
    addr1, addr2 = addr2, addr1
    }

    // Short circuit if references are already seen.
    typ := v1.Type()
    v := visit{addr1, addr2, typ}
    if visited[v] {
    return true
    }

    // Remember for later.
    visited[v] = true
    }

    switch v1.Kind() {
    case Array:
    for i := 0; i < v1.Len(); i++ {
    if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
    return false
    }
    }
    return true
    case Slice:
    if v1.IsNil() != v2.IsNil() {
    return false
    }
    if v1.Len() != v2.Len() {
    return false
    }
    if v1.UnsafePointer() == v2.UnsafePointer() {
    return true
    }
    // Special case for []byte, which is common.
    if v1.Type().Elem().Kind() == Uint8 {
    return bytealg.Equal(v1.Bytes(), v2.Bytes())
    }
    for i := 0; i < v1.Len(); i++ {
    if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
    return false
    }
    }
    return true
    case Interface:
    if v1.IsNil() || v2.IsNil() {
    return v1.IsNil() == v2.IsNil()
    }
    return deepValueEqual(v1.Elem(), v2.Elem(), visited)
    case Pointer:
    if v1.UnsafePointer() == v2.UnsafePointer() {
    return true
    }
    return deepValueEqual(v1.Elem(), v2.Elem(), visited)
    case Struct:
    for i, n := 0, v1.NumField(); i < n; i++ {
    if !deepValueEqual(v1.Field(i), v2.Field(i), visited) {
    return false
    }
    }
    return true
    case Map:
    if v1.IsNil() != v2.IsNil() {
    return false
    }
    if v1.Len() != v2.Len() {
    return false
    }
    if v1.UnsafePointer() == v2.UnsafePointer() {
    return true
    }
    for _, k := range v1.MapKeys() {
    val1 := v1.MapIndex(k)
    val2 := v2.MapIndex(k)
    if !val1.IsValid() || !val2.IsValid() || !deepValueEqual(val1, val2, visited) {
    return false
    }
    }
    return true
    case Func:
    if v1.IsNil() && v2.IsNil() {
    return true
    }
    // Can't do better than this:
    return false
    case Int, Int8, Int16, Int32, Int64:
    return v1.Int() == v2.Int()
    case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
    return v1.Uint() == v2.Uint()
    case String:
    return v1.String() == v2.String()
    case Bool:
    return v1.Bool() == v2.Bool()
    case Float32, Float64:
    return v1.Float() == v2.Float()
    case Complex64, Complex128:
    return v1.Complex() == v2.Complex()
    default:
    // Normal equality suffices
    return valueInterface(v1, false) == valueInterface(v2, false)
    }
    }
    这便是encoder的整体计算流程图了,Transformer模型中堆叠了多个这样的encoder,无非就是输出连接输入罢了,常规操作。
    最后再附上一个Transformer的代码实现,读者有兴趣可以跟着自己复现一下Transformer模型的代码。
       package main

       import (
           "log"
           "sync"
       )

       func init() {
           log.SetFlags(log.Lshortfile)
       }
       func main() {
           lock := sync.Mutex{}

           //Go 1.18 新增,是一种非阻塞模式的取锁操作。当调用 TryLock() 时,
           //该函数仅简单地返回 true 或者 false,代表是否加锁成功
           //在某些情况下,如果我们希望在获取锁失败时,并不想停止执行,
           //而是可以进入其他的逻辑就可以使用TryLock()
           log.Println("TryLock:", lock.TryLock())
           //已经通过TryLock()加锁,不能再次加锁
           lock.Lock()

       }

  • ECG前置电路设计
    TI出的一个经验文档,讲的很不错
  • 12、如何挑选立式磁棒电感厂家
    12、如何挑选立式磁棒电感厂家
  • 安科瑞 ASCB1系列智能微型断路器样本
    ASCB1 系列智能微型断路器是安科瑞电气股份有限公司全新推出的智慧用电产品,产品由智能微型断路器与智能网关两部分组成,可用于对用电线路的关键电气因素,如电压、电流、功率、温度、漏电、能耗等进行实时监测,具有远程操控、预警保护、短路保护、电能计量统计、故障定位等功能,应用于户内建筑物及类似场所的工业、商业、民用建筑及基础设施等领域低压终端配电网络。
  • [完结11章]技术大牛成长课,从0到1带你手写一个数据库系统
    大家好,今天我将给大家分享关于如何开发一个数据库系统的知识,将从0到1手把手带着一步步去开发这个项目,希望我的分享对大家的学习和工作有所帮助,如果有不足的地方还请大家多多指正。

    一、什么是数据库系统
    数据库系统一般由数据库、数据库管理系统(及其开发工具)、应用系统、数据库管理员构成 

    二、数据库管理系统的主要功能包括
    数据定义功能:DBMS提供数据定义语言(Data Definition Language,DDL),用户通过它可以方便地对数据库中的对象进行定义
    数据组织、存储和管理:DBMS要分类组织、存储和管理各种数据,包括数据字典、用户数据、数据的存取路径等。
    数据操纵功能:DBMS提-供数据操纵语言(Data Manipulation Language,DML),用户可以使用DML操纵数据,实现对数据库的基本操作,如查询、插入、删除和修改等
    数据库的事务管理和运行管理:数据库在建立、运用和维护时由数据管理系统统一管理、统一控制,以保证数据的安全性、完整性、多用户对数据的并发使用以及发生故障后的系统恢复
    数据库建立和维护功能:数据库初始数据的输入、转换功能,数据库的转储、恢复功能,数据库的重组织功能和性能监视、分析功能等。

    三、数据库系统结构
    1.1模式(概念模式或逻辑模式)
    定义:数据库中全体数据的逻辑结构特征的描述,是所有用户的公用数据库结构。

    特性:

    一个数据库只有一个模式
    模式与应用程序无关,只是数据的一个框架
    1.2子模式(外模式或用户模式)
    定义:数据库用户所见和使用的局部数据的逻辑结构和特征的描述,是用户所用的数据库结构

    特性:

    子模式是模式的子集
    一个数据库有多个子模式,每个用户至少使用一个子模式
    同一个用户可以使用不同的子模式,每个子模式可为不同的用户所用
    1.3内模式(存储模式)
    定义:是数据物理结构和存储方法的描述。它是整个数据库的最低层结构的表示。

    特性:

    一个数据库只有一个内模式,内模式对用户透明
    一个数据库由多种文件组成,如用户数据文件,索引文件及系统文件
    内模式设计直接影响数据库的性能

    以下是开发流程:
    在idea中构建如下几个子模块工程:
    @PostMapping("/doLogin")
    @ApiOperation(value = "一键注册登录接口", notes = "一键注册登录接口", httpMethod = "POST")
    public GraceJSONResult doLogin(HttpServletRequest request,
                                   HttpServletResponse response,
                                   @RequestBody @Valid RegisterLoginBO registerLoginBO,
                                   BindingResult result);
    验证的字段上方可以写一些相关的注解,系统识别后会自动检查
    RegisterLoginBO.java
    public class RegisterLoginBO {

        @NotBlank(message = "手机号不能为空")
        private String mobile;
        @NotBlank(message = "短信验证码不能为空")
        private String smsCode;

        public String getMobile() {
            return mobile;
        }

        public void setMobile(String mobile) {
            this.mobile = mobile;
        }

        public String getSmsCode() {
            return smsCode;
        }

        public void setSmsCode(String smsCode) {
            this.smsCode = smsCode;
        }

        @Override
        public String toString() {
            return "RegisterLoginBO{" +
                    "mobile='" + mobile + '\'' +
                    ", smsCode='" + smsCode + '\'' +
                    '}';
        }
    }

    如果校验有问题,那么可以直接获得并且放回给前端即可。
    BaseController.java
    /**
     * 验证beanBO中的字段错误信息
     * @param result
     * @return
     */
    public Map<String, String> getErrors(BindingResult result) {
        Map<String, String> map = new HashMap<>();
        List<FieldError> errorList = result.getFieldErrors();
        for (FieldError error : errorList) {
            // 发生验证错误所对应的某一个属性
            String errorField = error.getField();
            // 验证错误的信息
            String errorMsg = error.getDefaultMessage();
            map.put(errorField, errorMsg);
        }
        return map;
    }
    一般来说,admin系统不会有主动注册功能,账号都是分配的,那么默认就会存在一个基本账户,这也是预先通过代码生成用户名和密码的。直接手动生成即可:
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

    同理,查询操作也是类似JPA的操作,再继承Repository后直接使用其内置api即可:
    FriendLinkMngControllerApi.java
    @PostMapping("getFriendLinkList")
    @ApiOperation(value = "查询友情链接列表", notes = "查询友情链接列表", httpMethod = "POST")
    public GraceJSONResult getFriendLinkList();
    首先可以在数据库通过写sql脚本实现查询
    SELECT
    c.id as commentId,
    c.father_id as fatherId,
    c.article_id as articleId,
    c.comment_user_id as commentUserId,
    c.comment_user_nickname as commentUserNickname,
    c.content as content,
    c.create_time as createTime,
    f.comment_user_nickname as quoteUserNickname,
    f.content as quoteContent
    FROM
    comments c
    LEFT JOIN
    comments f
    on
    c.father_id = f.id
    WHERE
    c.article_id = '2006117B57WRZGHH'
    order by
    c.create_time
    desc
    目前我们所搭建的eureka是单机单实例的注册中心,如果挂了,那么整个微服务体系完全不可以,这是不应该的,所以为了实现eureka的高可用,我们可以搭建集群。
    在进行集群构建之前,大家先参照目前的eureka再去构建一个一模一样的工程,可以取名为 springcloud-eureka-cluster。
    为集群中各个eureka节点配置host
    eureka:
      instance:
        hostname: eureka-cluster-${port:7001}    # 集群中每个eureka的名字都要唯一
      # 自定义eureka集群中另外的两个端口号
      other-node-port2: ${p2:7002}
      other-node-port3: ${p3:7003}
      client:
    #    register-with-eureka: false
    #    fetch-registry: false
        service-url:
          # 集群中的每个eureka单实例,都需要相互注册到其他的节点,在此填入集群中其他eureka的地址进行相互注册
          defaultZone: http://eureka-cluster-${eureka.other-node-port2}:${eureka.other-node-port2}/eureka/,http://eureka-cluster-${eureka.other-node-port3}:${eureka.other-node-port3}/eureka/
    我们自己测试的时候时间可以设置为10秒内有10次,我认定非法请求,直接限制这个ip访问15秒,15秒后释放。(像有的网站会出现二维码让你扫描通过,或者手机验证码或者人机交互判断你当前是否是人还是机器,因为有可能是爬虫请求)
    开发步骤:
    首先在yml中设置基本参数:
    @Override
    public Object run() throws ZuulException {
        System.out.println("执行【IP黑名单】Zuul过滤器...");

        // 获得上下文对象requestContext
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        // 获得ip
        String ip = IPUtil.getRequestIp(request);

        /**
         * 需求:
         * 判断ip在10秒内请求的次数是否超过10次,
         * 如果超过,则限制访问15秒,15秒过后再放行
         */
        final String ipRedisKey = "zuul-ip:" + ip;
        final String ipRedisLimitKey = "zuul-ip-limit:" + ip;

        // 获得剩余的限制时间
        long limitLeftTime = redis.ttl(ipRedisLimitKey);
        // 如果剩余时间还存在,说明这个ip不能访问,继续等待
        if (limitLeftTime > 0) {
            stopRequest(requestContext);
            return null;
        }

        // 在redis中累加ip的请求访问次数
        long requestCounts = redis.increment(ipRedisKey, 1);

        // 从0开始计算请求次数,初期访问为1,则设置过期时间,也就是连续请求的间隔时间
        if (requestCounts == 1) {
            redis.expire(ipRedisKey, timeInterval);
        }

        // 如果还能取得到请求次数,说明用户连续请求的次数落在10秒内
        // 一旦请求次数超过了连续访问的次数,则需要限制这个ip了
        if (requestCounts > continueCounts) {
            // 限制ip访问一段时间
            redis.set(ipRedisLimitKey, ipRedisLimitKey, limitTimes);

            stopRequest(requestContext);
        }

        return null;
    }

    private void stopRequest(RequestContext requestContext){
        // 停止继续向下路由,禁止请求通信
        requestContext.setSendZuulResponse(false);
        requestContext.setResponseStatusCode(200);
        String result = JsonUtils.objectToJson(
                GraceJSONResult.errorCustom(
                        ResponseStatusEnum.SYSTEM_ERROR_BLACK_IP));
        requestContext.setResponseBody(result);
        requestContext.getResponse().setCharacterEncoding("utf-8");
        requestContext.getResponse().setContentType(MediaType.APPLICATION_JSON_VALUE);
    }
    上面这些都是通过不同key要执行多次才能得到结果,一般来说我们会使用es的aggs功能做聚合统计,会更好。
    通过一个脚本来统计男女数量:
    POST http://192.168.1.203:9200/fans/_doc/_search
    {
        "size": 0,
        "query":{
            "match":{
                "writerId":"201116760SMSZT2W"
            }
        },
        "aggs": {
            "counts": {
                "terms": {
                    "field": "sex"
                }
            }
        }
    }

    以下就是数据库系统开发的整个流程讲解,感谢大家的阅读

  • 首个基于Transformer的分割检测+视觉大模型视频课程(附源码+课件)
    众所周知,视觉系统对于理解和推理视觉场景的组成特性至关重要。这个领域的挑战在于对象之间的复杂关系、位置、歧义、以及现实环境中的变化等。作为人类,我们可以很轻松地借助各种模态,包括但不仅限于视觉、语言、声音等来理解和感知这个世界。现如今,随着 Transformer 等关键技术的提出,以往看似独立的各个方向也逐渐紧密地联结到一起,组成了“多模态”的概念。

    多功能
    通过引入灵活的提示引擎,包括点、框、涂鸦 (scribbles)、掩模、文本和另一幅图像的相关区域,实现多功能性;
    可组合
    通过学习联合视觉-语义空间,为视觉和文本提示组合实时查询,实现组合性,如图1所示;
    可交互
    通过结合可学习的记忆提示进行交互,实现通过掩模 引导的交叉注意力保留对话历史信息;
    语义感知
    通过使用文本编码器对文本查询和掩模标签进行编码,实现面向开放词汇分割的语义感知。

    超大规模视觉通用感知模型由超大规模图像、文本主干网络以及多任务兼容解码网络组成,它基于海量的图像和文本数据构成的大规模数据集进行预训练,用于处理多个不同的图像、图像-文本任务。此外,借助知识迁移技术能够实现业务侧小模型部署。

    超大规模视觉通用感知模型面临的挑战:
    (1)网络参数量庞大,通常超十亿参数,训练稳定性、收敛性、过拟合等问题相较于小网络挑战大很多。
    (2)原始数据集包含数十亿异质低质量图片与海量文本,多步训练以利用异质的多模态多任务数据,流程复杂,存在灾难性遗忘,难以定位精度等问题。
    (3)实验成本高,通常需要上千块GPU并行训练数周,需要研究者有敏锐的分析能力和扎实的知识基础。
    (4)工程挑战多,海量数据的吞吐,大型GPU集群上的并行算法,超大参数量模型的内存管理。

    提示工程
    大多数视觉数据集由图像和相应文本标签组成,为了利用视觉语言模型处理视觉数据集,一些工作已经利用了基于模版的提示工程,
    text_descriptions = [f"This is a photo of a {label}" for label in cifar100.classes]  
    text_tokens = clip.tokenize(text_descriptions).cuda()

    除了此类大型视觉语言基础模型外,一些研究工作也致力于开发可以通过视觉输入提示的大型基础模型。例如,最近 META 推出的 SAM 能够执行与类别无关的分割,给定图像和视觉提示(如框、点或蒙版),指定要在图像中分割的内容。这样的模型可以轻松适应特定的下游任务,如医学图像分割、视频对象分割、机器人技术和遥感等

    从模型训练、模型分发、模型商业化,美图体系化地同创作者和开发者共建模型生态:

    (1)模型训练:提供二次训练能力,并持续不断地为创作者提供服务,包括培训、社区和模型创作大赛。

    (2)模型分发:创作者和开发者共建的模型可以在美图的产品内进行分发,在分发过程中持续优化模型。

    (3)模型商业化:行业客户可通过 MiracleVision 的 API 和 SDK 进行商业使用,创作者和开发者通过商业合作获得经济收益。
    通用视觉-语言学习的基础模型
    UNITER:结合了生成(例如掩码语言建模和掩码区域建模)和对比(例如图像文本匹配和单词区域对齐)目标的方法,适用于异构的视觉-语言任务。
    Pixel2Seqv2:将四个核心视觉任务统一为像素到序列的接口,使用编码器-解码器架构进行训练。
    Vision-Language:使用像 BART 或 T5 等预训练的编码器-解码器语言模型来学习不同的计算机视觉任务。
    模型整体结构上,抛弃了CNN,将 BERT 原版的 Transformer 开箱即用地迁移到分类任务上面,在使用大规模训练集的进行训练时,取得了极好的效果。
    同时,在大规模数据集上预训练好的模型,在迁移到中等数据集或小数据集的分类任务上以后,也能取得比CNN更优的性能。
    模型整体结构如下图所示,完全使用原始 BERT 的 Transformer 结构,主要是对图片转换成类似 token 的处理,原文引入了一个 patch 的概念,首先把图像划分为一个个的 patch,然后将 patch 映射成一个 embedding,即图中的 linear projection 层,将输入转换为类似 BERT 的输入结构,然后加上 position embedding,这里的 position 是1D的,最后加上一个learnable classification token 放在序列的前面,classification由 MLP 完成。

    这里我们用 RAM 提取了图像的语义标签,再通过将标签输入到 Grounding-DINO 中进行开放世界检测,最后再通过将检测作为 SAM 的提示分割一切。目前视觉基础大模型可以粗略的归为三类:
    textually prompted models, e.g., contrastive, generative, hybrid, and conversational;
    visually prompted models, e.g., SAM, SegGPT;
    heterogeneous modalities-based models, e.g., ImageBind, Valley.

    CoCa 通过将所有标签简单地视为文本,对 web-scale alt-text 和 annotated images 进行了从头开始端到端的预训练,无缝地统一了表示学习的自然 语言 监督。因此,CoCa 在广泛的下游任务上实现了最先进的性能,零样本传输或最小的任务特定适应, 跨越视觉识别(ImageNet,Kinetics-400/600/700,Moments-in-Time )、跨模式检索(MSCOCO、Flickr30K、MSR-VTT)、 多模式理解(VQA、SNLI-VE、NLVR2)和图像字幕(MSCOCO、NoCaps)。在 ImageNet 分类中,CoCa 获得了 86.3% 的 zero-shot top-1 准确率, frozen encoder and finetune classifier 是 90.6%,finetune encoder 可以到 91.0%。

    截止目前国内外已经发布了许多包括 NLP, CV 和 多模态在内的大规模模型,但是这些模型在应用落地上还是有待进一步探究的,目前应用落地较好的有华为 的盘古,在电网和金融圈都有应用;智源的悟道系列在诗词图文上都有广泛应用,可以帮助学生看图写作,根据文字生成插图等;百度的文心也发布了在金融方 面的应用。但截止目前为止大模型在实际中的应用还不是很理想,大模型发展的初衷是使用一个预训练好的大模型代替一堆小作坊似的根据不同任务训练的小模 型,通过模型蒸馏知识迁移等技术在小模型上使用少量数据集达到超过原来小模型性能的目标。CV 大模型在应用上的一个难点是与实际应用相结合,目前社会中 用的较多的视觉相关的深度学习模型主要包括物体检测,人脸识别以及缺陷检测(部分)相比 NLP 模型在实际中的使用少很多,因此将 CV 模型与实际生产相 结合发现更多的应用场景很关键。另外一个 CV 大模型应用的难点就是如何快速高效的使用蒸馏和知识迁移技术提升下游任务的性能,这两点难题的解决在 CV 大模型的实际应用中都刻不容缓。

    总结起来,将大模型应用于更高分辨率的下游视觉任务具有以下好处:提高感知能力、改善定位精度、提升语义理解、改善细节保留和边缘清晰度、增加鲁棒性和泛化能力,以及推动研究进展。这些好处使得大模型在处理高分辨率图像时能够获得更准确、更细致和更真实的结果。随着深度学习和计算资源的不断发展,我们可以期待更先进的大模型和相关技术的出现,进一步推动计算机视觉在高分辨率图像任务中的应用和突破

  • 13、如何解决直插差模电感的异响问题
    13、如何解决直插差模电感的异响问题
  • 来源:虹科汽车电子 虹科技术丨BabyLIN产品如何轻松搞定K线协议实现? 原文链接:https://mp.weixin.qq.com/s/LR7VHFQajjyw6s6bVDJmsg 欢迎关注虹科,为您提供最新资讯!   导读 为了实现K线通信,SDF-V3在协议部分中定义了新的协议类型KLine Raw。所有能够运行SDF-V3文件(LinWorks版本在V.2.29.4以上)并使用最新固件(固件版本在V.6.18以上)的BabyLIN设备都可以执行KLine Raw
    虹科电子科技 2023-12-06 14:42 111浏览
  • 国产光耦是近年来中国电子产业中备受关注的领域之一。在全球电子市场的竞争中,中国光电行业正逐渐崭露头角。本文将详细分析国产光耦的发展趋势,探讨其未来发展的关键因素与前景。国产光耦的现状国产光耦是一种用于电气隔离和信号传输的关键电子元器件,广泛应用于通信、工控、医疗、消费电子等领域。随着中国电子制造业的不断壮大,国产光耦在市场上逐渐崭露头角。目前,国产光耦已经实现了从技术到市场的多方面突破,主要体现在以下几个方面:1. 技术创新国产光耦制造商不断投入研发,推动光耦技术的创新与升级。新材料的应用、封装
    克里雅半导体科技 2023-12-06 10:56 36浏览
  • 光耦合器是一种在现代科技中发挥关键作用的设备,其应用领域横跨通信、医疗、工业等多个行业。光耦合器通过巧妙地将光电子器件结合起来,实现了光与电的高效转换和传输,为光电子领域的发展提供了强大的支持。光耦合器是什么光耦合器是一种用于隔离、耦合和传输光信号的器件。其主要功能是将一个光学系统的光信号转换成电信号,或者将电信号转换为光信号,以实现光与电之间的高效转换。在各类光电子设备中,光耦合器起到了桥梁的作用,实现了不同部分之间的无缝衔接。光耦合器的原理及结构光耦合器的基本原理是通过光电二极管和光电晶体管
    克里雅半导体科技 2023-12-06 10:58 31浏览
  •     今天看到一个麦肯锡的统计数据,2021年中国出口的电子产品占世界34%。越来越多的PCB组件在中国造出来,然后送往全世界。作为电子工程师,除了增加修养,不断实现良好的设计,也要减少电子垃圾,对国际上的主要环保要求有所了解。    ROHS  Restriction of Hazardous Substances  有毒物质限制        这个标准针对 6 类电子产品中常见的的有毒物质,
    电子知识打边炉 2023-12-06 22:21 109浏览
  • 背景   随着汽车行业的不断迭代发展,市场及消费者对汽车提出了更高的要求,智能网联、自动驾驶等新技术的应用推动整车厂对车载芯片、汽车软件等方面投入了更多的精力,SOA(面向服务的架构)逐渐成为大多整车厂顺应市场趋势和技术趋势的首选。SOA架构使服务间的通讯变得更加简单,ECU更新、软件升级等变得更加灵活,使系统的健壮性和拓展性获得了大幅提高。但是在SOA架构开发阶段,由于市面上的IDL(接口描述语言)众多,例如FIDL、Protobuf、vCDL、ARXML、OMG IDL、CAN
    北汇信息 2023-12-06 11:41 73浏览
  • 近日,在传感器专家网的压力传感器专业交流群组中,有相关专家交流了目前我国压力传感器的一些情况。交流中指出,目前国内已有一些企业在做MEMS压力传感器芯片,在该领域国内相关企业总体来说技术差不多,精度等关键技术指标彼此间相差不大,但与国外压力传感器芯片巨头相比,精度等指标却有较大差距。传感器专家网https://www.sensorexpert.com.cn专注于传感器技术领域,致力于对全球前沿市场动态、技术趋势与产品选型进行专业垂直的服务,是国内领先的传感器产品查询与媒体信息服务平台。基于传感器
    传感器专家网 2023-12-06 11:03 52浏览
  • 2023年,对我来说,是充满挑战和收获的一年。这一年,我实现了很多的愿望,也收获了许多意外之喜。汗水与收获并存,艰难与惊喜共立。 工作上,我负责的项目在经过漫长的调研后终于立项了。在原理功能的实现过程中,我不仅学到了很多新的知识和技能,也经历了许多挫折和困难,一筹莫展时的长期等待和有效结果的欣喜。不放弃成功才会向你招手,最终努力得到了回报,项目成功立项,这让我感到非常自豪和满足。 除了工作上的成就,生活中我也有很多收获。这一年,我踩着夏天的尾巴购买了人生中属于自己的第一辆摩托车。 像风
    无言的朝圣 2023-12-06 10:48 104浏览
  • 近日,英国伦敦的可持续倡议(SMI)公布了2023年《地球宪章》徽章获奖名单。在这个名单中,全球共17家企业入选,中国企业仅占两席。最值得注目的是,海尔智家作为唯一获奖的中国家电企业,荣登榜单。 据了解,《地球宪章》徽章由现任英国国王查尔斯三世于2021年发起,旨在表彰对全球环境的可持续发展做出突出贡献的企业,鼓励企业将自然、人类和地球置于核心位置,通过创新和可持续的商业模式,共同应对全球气候挑战。获奖企业由来自环境、商业、政治和慈善界的全球专家小组经过严苛的评选选出。 海尔
    锦缎研究院 2023-12-06 12:41 53浏览
  • #这段代码是一个基于C语言的嵌入式程序,用于在HPMicro平台上运行。它的主要功能是初始化一个LED灯,并使其以一定的时间间隔闪烁。#以下是对代码的解析:#```c#include #include "board.h"#include "hpm_debug_console.h"#define LED_FLASH_PERIOD_IN_MS 300int main(void){    int u;    board_init(); // 初始化板子 
    丙丁先生 2023-12-06 14:22 106浏览
  • ​无论当下看不看机会,把握行情肯定是没错。 通过岗位数量,岗位要求(如对学历,技术点的要求)来了解行情是有效途径之一。 可以找我了解更多全国岗位。 【嵌入式软件工程师】 上海,风电行业国资企业,对学历有要求。 岗位职责: 1. 负责产品全周期研发,包括市场调研、客户需求技术转化、产品设计、产品制造、产品安装调试、产品测试验证和产品认证; 2. 负责产品失效根因分析,提供有效解决方案; 3. 负责组织供应商选择和产品质量管控; 4. 组织编制产品开发技
    落子无悔 2023-12-06 13:27 63浏览
  • 导语:CINNO Research统计数据表明,Q3'23全球半导体设备厂商市场规模前十大公司合计超250亿美元,同比下降9%,环比增长3%。CINNO Research统计数据表明,Q3'23全球半导体设备厂商市场规模Top10营收合计超250亿美元,同比下降9%,环比增长3%。Q3'23全球半导体设备厂商市场规模排名Top10与1H'23的Top10设备商相比,日立高新(Hitachi High-Tech)排名跌出Top10,泰瑞达(Teradyne)排名回归第十。荷兰公司阿斯麦(ASML)
    CINNOResearch 2023-12-06 14:04 105浏览
  • 摘要:根据CINNO Research产业统计数据,Q3'23国内智能手机屏下指纹识别占比创历史新高达45%,而侧边指纹识别占比较去年同期下降12%,后置指纹识别占比下降至1%,而前置指纹已淡出国内智能手机指纹识别市场。根据CINNO Research产业统计数据,受华为、荣耀热门机型销售的影响,Q3'23国内智能手机指纹识别搭载率上升至84%。图示:中国市场智能手机指纹识别技术别占比趋势来源: CINNO Research月度中国市场智能手机指纹识别应用趋势报告2023年第三季度,国内OLED
    CINNOResearch 2023-12-06 12:53 91浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦