当前位置:   article > 正文

嵌入式分享合集150_opr嵌入式

opr嵌入式

一、MCU简易数字示波器

    这是一款采用STC8A8K MCU制造的简单示波器,只有零星组件,易于成型。这些功能可以涵盖简单的测量:

   该作品主要的规格如下:

  • 单片机:STC8A8K64S4A12 @27MHz

  • 显示屏:0.96“ OLED,分辨率为 128x64

  • 控制器:一个 EC11 编码器

  • 输入:单通道

  • 秒/秒:500 毫秒、200 毫秒、100 毫秒、50 毫秒、20 毫秒、10 毫秒、5 毫秒、2 毫秒、1 毫秒、500us、200us、100us
    100us( 仅在自动触发模式下可用)

  • 电压范围:0-30V

  • 采样额定值:250kHz @100us/格

    所有操作均由 EC11 编码器完成。输入包括单击,双击,长按,旋转和旋转时按。这似乎有点复杂,不用担心,下面有细节。该编码器的资源几乎已经耗尽。如果有新功能,可能需要额外的输入组件。

主界面 - 参数模式

  • 单击编码器:运行/停止采样。

  • 双击编码器:进入波形滚动模式。

  • 长按编码器:进入设置界面。

  • 旋转编码器:调整参数。

  • 按下时旋转编码器:在选项之间切换。

  • 切换自动和手动量程:连续顺时针旋转编码器以进入自动量程。逆时针旋转编码器以进入手动范围。

主界面 - 波浪滚动模式

  • 单击编码器:运行/停止采样。

  • 双击编码器:进入参数模式。

  • 长按编码器:进入设置界面。

  • 旋转编码器:水平滚动波形。(仅在采样停止时可用)

  • 按下时旋转编码器:垂直滚动波形(仅在采样停止时可用)

设置界面

  • 单击式编码器:不适用

  • 双击编码器:不适用

  • 长按编码器:返回主界面。

  • 旋转编码器:调整参数。

  • 按下时旋转编码器:在选项之间切换。

功能

  • 触发电平:对于重复信号,触发电平可以使其在显示屏上稳定。对于单发信号,触发电平可以捕获它。

  • 触发斜率:触发斜率确定触发点是在信号的上升沿还是下降沿。

  • 触发模式:

    • 自动模式:连续扫描。单击编码器可停止或运行采样。如果触发,波形将显示在显示屏上,触发位置将放在图表的中心。否则,波形将不规则地滚动,并且显示屏上将显示“Fail”。

    • 正常模式:完成预采样后,可以输入信号。如果触发,波形将显示在显示屏上并等待新的触发。如果没有新的触发器,波形将被保留。

    • 单模:完成预采样后,可以输入信号。如果触发,将显示波形并停止采样。用户需要单击编码器才能开始下一次采样。

    • 对于正常模式和单模式,请确保已正确调整触发电平,否则显示屏上不会显示波形。

  • 指标:通常,指标 on 表示采样正在运行。更重要的用途是在单触发和正常触发模式下,在进入触发阶段之前,需要预先采样。在预采样阶段,指示器不会亮起。在指标亮起之前,我们不应该输入信号。选择的时间尺度越长,预采样的等待时间就越长。

  • 保存设置:退出设置界面时,设置和主界面中的所有参数都将保存在EEPROM中。

    作品展示部分效果如下:  whaosoft aiot http://143ai.com 

项目地址~  https://github.com/CreativeLau/Mini-DSO

二、编写一个超简单的CPU

FPGA的处理能力固然强大,但在进行程序化的任务时,用状态机来实现有时就显得不如CPU写程序那么简洁。在FPGA里面也可以用逻辑来搭出简单的CPU,并固化一小段代码去实现特定的功能。

考虑下最简单的CPU是什么样子呢?最少,需要有读取程序(指令),并执行指令的过程。指令存放在一块内存当中,CPU每步取一条指令来执行,根据读出的指令内容,内部的状态发生转变——比如寄存器按指令要求进行运算,比如访问外部的端口(或总线)。指令是一个编码,描述这一步需要做的事情;执行指令的过程就是状态转移的过程。我实验的这个超简单CPU是这样:

上图中,PC是Program Counter,就是程序计数器,选择ROM中程序执行的地址。opr用来存放当前的指令,它的内容从ROM中读到。寄存器还有A寄存器和R0~R7寄存器,用来计算和存放结果,另外还有一个1-bit的“零"标志位zflag,是给条件转移指令用的。

