Чип STM32F103 сбрасывается каждые 500 мс - PullRequest
0 голосов
/ 25 мая 2020

Я написал простую программу мигания для микросхемы stm32f103rbt6, но через некоторое время заметил, что MCU постоянно сбрасывается. Когда я проверяю регистр R CC -CSR, флаг PINRSTF высокий. но я не подключал ничего внешне к выводу NRST. Есть ли у кого-нибудь идеи, почему это происходит? Возможно ли, что что-то внутри вызывает эту ситуацию?

Это программа, которую я написал для отладки. в результате светодиод каждый раз хочет включиться, но быстро гаснет.

#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);
}

1 Ответ

2 голосов
/ 25 мая 2020

Ваши 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, возможно, у вас есть отладчик на уровне исходного кода? В этом случае вместо того, чтобы пытаться отладить это на одном выводе светодиода, используйте отладчик исходного уровня и поместите точку останова в каждое тело проверки флага состояния. Или проще, но читать весь регистр в одном месте:

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

while(1) ; // breakpoint here

Затем проверьте значение rcc_status в отладчике.

Если кажется вероятным, что это сброс IWDG, то он либо был включен программно при запуске, либо загрузчиком, либо включен в байтах опций . Вы можете проверить это, прочитав FLASH_OBR (адрес 0x4002201 C)? Его значение по умолчанию - 0x03FF FFF C - если в вашем случае это какое-то другое значение, то байты опций (которые являются специальной областью памяти fla sh по адресу 0x1FFFF800 - 0x1FFFF80F) были изменены. . В частности, если FLASH_OBR бит 2 (маска 0x04) равен нулю, то IWDG будет работать после сброса, не будучи специально установленным программным обеспечением. Байты опций описаны не в общем руководстве пользователя STM32F102 UM0008 , а в руководстве по программированию fla sh PM0075 .

Простой тест для демонстрации этого это сброс сторожевого таймера просто для поддержания сторожевого таймера в занятом-l oop:

while(1)
{
    IWDG_ReloadCounter() ;
}

Вы также можете установить / сбросить байты опций с помощью ST-Link Utility .

IWDG работает либо от генератора R C 40 кГц (номинальный, но широкий диапазон), либо от внешнего генератора / кристалла на выводах OSC_32KHz. Обычно это 32768 Гц для точного RT C. В любом случае предварительный делитель по умолчанию - / 4, а перезагрузка по умолчанию - 0x0FFF (4096). Таким образом, для частоты 32768 Гц значения IWDG по умолчанию вызовут тайм-аут ровно 500 мс (4096 / (32768/4)), что вы и наблюдали. Осциллятор R C может работать в диапазоне от 30 кГц до 60 кГц, что дает диапазон IWDG по умолчанию от 273 мс до 546 мс.

...