简体   繁体   English

STM32F103芯片大约每500ms保持一次复位

[英]STM32F103 chip keeps resetting about every 500ms

I wrote a simple blink program for a stm32f103rbt6 chip, but after a while I noticed that MCU is resetting constantly.我为 stm32f103rbt6 芯片写了一个简单的闪烁程序,但过了一会儿我注意到 MCU 不断地复位。 When I check RCC-CSR register the PINRSTF flag is high.当我检查 RCC-CSR 寄存器时,PINRSTF 标志为高。 but I didn't connect anything externally to NRST pin.但我没有将任何外部连接到 NRST 引脚。 Has anybody an idea that why this occures?有人知道为什么会这样吗? Is it possible that anything internally cause this situation?有没有可能是什么内部原因导致了这种情况?

It's the program that I've written for debugging.这是我为调试而编写的程序。 the result is that everytime LED wants to turn on but quickly turns off.结果是每次 LED 想要打开但又很快关闭。

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_i2c.h"
#include "system_stm32f10x.h"
#include "delay.h"
#include "output.h"

int main(void){


    RCC_APB2PeriphClockCmd(
        RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin   = PIN_52.pin;
    GPIO_Init(PIN_52.port, &GPIO_InitStructure);
    GPIO_WriteBit(PIN_52.port, PIN_52.pin, Bit_SET);

    if  (RCC_GetFlagStatus(RCC_FLAG_SFTRST)){
        //GPIO_WriteBit(PIN_52.port, PIN_52.pin, Bit_RESET);
    } else if  (RCC_GetFlagStatus(RCC_FLAG_PORRST)){
        //GPIO_WriteBit(PIN_52.port, PIN_52.pin, Bit_RESET);
    } else if  (RCC_GetFlagStatus(RCC_FLAG_PINRST)){
        GPIO_WriteBit(PIN_52.port, PIN_52.pin, Bit_RESET);
    } else if  (RCC_GetFlagStatus(RCC_FLAG_IWDGRST)){
        //GPIO_WriteBit(PIN_52.port, PIN_52.pin, Bit_RESET);
    }else if  (RCC_GetFlagStatus(RCC_FLAG_WWDGRST)){
        //GPIO_WriteBit(PIN_52.port, PIN_52.pin, Bit_RESET);
    }else if  (RCC_GetFlagStatus(RCC_FLAG_LPWRRST)){
        //GPIO_WriteBit(PIN_52.port, PIN_52.pin, Bit_RESET);
    }else {
        //GPIO_WriteBit(PIN_52.port, PIN_52.pin, Bit_RESET);
    }
    RCC_ClearFlag();

    while (1);
}

Your RCC_GetFlagStatus() checks in the if - else if chain detected only the first flag in the ordered list, but these flags are not mutually exclusive, you should check all reset flags.您的RCC_GetFlagStatus()检查if - else if链仅检测到有序列表中的第一个标志,但这些标志不是互斥的,您应该检查所有重置标志。

if( RCC_GetFlagStatus(RCC_FLAG_SFTRST) )
{
    //GPIO_WriteBit(PIN_52.port, PIN_52.pin, Bit_RESET);
}

if( RCC_GetFlagStatus(RCC_FLAG_PORRST) )
{
    //GPIO_WriteBit(PIN_52.port, PIN_52.pin, Bit_RESET);
}

// etc...

Since you have an ST-Link debugger, presumably you have a source-level debugger?既然你有一个 ST-Link 调试器,想必你有一个源级调试器? In which case rather then trying to debug this on a single LED pin, use the source-level debugger, and place a breakpoint in each status flag check body.在这种情况下,不要尝试在单个 LED 引脚上进行调试,而是使用源级调试器,并在每个状态标志检查主体中放置一个断点。 Or more simply, but read the entire register in one place:或者更简单,但是在一个地方读取整个寄存器:

uint32_t rcc_status = RCC->CSR ;
RCC->CSR |= RCC_CSR_RMVF ;

while(1) ; // breakpoint here

Then inspect rcc_status value in the debugger.然后在调试器中检查 rcc_status 值。

If as seems likely this is an IWDG reset, then either it has been enabled in software in the start-up or a bootloader, or it is enabled in the Option Bytes .如果看起来这很可能是 IWDG 复位,那么它要么已在启动或引导加载程序中的软件中启用,要么已在Option Bytes中启用。 You can check that by reading the FLASH_OBR (address 0x4002201C)?您可以通过读取FLASH_OBR (地址 0x4002201C)来检查吗? It's default value is 0x03FF FFFC - if in your case it is some other value, then the option bytes (which is a special area of flash memory at 0x1FFFF800 - 0x1FFFF80F) have been modified.它的默认值为 0x03FF FFFC - 如果在您的情况下是其他值,则选项字节(这是 flash memory 在 0x1FFFF800 - 0x1FFFF80F 的特殊区域)已被修改。 Specifically if FLASH_OBR bit 2 (0x04 mask) is zero, then the IWDG will run from reset without being specifically set by software.具体而言,如果FLASH_OBR位 2(0x04 掩码)为零,则 IWDG 将从复位运行,无需软件专门设置。 The option bytes are not described in the general STM32F102 user manual UM0008 , but rather in the flash programming manual PM0075 .选项字节在通用 STM32F102 用户手册UM0008中没有描述,而是在 flash 编程手册PM0075中描述。

A simple test to demonstrate that it is a watchdog reset is simply to maintain the watchdog in the busy-loop:一个简单的测试来证明它是一个看门狗复位是简单地保持看门狗在忙循环中:

while(1)
{
    IWDG_ReloadCounter() ;
}

You can also set/reset the option bytes using the ST-Link Utility .您还可以使用ST-Link Utility设置/重置选项字节。

The IWDG runs from either the 40KHz (nominal but wide variation) RC oscillator, or an external oscillator/crystal on the OSC_32KHz pins. IWDG 从 40KHz(标称但变化很大)RC 振荡器或 OSC_32KHz 引脚上的外部振荡器/晶体运行。 This is normally 32768Hz for an accurate RTC.对于准确的 RTC,这通常是 32768Hz。 Anyway the default prescaler is /4 and the default reload is 0x0FFF (4096).无论如何,默认预分频器是 /4,默认重载是 0x0FFF (4096)。 So for 32768Hz clock, the default IWDG values will cause a timeout at exactly 500ms (4096/(32768/4)) which is what you have observed.因此,对于 32768Hz 时钟,默认 IWDG 值将导致恰好 500 毫秒 (4096/(32768/4)) 的超时,这是您观察到的。 The RC oscilator may range from 30KHz to 60KHz giving a default IWDG range of 273ms to 546ms. RC 振荡器的频率范围可以从 30KHz 到 60KHz,默认 IWDG 范围为 273ms 到 546ms。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM