[英]STM32F103 chip keeps resetting about every 500ms
我為 stm32f103rbt6 芯片寫了一個簡單的閃爍程序,但過了一會兒我注意到 MCU 不斷地復位。 當我檢查 RCC-CSR 寄存器時,PINRSTF 標志為高。 但我沒有將任何外部連接到 NRST 引腳。 有人知道為什么會這樣嗎? 有沒有可能是什么內部原因導致了這種情況?
這是我為調試而編寫的程序。 結果是每次 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);
}
您的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...
既然你有一個 ST-Link 調試器,想必你有一個源級調試器? 在這種情況下,不要嘗試在單個 LED 引腳上進行調試,而是使用源級調試器,並在每個狀態標志檢查主體中放置一個斷點。 或者更簡單,但是在一個地方讀取整個寄存器:
uint32_t rcc_status = RCC->CSR ;
RCC->CSR |= RCC_CSR_RMVF ;
while(1) ; // breakpoint here
然后在調試器中檢查 rcc_status 值。
如果看起來這很可能是 IWDG 復位,那么它要么已在啟動或引導加載程序中的軟件中啟用,要么已在Option Bytes中啟用。 您可以通過讀取FLASH_OBR
(地址 0x4002201C)來檢查嗎? 它的默認值為 0x03FF FFFC - 如果在您的情況下是其他值,則選項字節(這是 flash memory 在 0x1FFFF800 - 0x1FFFF80F 的特殊區域)已被修改。 具體而言,如果FLASH_OBR
位 2(0x04 掩碼)為零,則 IWDG 將從復位運行,無需軟件專門設置。 選項字節在通用 STM32F102 用戶手冊UM0008中沒有描述,而是在 flash 編程手冊PM0075中描述。
一個簡單的測試來證明它是一個看門狗復位是簡單地保持看門狗在忙循環中:
while(1)
{
IWDG_ReloadCounter() ;
}
您還可以使用ST-Link Utility設置/重置選項字節。
IWDG 從 40KHz(標稱但變化很大)RC 振盪器或 OSC_32KHz 引腳上的外部振盪器/晶體運行。 對於准確的 RTC,這通常是 32768Hz。 無論如何,默認預分頻器是 /4,默認重載是 0x0FFF (4096)。 因此,對於 32768Hz 時鍾,默認 IWDG 值將導致恰好 500 毫秒 (4096/(32768/4)) 的超時,這是您觀察到的。 RC 振盪器的頻率范圍可以從 30KHz 到 60KHz,默認 IWDG 范圍為 273ms 到 546ms。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.