C STM32F103芯片大约每500毫秒复位一次
我为stm32f103rbt6芯片编写了一个简单的闪烁程序,但过了一会儿,我注意到MCU不断地复位。当我检查RCC-CSR寄存器时,PINRSTF标志为高。 但我没有将任何外部连接到NRST引脚。 有人知道为什么会这样吗?这种情况是否有可能是内部原因造成的 这是我为调试而编写的程序。结果是,每次LED都想打开,但很快就会关闭C STM32F103芯片大约每500毫秒复位一次,c,embedded,stm32,stm32f1,C,Embedded,Stm32,Stm32f1,我为stm32f103rbt6芯片编写了一个简单的闪烁程序,但过了一会儿,我注意到MCU不断地复位。当我检查RCC-CSR寄存器时,PINRSTF标志为高。 但我没有将任何外部连接到NRST引脚。 有人知道为什么会这样吗?这种情况是否有可能是内部原因造成的 这是我为调试而编写的程序。结果是,每次LED都想打开,但很快就会关闭 #include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include
#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);
}
您的
RCC_GetFlagStatus()
检查if
-else如果链仅检测到排序列表中的第一个标志,但这些标志不是互斥的,则应检查所有重置标志
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...
既然您有一个ST Link调试器,那么您大概有一个源代码级调试器?在这种情况下,与其尝试在单个LED管脚上调试,不如使用源代码级调试器,并在每个状态标志检查主体中放置一个断点。或者更简单地说,但在一个位置读取整个寄存器:
uint32_t rcc_status = RCC->CSR ;
RCC->CSR |= RCC_CSR_RMVF ;
while(1) ; // breakpoint here
然后在调试器中检查rcc_状态值
如果这很可能是IWDG重置,则在启动或引导加载程序中已在软件中启用,或者在选项字节中启用。您可以通过读取闪存OBR来检查(地址0x4002201C)?
它的默认值是0x03FF FFFC-如果在您的情况下它是其他值,那么选项字节(在0x1FFF800-0x1FFF80F处是闪存的一个特殊区域)已被修改。具体而言,如果FLASH_OBR
位2(0x04掩码)为零,则IWDG将从复位运行,无需软件专门设置。选项字节未在通用STM32F102用户手册中描述,而是在闪存编程手册中描述
为了证明它是看门狗复位,一个简单的测试就是将看门狗保持在忙碌的循环中:
while(1)
{
IWDG_ReloadCounter() ;
}
您还可以使用设置/重置选项字节
IWDG由40KHz(标称但大范围变化)RC振荡器或OSC_32KHz引脚上的外部振荡器/晶体运行。对于精确的RTC,这通常是32768Hz。无论如何,默认的预分频器是/4,默认的重新加载是0x0FFF(4096)。因此,对于32768Hz时钟,默认的IWDG值将导致正好500毫秒(4096/(32768/4))的超时,这就是您所观察到的。RC振荡器的范围从30KHz到60KHz,默认IWDG范围为273ms到546ms。您的RCC_GetFlagStatus()
在中检查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...
既然您有一个ST Link调试器,那么您大概有一个源代码级调试器?在这种情况下,与其尝试在单个LED管脚上调试,不如使用源代码级调试器,并在每个状态标志检查主体中放置一个断点。或者更简单地说,但在一个位置读取整个寄存器:
uint32_t rcc_status = RCC->CSR ;
RCC->CSR |= RCC_CSR_RMVF ;
while(1) ; // breakpoint here
然后在调试器中检查rcc_状态值
如果这很可能是IWDG重置,则在启动或引导加载程序中已在软件中启用,或者在选项字节中启用。您可以通过读取闪存OBR来检查(地址0x4002201C)?
它的默认值是0x03FF FFFC-如果在您的情况下它是其他值,那么选项字节(在0x1FFF800-0x1FFF80F处是闪存的一个特殊区域)已被修改。具体而言,如果FLASH_OBR
位2(0x04掩码)为零,则IWDG将从复位运行,无需软件专门设置。选项字节未在通用STM32F102用户手册中描述,而是在闪存编程手册中描述
为了证明它是看门狗复位,一个简单的测试就是将看门狗保持在忙碌的循环中:
while(1)
{
IWDG_ReloadCounter() ;
}
您还可以使用设置/重置选项字节
IWDG由40KHz(标称但大范围变化)RC振荡器或OSC_32KHz引脚上的外部振荡器/晶体运行。对于精确的RTC,这通常是32768Hz。无论如何,默认的预分频器是/4,默认的重新加载是0x0FFF(4096)。因此,对于32768Hz时钟,默认的IWDG值将导致正好500毫秒(4096/(32768/4))的超时,这就是您所观察到的。RC振荡器的范围从30KHz到60KHz,给出了273ms到546ms的默认IWDG范围。这不是一个真正的答案,但太多了,无法评论。更多关于如何更有效地调查问题中使用的调试方法。将更新以响应注释或问题更新@aygin(如果即将出现)。我尝试了调试模式。这似乎是看门狗的问题。但问题是我从来没有启用过独立的看门狗,我也不知道如何禁用它。RCC_CSR值为:10 0100 0000 0010。这意味着标志PINRSTF和IWDGRSTF为高。@aygin OK,用选项字节的信息更新。@aygin:当您在问题中声明没有任何东西连接到NRST引脚时,您的ST链接连接了吗?因为那是连接到NRST的。@aygin:的确-我是在内存中工作,没有访问API。根本不需要IWDG_setrelad()
,它已被设置或处于默认状态。但是,您确实应该弄清楚如何禁用它。请注意,启用看门狗时,选项位为零-这可能违反直觉。这不是一个真正的答案,但对于注释来说太多了。更多关于如何更有效地调查问题中使用的调试方法。将更新以响应注释或问题更新@aygin(如果即将出现)。我尝试了调试模式。这似乎是看门狗的问题。但问题是我从来没有启用过独立的看门狗,我也不知道如何禁用它。RCC_CSR值为:10 0100 0000 0010。这意味着标志PINRSTF和IWDGRSTF为高。@aygin OK,已更新选项字节的信息。@aygin:W