前言
最近我想在设备中加入一个根据某个条件能将芯片复位重启的功能。
我也尝试过使用数字接口接 reset 引脚的方式,在程序中通过拉低引脚对芯片进行复位,但在烧写阶段的时候发现那个数字引脚在未初始化时,一直处于低电平,导致我无法对芯片进行程序烧写。
后来,我在 CSDN 上找到了一个只需要修改代码就能复位设备的方法1。
这里我将这个方法进行总结整理了一下,并把我使用该方法时遇到的问题也一并提出。
使用resetFunc()进行复位
–In this method, we are not gonna use any hardware pin, instead we will do everything in programming.
–Arduino has a builtin function named as resetFunc() which we need to declare at address 0 and when we execute this function Arduino gets reset automatically.
–So, no need of doing anything in hardware and simply upload the below code in your Arduino board.
在代码中,将 resetFunc()
这一函数的地址声明为0,那么我们在调用该函数时,arduino 就会回到地址0的位置,也就是回到起始代码,从而使 arduino 复位。
void(* resetFunc) (void) = 0;
void setup() {Serial.begin(9600);Serial.println("Hello, here is arduino");delay(500);}
void loop() {Serial.print("A");delay(1000);Serial.println(0);delay(1000);Serial.println("Now, reset arduino");delay(1000);resetFunc();Serial.println("Arduino will never reach here");}
与MsTimer2的配合
在项目中,由于我使用的 MsTimer2 这个定时中断的库,所以在我尝试复位时芯片总是锁死,没有任何响应,起初一度以为是 arduino 删除了该函数,还查了很久,但就没啥结果。
但有时候就是会突然抖一下机灵,由于我大部分的库都是自己重新构建的,我知道我的库里没有使用会牵扯到定时器、中断一类的操作,只使用了 MsTimer2 的作为定时中断,所以我尝试了一下如下步骤:
- 在 loop() 中进行 resetFunc(),在定时中断中进行打印输出,发现尝试复位后,定时中断和 loop 都停了
- 我尝试注释了 MsTimer2 在 setup() 中的 MsTimer2::start() 启动函数,再尝试后发现正常
- 在 resetFunc() 前,先使用 MsTimer2::stop() 停止函数,把定时中断关了,结果也能正常复位
破案了,在使用 MsTimer2 并启用定时中断时,如果需要使用 resetFunc 进行复位,就需要先将定时中断停止。
#include <MsTimer2.h>
void(* resetFunc) (void) = 0;
void OnTime() { Serial.println("Here is OnTime");}
void setup() { Serial.begin(9600); Serial.println("Hello, here is arduino"); delay(500); MsTimer2::set(2000, OnTime); MsTimer2::start();}
void loop() { delay(5000); Serial.println("Now, reset arduino"); delay(1000); MsTimer2::stop(); resetFunc(); Serial.println("Arduino will never reach here");}
同时我也尝试过在定时中断时进行复位,虽然依旧能复位,但是无法使用串口回传数据。
void OnTime() { Serial.println("Here is OnTime"); // Serial.println(1); delay(1000); // Serial.println(2); MsTimer2::stop(); // Serial.println(3); resetFunc();}
在尝试在以上三个位置通过串口回传数据时,都出现了如下情况:
\\80\\00\\00\\00\\00\\00\\00\\00\\00\\00\\00\\00\\00\\00\\00\\00\\00...
先会接受到一个\\80
字符,然后出现一大串\\00
,这个问题应该是因为我在OnTime中尝试停止定时中断导致的,与复位无关。
结论
相当简单的复位方法,至少设备死锁的时候能进行复位了🥰。