关于STM32G474芯片有规律的自动重启的问题

各位,我正在做一个板子,将以前的软件移植过来,并修改相关的电机驱动,以期赶上今年6月的光伏展。这个新板子还是用我一直使用的STM32G474芯片。相关的电路,除了电机驱动的部分外,其他的都没变,还是沿用以前的经过长时间检验的电路。

板子外发打板回来之后,我就来进行软件的移植,移植得差不多的时候,我就接上电机试试看转不转。因为是新板子,没有进行完全的测试和确认,所以,为了防止烧板子,我就将桌面电源的输出设置成1A了,那么这样,即使板子上有短路,或者某些器件选得不对,耐压,耐电流不够的话,最大也就跑1A的电流,不会把板子严重的烧坏。

然后,我就接上电机试试看。接上电机后,我就按了启动按钮,电机缓慢的转起来了。转了几秒钟之后,开始加速的转,可是加速一会儿后,又自动的减速了,减速一会儿后,又自动的加速了,现象就是"呜--嗡--呜--嗡"这样的转,像一个摆轮一样,一会儿快,一会儿慢。我操,这可使我吃了一惊,我设计的电路和软件,可没有给电机这个一会儿快,一会儿慢的指令呀。很奇怪,不得其解。搞得我头上都要冒汗了。

赶紧关了电源,将所有的接线再仔细的检查了一遍,觉得没有问题,再重新打开电源上电,让电机反转,发现还是这样一会儿快,一会儿慢,搞得我一头雾水。仔细想了想硬件设计和软件设计,觉得应该没有问题,为什么会这样呢?

忽然脑袋里面灵光一闪,莫不是设置的电源电压是1A,电机转起来,加速之后,电流超过1A,就将电源的电压拉低,导致加到电机上的电压也低,就使得电机转起来,一会儿快,一会儿慢。于是,将电源的电流设成4A,因为刚刚用1A电流已经跑过了,除了电机的转动一会儿快,一会儿慢之外,板子并没有什么异常,也没有过热,也没有发烟。设大电流应该没有问题。将电流设大到4A后,重新上电,电机按照预定的设计转动起来了,先是缓慢启动,几秒钟之后加速到一个相对的高速就稳定在这个速度。看来,问题就是电源的电流设成1A限流了,才导致的这个问题。搞定。

想着让电机好好转一会儿,看看会怎么样。结果,转了几分钟之后,电机忽然不转了,停了,电机转的指示灯也不亮了。这又是什么问题呢?我这代码是移植过来的,移植前的代码是经过长时间检验,没有问题的。唯一改的地方就是电机的驱动,但是电机的正传,反转和停,我刚刚都试了一下,都没有问题,为什么转了几分钟就停了呢?我可没有发指令让它停呀,百思不得其解。赶紧看看log,有没有发BRK指令,将有BRK指令的地方,都用printf打印输出,并将当时的tick也打印出来,做记录。调试器也在BRK指令的地方打断点,开着调试器,重新运行程序。重新启动程序后,电机还是能转,几分钟之后,还是停了,也没有进入我打的断点,也没有打印BRK的命令的信息,这就怪了,没有经过BRK命令怎么就停了呢?重新启动程序,等电机转了之后,自己按BRK按钮,发现程序果然运行到BRK指令的断点处,单步运行也确实能够打印BRK命令的信息。连续运行之后,发现几分钟之后,还是会停。

这时,会想,莫不是系统重启了吧?赶紧找log,看系统重启的记录,搜索"system", 果然发现了系统重启的记录。如下:

看来果然是系统重启了,那么是什么原因呢?是喂狗不及时导致看门狗超时重启了吗?检查了所有的喂狗程序,发现基本上每3ms就喂一次狗,不应该是看门狗的问题。但是,还是不知道,就把看门狗取消掉吧,整个系统不用看门狗,看看会怎么样。

取消看门狗之后,还是会重启。而且,仔细看重启的时间,发现差不多10分钟会重启一次。如下:

这个就奇怪了,很规律的间隔10分钟就重启一次。什么原因呢?

是电路板设计得有问题,导致有干扰或者怎么样,自动10分钟重启?还是哪里有什么指令让系统重启?看来得找出系统重启的原因了。

于是,在网上找了一下,加上问AI,得出下列指令可以看出系统重启的原因。如下:

复制代码
uint32_t reset_flag = 0;

reset_flag = __HAL_RCC_GET_FLAG(RCC_FLAG_BORRST); usb_printf("BORRST: 0x%08lX\r\n", reset_flag);
  reset_flag = __HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST); usb_printf("SFTRST: 0x%08lX\r\n", reset_flag);
  reset_flag = __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST); usb_printf("IWDGRST: 0x%08lX\r\n", reset_flag);
  reset_flag = __HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST); usb_printf("WWDGRST: 0x%08lX\r\n", reset_flag);
  reset_flag = __HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST); usb_printf("LPWRRST: 0x%08lX\r\n", reset_flag);
  reset_flag = __HAL_RCC_GET_FLAG(RCC_FLAG_PINRST); usb_printf("PINRST: 0x%08lX\r\n", reset_flag);

// Clear reset flags
  __HAL_RCC_CLEAR_RESET_FLAGS();
  reset_flag = __HAL_RCC_GET_FLAG(RCC_FLAG_BORRST) | __HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) | __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) | __HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) | __HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST) | __HAL_RCC_GET_FLAG(RCC_FLAG_PINRST);
  usb_printf("Reset flags: 0x%08lX\r\n", reset_flag);

就是声明一个reset标志,读RCC寄存器的跟reset相关的每个标志位,并将结果打印出来,那么就能看出是什么原因导致reset了。读完RCC寄存器的reset相关的标志位后,用指令将reset标志都清掉,看看清掉的结果,确保都清掉了。这样,下次发生重启时,就能反应真实的重启的原因。运行的结果为:

可以看到,系统重启了,在软件重启和外部NRST重启的2个标志位上有结果。那么说明,要么是软件重启了,要么是外部NRST按键/管脚重启了。但是,我没有按NRST按键,这个NRST按键电路也是久经考验的电路,自己产生误操作或者信号干扰导致NRST重启的可能性很小,最大的可能性是软件重启。将我写的软件重启的函数注释掉,那么应该就不会触发软件重启了。注释掉之后再运行,发现还是会重启。再检索整个项目,发现在同事写的网络通信的代码里有重启的指令,

看来是同事写的这个代码导致了系统重启。

于是,跟同事沟通了一下,同事也同意跟他这段代码有关,看来这就是原因了。

这样,一块悬而未决的石头落地了。搞定。

大功告成,亲个嘴儿。

相关推荐
HQB20267 小时前
EG1198|屹晶微电子 120V 内置 MOS 异步降压 DC‑DC(高性价比)
嵌入式硬件·硬件工程
果壳science8 小时前
张祥前实验如何获取正电荷
笔记·科技·嵌入式硬件·硬件工程·制造
南山电子nscn8 小时前
中科芯CETC汽车电池管理系统BMS进口芯片国产型号替代指南
单片机·汽车·bms
沉淀的.晴天9 小时前
can总线
stm32
桀人9 小时前
认识AT24C02
stm32·单片机·嵌入式硬件
国科安芯10 小时前
星间激光通信终端CANFD控制网络的时延确定性与辐射可靠性
网络·嵌入式硬件·信息与通信·canfd·低轨卫星·商业航天·抗辐射
一直C11 小时前
嵌入式 Linux 驱动开发学习笔记:内核定时器、platform 总线与 I²C 驱动
linux·驱动开发·嵌入式硬件·学习·imx6ull
传感器与混合集成电路11 小时前
150MHz主频、8路DAC与6路PWM:JLH221360伺服控制SIP解析
嵌入式硬件
comyccccc11 小时前
STM32PID控制板设计全解析学习笔记
单片机·嵌入式硬件
碧海银沙音频科技研究院12 小时前
实现炬芯ATS308X的usb cdc 串口IAP 固件升级功能实现
人工智能·嵌入式硬件·深度学习·算法