当然,若只是里面的寄存器变来变去,这个CPU就没有实用价值了,所以还有一个输入端口,以及一个输出端口,用来和寄存器A交换数据。设计指令字长为8-bit,寄存器宽度也为8-bit。每条指令都是从ROM中读8-bit,可以最多有256种不同的指令,当然指令中能编码立即数,所以指令不会有那么多种。我给这个CPU设计了14条指令:

跳转指令有2条,无条件转移和Z条件转移,转移范围为5-bit相对地址,即-16~+15。带立即数指令有4条,因为指令才8-bit,立即数只好分配4-bit了。装入A寄存器的高4位或低4位,以及与A做加减法。R0~R7寄存器只能与A寄存器进行copy和比较操作。影响zflag标志的指令有位测试指令TESTB, 比较指令COMP和加减法指令。指令空间并没有用完,可以根据需要再补充指令。用Verilog语言来写这个CPU的状态转移部分: 

  1. module cpu0(clk, Iaddr, Ibus, PortI, PortO);
  2. input clk;
  3. output [9:0] Iaddr;
  4. input [7:0] Ibus;
  5. input [7:0] PortI;
  6. output reg [7:0] PortO;
  7. reg [9:0] pc;
  8. reg [7:0] RA;
  9. reg [7:0] Rn[0:7];
  10. reg zflag;
  11. assign Iaddr=pc;
  12. reg [7:0] opr;
  13. always @(posedge clk)
  14. opr <= Ibus;
  15. wire [1:0] opc1=opr[7:6];
  16. wire [5:0] opx=opr[5:0];
  17. wire [1:0] opc2=opr[5:4];
  18. wire [3:0] imm4=opr[3:0];
  19. wire [2:0] sel=opr[2:0];
  20. reg branch;
  21. always @(posedge clk) begin
  22. pc <= pc + 1'b1; // default increment
  23. branch <= 1'b0;
  24. if(~branch) begin
  25. if(opc1==2'd3)
  26. if(opr[5] | zflag) begin
  27. pc <= pc + {{5{opr[4]}},opr[4:0]}; // jump instruction
  28. branch <= 1'b1;
  29. end
  30. end
  31. end
  32. always @(posedge clk) begin
  33. if(~branch) begin
  34. if(opc1==2'd1 && opc2==2'd0)
  35. Rn[sel] <= RA;
  36. end
  37. end
  38. always @(posedge clk) begin
  39. if(~branch) begin
  40. case(opc1)
  41. 2'd0: begin
  42. if(opx==6'd0)
  43. RA <= PortI;
  44. end
  45. 2'd1: begin
  46. if(opc2==2'd1)
  47. RA <= Rn[sel];
  48. end
  49. 2'd2: begin
  50. case(opc2)
  51. 2'd0: RA[7:4] <= imm4;
  52. 2'd1: RA[3:0] <= imm4;
  53. 2'd2: RA <= RA + imm4;
  54. 2'd3: RA <= RA - imm4;
  55. endcase
  56. end
  57. endcase
  58. end
  59. end
  60. always @(posedge clk) begin
  61. if(~branch) begin
  62. if(opc1==2'd0 && opx==6'd1)
  63. PortO <= RA;
  64. end
  65. end
  66. always @(posedge clk) begin
  67. if(~branch) begin
  68. if(opc1==2'd1) begin
  69. case(opc2)
  70. 2'd3: zflag <= ~RA[sel];
  71. 2'd2: zflag <= (RA==Rn[sel]);
  72. endcase
  73. end
  74. if(opc1==2'd2) begin
  75. if(opc2[1])
  76. zflag <= (RA==8'd0);
  77. end
  78. end
  79. end
  80. endmodule

除了指令所描述的寄存器的操作外,还多了一个branch寄存器和条件判断,这是做什么呢?

请注意,PC寄存器所指的是下一条要执行的指令地址(默认总是 pc <= pc + 1),但是如果遇到跳转指令,下一条指令是紧接着跳转指令的,将在下一个时钟沿上被读入opr,但是这条指令不该被执行,所以需要条件判断一下。而要跳转的位置的指令需要在PC更新之后的下一拍才能够被读入opr,这就是转移指令比普通指令要多花一个时钟周期的原因(这个CPU是两级流水线)。写测试程序了,没有编译器,汇编程序都得自己写呢。先就手写机器码吧!

  1. module coderom(addr, data);
  2. input [9:0] addr;
  3. output reg [7:0] data;
  4. always @(addr) begin
  5. case(addr)
  6. 0 : data = 8'h80; // LOADAL 0
  7. 1 : data = 8'h90; // LOADAH 0
  8. 2 : data = 8'h01; // OUT A
  9. 3 : data = 8'hA1; // ADDA #1
  10. 4 : data = 8'h40; // MOV R0, A
  11. 5 : data = 8'h00; // IN A
  12. 6 : data = 8'h77; // TESTB A,7
  13. 7 : data = 8'h50; // MOV A, R0
  14. 8 : data = 8'hDB; // JUMPZ 4
  15. 9 : data = 8'hF8; // JUMP 2
  16. default: data=8'h00;
  17. endcase
  18. end
  19. endmodule

这个程序不干啥有价值的,就是检测到输入端口第7位为高时,循环加一计数,输出到端口点LED.顶层模块,将ROM和CPU连起来:

  1. module cpu_top(clk, PortI, PortO);
  2. input clk;
  3. input [7:0] PortI;
  4. output [7:0] PortO;
  5. wire [7:0] rom_q;
  6. wire [9:0] rom_addr;
  7. cpu0 minicpu(.clk(clk),
  8. .PortI(PortI),
  9. .PortO(PortO),
  10. .Ibus(rom_q),
  11. .Iaddr(rom_addr));
  12. coderom rom(
  13. .addr(rom_addr),
  14. .data(rom_q));
  15. endmodule

三、电源IC是如何失效的?电源IC损坏过应力分析

在我们项目开发和产品量产过程中总是会出现一些 IC 损坏的现象,通常要想找出这些 IC损坏的根本原因并不总是很容易。有些偶发性的损坏很难被重现,这时的难度就会更大。而且有些时候 IC 的失效表现简直就是破坏性的,可能IC已经被烧得一塌糊涂,即使求助IC原厂分析,往往也不一定能找出失效的根本原因,出现这种情况,作为工程师的你估计头皮要感觉到阵阵发麻了。

电源 IC 的失效常常是其输入端受到电气过应力( EOS)的结果。在很多情况下,器件失效的原因都是输入电压太高了。本文对电源 IC 输入端 ESD 保护单元的结构进行了解释,说明了它们在受到 EOS 攻击时是如何受损的。造成 EOS 攻击事件的原因常常是热插入和导线或路径电感与低 ESR 陶瓷电容结合在一起形成的瞬态效应。在电路设计中采用一些特别的设计可以避免 EOS 的发生,防范它们可能带来的危害。本文也将对 Buck 转换器输入端的结构进行介绍,给出过高的输入电压造成器件损坏的机制,通过不同的应用案例说明过高的输入电压是如何发生的,还将提供相应的问题解决方案。

Buck 转换器输入端的结构

下图显示了一个Buck转换器 IC 内部的基本构成,其中包含了几个静电释放( ESD)防护单元。

上图中,电源输入端 VIN 被一个很大的 ESD 单元保护着,其保护范围包括内部稳压器和 MOSFET, 因而可以承受很高的静电电压。SW 端子内部通常没有 ESD 单元,因为大型 MOSFET 本身就可以像 ESD 保护单元一样动作,静电电流可经其内部体二极管流向 GND 或 VIN 端,也可利用它们的击穿特性实现保护。BOOT 端有一个 ESD 单元处于它和 SW 之间,其它小信号端子也各有一个小型的 ESD 单元,它们通常都和输入串联电阻一起保护这些小信号端子免受静电放电的危害。

ESD 和 EOS 的差异

当超过 ESD 单元钳位电压的过电压出现在 IC 端子上时, IC 会不会损坏就取决于 ESD 元件被击穿期间通过它的能量的多少。
ESD( Electro Static Discharge, 静电释放)和 EOS( Electrical Over Stress, 电气过应力)都是与电压过应力有关的概念,但它们之间的差异也很明确:

ESD 的电压很高( > 500V),持续时间相对较短( < 1µs)

EOS 的电压相对较低( < 100V),持续时间更长一些(通常 > 1µs)

当持续时间更长的 EOS 事件发生时,冲击 ESD 保护单元的能量就会更多,常常超出 ESD 保护单元的最大冲击能量承受能力,这样就会在 ESD 保护单元中积累太多的热量,最终导致严重的毁灭性结果。通常情况下,芯片中支撑ESD 保护单元的其他部分也会连带着一起受损。

电源热插入导致的输入端过应力

一种造成电源 IC 输入端受到 EOS 冲击的常见原因是电源的热插入事件,这种事件发生在处于开机状态的电源被引入一个系统的时候。这种系统的输入端通常含有低 ESR 的陶瓷输入电容,它们与电源引线的电感一起发生谐振,可以导致高压振荡信号的出现。下图显示的就是这样的场景,其中的电源是开着的,有两根引线将电源接入应用系统,其中的开关 S 用于模拟热插入的行为。出现在系统输入端的电压振荡信号的幅度与很多因素有关:电源供应器的内阻,引线的电阻和电感量,开关 S 的电阻,输入电容 C1、 C2 的电容量和它们的 ESR 的大小。

作为一个例子,我们假设 12V 电源供应器具有很大的输出电容,电源引线的长度为 1.2m 并且具有很低的电阻,开关S 的阻抗也是很低的, C1、 C2 是 10µF/25V X5R 1206 的 MLCC。电源引线的总电感大约为 1.5µH,包括连接器在内其电阻约为 10mΩ。两只电容在 12V 直流偏置下的实际总容量约为 9µF,而且它们各自的 ESR 约为 5mΩ。

下图显示了热插入事件发生在这样的输入电路时的振荡过程的模拟结果。从模拟结果可以看到,这样的热插入过程导致的输入电流高达大约 30A,由引线电感和输入电容导致的电压振荡波形的峰值几乎可以达到直流输入电压的 2 倍。

下图显示的是对同样的电路进行热插入测试的情形,其中的开关 S 被换成了 MOSFET,该 MOSFET 是用脉冲发生器驱动的,目的是让热插入的动作变成是稳定的,同时也是可以重复的。

从上图可以看到,实际的热插入事件导致了比理论上更高的振荡电压峰值,这是由于 MLCC 输入电容在直流偏置电压下的电容量的非线性变化导致的,它的这种特性在图中的右侧显示出来。当电容上的电压升高时,它的电容量会下降,对其充电的电流进入更小的电容后就会得到更高的电压。在此案例中, 12V 电源的热插入事件能导致大约 30V 的最高电压峰值。

消除热插入期间电压尖峰的措施

上面已经解释过热插入期间电压尖峰发生的原因,下图 将与输入电路有关的参数表达了出来:电源供应器的内阻Ri,电源传输线的电感 Lwire 和电阻 Rwire,具有低 ESR 的输入电容。有多种方法可以降低热插入期间的电压振铃信号的幅度:

方法 1:大多数电源供应器是使用了很大的输出电容的开关模式电源适配器,这种电路的输出阻抗很低,遇到热插入事件时可以快速生成大电流。如下图那样增加一个共模电感和一只 ESR 比较高的小型电解电容,适配器的输出阻抗就会增加,谐振过程会受到抑制。

方法 2:使用较小线径的适配器电缆来增加电缆的阻抗。为了达成好的谐振抑制效果,电缆的阻抗应该大于 0.3Ω,其坏处是电缆上的压降会增加。

方法 3:增加电缆两条线间的耦合程度。两线间更好的耦合可以形成相反的磁场,这对谐振的抑制有帮助。如下图显示了对 75cm 长、规格为 18AWG 的同轴电缆的模拟,根据漏感测试的结果,两线间的耦合度大概为 0.8。通过使用不同类型的电缆进行测量,可以确认耦合良好的线对谐振过程会有更好的抑制效果,相应的热插入过程所导致的电压尖峰也更低。

方法 4:由 LC 电路形成的谐振可以通过给输入电容并联一个 RC 电路进行抑制, RC 电路的参数可用下述方法进行计算,RS 的计算公式如下图:其中 LP是电缆的电感量, CIN是系统的输入电容, ξ 是希望的抑制系数。在前述的热插入案例中, LP 大约是 1.5µH, CIN 在 12V 时为 9µF。当我们选择良好的抑制效果(ξ = 1)时, RS = 0.2Ω。抑制电容 CS 的值必须足够大以避免它在热插入造成的电流脉冲出现期间被过度充电,其电压增量 VC = IC * 1/ωC,其中的 ω 是 LP 和 CIN 的谐振频率(测量数据大约是 40kHz)。由于电流脉冲的幅度是 35A,要想使充电造成的电压增量小于 2V,我们需要电容的值大于 70µF。

在加入 100µF 和 0.2Ω 的 RC 电路后,针对上述的热插入案例再次进行仿真模拟,我们可以看到谐振被完全抑制住了,电压的过冲低于 2V,参见下图所示。在实践应用中,RC 抑制电路可以很容易地通过使用一只 100µF/25V 的电解电容实现,它需要和陶瓷输入电容并联在一起。之所以这么简单,是因为大多数 100µF 的电解电容在 100kHz 频率下有大约 0.2Ω 的 ESR。在下图中的右侧电路就在输入端加入了 100µF/25V 电解电容,热插入试验表明其输入端的过冲会被完全抑制掉,不会有损毁风险再出现在 IC 上。 其他造成电源 IC 输入端 EOS 的原因

除了热插入造成的冲击以外,还有其他一些状况可能造成电源 IC 输入端受到 EOS 的攻击:
a. USB 输出端短路测试造成 USB 开关输入端损毁
下图显示的是一个典型的 USB 开关的应用电路图,有一个 1µF 的去耦电容放在靠近 IC 输入端的地方,电容前面有大约 10cm 的铜箔路径将它和 5V 主电源连接起来。

USB 端口都需要进行短路测试, 这个测试通过一个开关来模拟, IC 需要在侦测到短路以后快速将其 MOSFET 开关关断。从上图中的实例可以看到, MOSFET 开关关断的动作是有延时的,因而会有一个短时大电流流过 IC 之后关断才会发生。由于输入线有电感存在,此电感和输入端去耦电容 C2 会一起发生谐振,因而可在示波器上看见输入端出现了高压脉冲,这很可能超过 IC 的最高耐压能力并将其损毁。

为了解决这样的可靠性隐患,用于热插入风险防范的类似措施可以被纳入考虑范围,因此我们要在电路中加入类似电解电容的 RC 抑制电路。抑制电路的参数计算方法是类似的,我们可以利用开关关断过程的 dI/dt 计算电容的值。实际上,一个 47µF 的电解电容就可以将电压峰值控制在大约 6V 上,如下图 所示。b. Buck 转换器的反向偏置问题
工作在强制 PWM 模式下的 Buck 转换器在经由输出端反向偏置时会表现出 Boost 转换器的行为。

假如转换器的输出端由高于预设输出电压的外部电源供电时, IC 内部的下桥 MOSFET 会从输出端吸入电流,再与上桥 MOSFET 一起形成一个Boost 转换器。如下图所示,该电路的输出端就由一个缓慢上升的 5V 电源供电,它的输入端电压将上升并最终将其 ESD 单元击穿。像这种电源反向偏置的情况并不经常发生,但在存在电池的系统中就很容易出现。又假如在某些设计中使用了动态电压调节技术(通过反馈网络对输出电压进行调节),如果输出电容很大,又恰好遇到了输出电压的设定突然变低,Boost 的动作就会发生了。

总结

电源 IC 的损坏经常是由于输入电压过应力造成的,这在电源热插入导致出现过高电压尖峰或由线路电感和低 ESR 陶瓷电容形成谐振时就会发生。
当电源 IC 输入端的 ESD 单元遇到超过其能量承担水平的冲击能量时就会被损坏。造成 IC 损坏的 EOS 能量通常要比正常的人体模式( HBM) ESD 能量高好几倍。当 ESD 单元被损坏的时候,作为其承载体的硅晶圆也会受到伤害。在大多数情况下,承载体的损坏会直接导致功率级的不正常运作,引起直通短路、功率级烧毁等问题。

具有折返特性的 ESD 单元在被触发以后可能保持在低于工作电压的电压上,这会在被触发之后立即导致大电流的出现。

由于热插入事件和电源线上的谐振效应都会将电压尖峰引入 IC 输入端,因而在电源设计过程中必须对这样的瞬态过程进行检查,确保在任何情况下都不会在 IC 输入端形成高电压。由于 ESD 单元的激活电压总是高于器件的绝对最大额定值,应用中能够出现的电压就不能超过 IC 的绝对最大额定值,以便确保 ESD 单元在工作过程中不会被激活。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/647035
推荐阅读
相关标签
  

闽ICP备14008679号