Посмотрел в отладке выполнение кода. Функция
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB();
SCB->AIRCR = ((0x5fa << SCB_AIRCR_VECTKEY_Pos) | (SCB->ARICR & SCB_AIRCR_PRIGROUP_Msk) | (SCB_AIRCR_SYSRESETREQ_Msk);
__DSB();
while(1);
}
висит на последнем пустом цикле и дальше не идет. Что же это может быть? Да и в режиме отладки сброс ядра тоже не работает.
Вспоминается, что в 1901ВЦ1Т есть кэш инструкций. Может он как-то мешает? Попробуйте вставить __ISB(); и (много) нопов перед while(1).
Само собой, глобально запретить прерывания перед вызовом NVIC_SystemReset(). Странно, что этого не делает сама NVIC_SystemReset()...
Хотя и времени много прошло и наверное все уже всё знают, НО! Для программного сброса 1901ВЦ1Т (а также 1986ВЕ1Т, 1986ВЕ91Т) следует использовать особенность работы WWDG, так как сброс с помощью AIRCR регистра НЕ работает. О чем и сообщается в errata на соответствующий контроллер.
Пример программного сброса 1901ВЦ1Т с помощью WWDG:
typedef unsigned char u8;
typedef unsigned int u32;
#define CLK_WWDT 12
/* Enable clock of specified peripheral block */
__STATIC_INLINE void ClkEnable(u8 clknum)
{
RST_CLK->PER_CLOCK |= (1 << (u32)(clknum & 0x1F));
}
/* Soft reset */
__STATIC_INLINE void MCUSoftReset()
{
//Use watch timer to reset: when T > W - RESET generated
//Enable WWDG clock
ClkEnable(CLK_WWDT);
//EWI[9] = 0 - Disable interrupt
//WGTB[8..7] = 0 - TMCLK = PCLK / 4096 / 1
//W[6..0] = 0 - window is 0
WWDG->CFR = 0x00;
//WDGA[7] = 1 - timer ON
//T[6..0] = 0x7F - timer counter
WWDG->CR = 0xFF;
WWDG->CR = 0xFF;
}