设计一个电路,用来验证微控制器内部保险丝的重要性
最近我在一个项目中遇到了一个问题,即MCU在上电后无法执行程序。原因是保险丝的问题!
和微控制器打交道很有趣,直到它们停止工作!
最近,我正在处理一个工业电路。在测试过程中,该电路和MCU运行完全正常。于是,我设计了PCB板,并从JLCPCB订购了它。收到后,我将代码上传到MCU并进行了基本的测试。整个电路运行得非常顺利!(需要注意的是,在这次基础测试中,我是使用台式电源为PCB供电的。)
但使用PCB上的降压模块(5V@20A)供电后,MCU似乎就停止工作了!无论我尝试多少次复位或重启电路,MCU都无法运行。所有的电压、连接和代码都完全正常。
更奇怪的是,使用外部台式电源为PCB供电时却完全没问题!起初我以为是降压模块的问题,于是将其更换为新的,但问题依旧存在!那么到底是什么原因导致了这个问题?我花了将近两天时间才发现,问题出在微控制器内部不同的保险丝配置上。
这是一个任何人都可能遇到的问题,尤其是当你打算从业余爱好者转型为专业PCB设计师时。
为什么这很重要,保险丝是什么?在这篇Instructables教程中,我将尝试介绍一些基础知识,并说明我是如何最终解决这个问题的。
理论(微控制器系列)
微控制器或MCU是人类最伟大的发明之一,随着半导体技术的进步,现在只需几美分就能买到性能强大的微控制器。
微控制器是一种酷炫的设备,可用于构建各种硬件项目、机器人和嵌入式系统。一个常见且或许最受欢迎的例子是Arduino Uno,它运行在AVR(高级虚拟RISC)家族中的ATMEGA328P芯片上。
对于简单的项目,ATMEGA328PP 可能有些过头;更好的选择是 ATTINY1614。你知道吗?你可以在 Arduino IDE 中使用相同的 Arduino 代码来编程这个芯片。ATTINY1614 更便宜、更小巧,且有 14 个引脚。
ATtiny1614 在 AVR AVR 家族中表现出色,原因如下:
•支持通过UPDI(统一程序与调试接口)进行单线代码上传
•它内置一个20 MHz振荡器(也可外接振荡器)
•拥有16KB闪存(用于代码)、2KB SRAM(用于程序)和256字节EEPROM(用于非易失性存储)。
•可适用于镍镉电池(工作电压1.8V至5.5V)
•12 个可编程通用引脚(GPIO)
•ADC、定时器、USART、SPI、I2C,以及更多功能
有了这些优点,我使用它来构建电路就再自然不过了。
更多理论——FUSES
即使你非常喜欢微控制器,但缺乏深入的知识也可能导致奇怪的行为、生产延迟以及大量调试时间的浪费。
例如微控制器内部的保险丝。保险丝是硬件层面的简单配置位,可以理解为埋在微控制器内部的开关,具有非易失性(断电后不会丢失信息),且在编程过程中其状态不会改变。
他们做什么?
Fuse 设定了一些芯片硬件的关键方面,例如
•确定微控制器是使用内部振荡器还是外部振荡器?
•设置低电平检测器的阈值,当供电电压低于该阈值时,微控制器将被复位。
•将复位引脚配置为通用输入输出(GPIO)。
•上电到代码执行延迟。
•锁定芯片。
•以及更多。
ATtiny1614上有多个保险丝,具体为8个:
•0x00 WDTCFG(看门狗配置)
•0x01 BODCFG(BOD配置)
•0x02 OSCCFG(振荡器配置)
•0x04 TCD0CFG(定时器计数器类型D配置)
•0x05 SYSCFG0(系统配置0)
•0x06 SYSCFG1(系统配置1)
•0x07 附加(应用程序代码结束)
•0x088 启动结束
•0x0AA 锁位(UPDI的锁位)
但我们将具体探讨两个保险丝:
•在 0x01,即 BODCFG(棕矮探测器配置)
•在 0x06 处,即 SYSCFG1(系统配置 1(启动时间设置))
别再理论了,让我们来看看这些保险丝和我的头痛有什么关系!
罪魁祸首
PCB由一个65W的适配器供电。该适配器提供20V、65W的电源。这20V电压通过红色圆圈标示的20A开关式降压模块降至5V,该5V电压为MCU及其他电路供电。
为了查明之前提到的问题,我将示波器探头连接到MCU的电源引脚上,以测量引脚之间的电压变化。电源开启后,电压迅速达到5V。如图(第二张图)所示,最终输出为平稳稳定的5V,噪声和失真非常小,那么这是怎么回事呢?
如果我们放大(第三张图片),可以看到输出需要一段时间才能达到满电压(5V)。大约是8到10毫秒,一个非常短的脉冲,但正是它起了主要作用!
为什么这很重要?现在我们来谈谈重点——位于0x06位置(偏移)的保险丝,也就是SYSCFG1或系统配置1的保险丝。
什么是系统配置1保险丝?
它设置启动时间,基本上是在电源开启后选择代码执行的起始时间。这正是导致我PCB出现奇怪问题的保险丝。可配置的取值如下:
•价值 --- 描述
•0x0 --- 0 毫秒
•0x1 --- 1毫秒
•0x2 --- 2 毫秒
•0x3 --- 4 毫秒
0x4 --- 8 毫秒
•0x5 --- 16毫秒
•0x6 --- 32毫秒
•0x7 --- 64 毫秒
我不太确定制造商设置的默认值是多少,但一些资料指出是4到8毫秒。这意味着代码执行在板子上电后仅延迟4毫秒才开始。在此期间,电源电压需要非常稳定。在我的情况下,电压达到稳定的5伏所需的时间过长(大约10到12毫秒)。
这与欠压检测器(保险丝)共同导致了一个不稳定状态,即使供电电压正常,IC也无法执行程序。
要解决这个问题,我们只需将系统配置中的1个保险丝改为一个更高的值。我将保险丝设置为0x05,这对应的是16毫秒的启动时间。
要更改 ATtiny1614 的 0x06 熔断器,请在 platformio.ini 中使用以下代码:
现在,ATtiny 在开始执行代码前需要等待至少 16 毫秒。而在这一段时间内,我的电源电压已经稳定到 5V。
经过彻底测试后,该漏洞已消除,IC运行正常。
另一个实用的保险丝
什么是欠压检测器?
欠压检测器是微控制器内置的安全功能,可持续监测供电电压。当电压低于安全阈值时,BOD(欠压检测)会将ATtiny芯片保持在复位状态,从而保护IC的闪存和EEPROM免受损坏。在ATtiny1614中,BOD寄存器位于地址0x01。
如果查看数据表中的可用BOD电平,共有8个可配置的BOD电平:
•0x0(1.80V)
•0x1(2.15V)
•0x2(2.60V)
•0x3(2.95V)
•0x4(2.20V)
•0x5(3.70V)
•0x6(4.00V)
•0x7(4.30V)
我认为MCU默认的BOD电平是4.3V,这意味着MCU只能在5V系统中正常工作。这没问题,但MCU的工作电压最低可低至1.8V!因此,即使在1.8V下,芯片也应能正常运行。
但因为BOD设置为4.3V,所以你不能将芯片用于运行在例如3.3V的电路中!这意味着,如果你给ATtiny1614供电3.3V,而BOD电平被设置为4.2V,IC就会进入复位状态,无法正常使用!
只需将保险丝从0x7改为0x4,就能让MCU在更低的电压下正常工作。这真是个值得学习的巧妙方法!
要更改 ATtiny1614 的 0x01 熔断器,请在 platformio.ini 中使用以下代码
我使用了二进制值(0b00000101),因为BOD具备其他功能,例如单次/连续监测。改变BOD电压只需使用该二进制值的前三位。
如何在微控制器上烧毁保险丝
更换保险丝并非由代码(C或C++程序)直接完成,而是需要使用外部编程器,例如jtag2updi或USB转TTL。要进行编程或更改保险丝设置,请按照电路图所示连接线路。
保险丝应在代码上传前或上传过程中设置。若要使用Arduino IDE更改保险丝,请按以下步骤操作:
•使用正确的核心:您需要确保在您的 IDE 中安装了现代且兼容的板载软件包,例如 GitHub 上的 megaTinyCore。
•在IDE中配置:在Arduino IDE中,使用工具菜单选择所需的时钟频率、工作电压(BOD)和引脚分配。
•烧录跳线:在您的IDE中点击“烧录引导加载程序”。尽管ATtiny1614不使用标准的引导加载程序,但此特定命令是IDE用来安全地将跳线字节写入芯片的机制。
我经常在 VS Code 中使用 PlatformIOIO 进行嵌入式项目开发。因此,以下是用于上传代码的 platformio.ini.ini 配置文件,以及 ATtiny1614 的 FUSE 设置。
本文编译自hackster.io





