stm32l051 не реагирует на ресет.

Кто любит RISC в жизни, заходим, не стесняемся.
Kost286
Родился
Сообщения: 10
Зарегистрирован: Пт окт 23, 2015 18:25:40

stm32l051 не реагирует на ресет.

Сообщение Kost286 »

Всем добрый день. Кто-то сталкивался с тем, что микроконтроллер stm32l051, от батарейного питания, в спящем режиме, перестаёт просыпаться и не реагирует даже на замыкание ножки РЕСЕТ ? Помогает только отключение питания. После этого работать может долго (месяц, два) и опять. Это не один контроллер, а уже много так себя повели.
Реклама
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: stm32l051 не реагирует на ресет.

Сообщение jcxz »

Видимо какой-то баг программы при уходе в сон. Случающийся непериодически.
Реклама
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Re: stm32l051 не реагирует на ресет.

Сообщение AlanDrakes »

Errata на stm32l051 для ревизии "A" прямо ПЕРВЫМ пунктом пишет:
2.1.1 - Выход из режима Stop по событию сбросу невозможен, когда в качестве основного источника тактирования выбран HSI16

Описание:
В режим Stop можно войти независимо от источника тактирования. Системный тактовый генератор после выхода из режима Stop выбирается через бит STOPWUCK регистра RCC_CFGR:
STOPWUCK = 0 - Внутренний тактовый генератор MSI (64kHz .. 4MHz) выбран
STOPWUCK = 1 - Внутренний тактовый генератор HSI16 (16MHz) выбран

Микроконтроллер блокируется (не выбран источник тактирования) при следующих событиях:
- Вход в режим Stop осуществляется когда источником системного тактирования выбран HSI16 и STOPWUCK = 1
- Выход из режима Stop происходит по сбросу (внешнему?)
Только сброс-по-питанию может сбросить микроконтроллер.

Имеется возможность обхода:
1. Перейти на MSI
2. Войти в режим Stop
3. При событии сброса микроконтроллер сбрасывается (любители тафталогии)
4. Код выполняется штатным образом после сброса.

Похоже?


Там же есть про "Проблемы пробуждения Flash-памяти при выходе из режимов Stop и Sleep, когда Flash-контроллер в режиме экономии энергии. Уже для ревизий "A", "Z"
И "Неожиданный сброс при выходе из режима Stop, когда регулятор напряжения в маломощном режиме".

Хотя эти два не должны приводить к полному зависанию.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: stm32l051 не реагирует на ресет.

Сообщение jcxz »

[uquote="AlanDrakes",url="/forum/viewtopic.php?p=4741545#p4741545"]Errata на stm32l051 для ревизии "A" прямо ПЕРВЫМ пунктом пишет:
2.1.1 - Выход из режима Stop по событию сбросу невозможен, когда в качестве основного источника тактирования выбран HSI16
...
Похоже?[/uquote]Нисколько. Потому как у ТС это случается не всегда, а только иногда.
Реклама
Эиком - электронные компоненты и радиодетали
Nranddek
Вымогатель припоя
Сообщения: 598
Зарегистрирован: Сб авг 09, 2025 22:08:28

Re: stm32l051 не реагирует на ресет.

Сообщение Nranddek »

ну, это объясняет, почему сброс только через питание.
вот почему зависает, не объясняет, да. Но это, да, либо баг, либо помехи мощные эпизодически ловит, либо ещё что... ТСу надо предоставлять всё, код, трассировку платы, внешние условия работы...
Реклама
Аватара пользователя
HardWareMan
Мучитель микросхем
Сообщения: 431
Зарегистрирован: Ср сен 02, 2015 07:47:20

Re: stm32l051 не реагирует на ресет.

Сообщение HardWareMan »

Питание батарейное = нестабильное, так что могут портится регистры и срабатывать еррата. Что с настройкой BOD?
Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ
Актуальность репозитория: 22 апреля 2026 года
Если чего-то не хватает с сайта st.com - пишите, докачаю.
/!\ Обновлений для STM32PowerMon и STM32PowerMon-UCPD временно не будет.
Реклама
Kost286
Родился
Сообщения: 10
Зарегистрирован: Пт окт 23, 2015 18:25:40

Re: stm32l051 не реагирует на ресет.

Сообщение Kost286 »

Питание от литиевой батарейки, параллельно кондёры на 4400мкф - даже их хватает на 2 передачи, без них да, по низкому питанию срабатывало бы прерывание. Конструкция такая, если интересно. Повторюсь, некоторые работают по несколько месяцев без проблем, и может раз и пропал. Если батарейк норм, то переподключение её всё приводит в порядок. Неизвестно на сколько. Некоторые начинают во сне жрать несколько милливольт - тут уж контроллер под замену сразу.

Добавлено after 4 minutes 56 seconds:
не пойму почему фото не добавляется

Добавлено after 8 minutes 18 seconds:
Тактирование от внутреннего генератора MSI. В сон уходит на 5 минут + случайное число от 0 до 59 секунд.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: stm32l051 не реагирует на ресет.

Сообщение jcxz »

[uquote="Kost286",url="/forum/viewtopic.php?p=4741564#p4741564"]Повторюсь, некоторые работают по несколько месяцев без проблем, и может раз и пропал.[/uquote]Значит = 90+% вероятность что проблема в коде.
Kost286
Родился
Сообщения: 10
Зарегистрирован: Пт окт 23, 2015 18:25:40

Re: stm32l051 не реагирует на ресет.

Сообщение Kost286 »

ну как бы код не давал бы я думаю такой эффект. Так температуру измеряет и предаёт по лоре. Получается наверно или тактовый генератор спящего режима отваливается (ток потребляет же мало, не видно тестером). Или хз.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: stm32l051 не реагирует на ресет.

Сообщение jcxz »

[uquote="Kost286",url="/forum/viewtopic.php?p=4741571#p4741571"]ну как бы код не давал бы я думаю такой эффект. Так температуру измеряет и предаёт по лоре. Получается наверно или тактовый генератор спящего режима отваливается (ток потребляет же мало, не видно тестером).[/uquote]Ну да - проще ведь самые фантастические теории придумывать, чем в коде разбираться. :)))
С чего бы он "отваливался" если напряжение питания в норме? А оно ведь в норме? (ведь это несложно проверить мультиметром)
С таким же успехом можно предполагать, что биты в каком-то регистре CPU самопроизвольно инвертируются под влиянием тёмной материи. Ну чем не теория? 8)

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

Добавлено after 6 minutes 22 seconds:
[uquote="Nranddek",url="/forum/viewtopic.php?p=4741548#p4741548"]либо помехи мощные эпизодически ловит[/uquote]Это решается испытанием устройства на помехоустойчивость.

Добавлено after 4 minutes 32 seconds:
[uquote="Kost286",url="/forum/viewtopic.php?p=4741564#p4741564"]Тактирование от внутреннего генератора MSI. В сон уходит на 5 минут + случайное число от 0 до 59 секунд.[/uquote]В целях "ловли блох" генерим прошивку, которая будет уходить в сон в ~100 раз чаще (~3 секунды + случайное). И запускаем на техпрогон несколько десятков устройств (или больше) с такой прошивкой.
Для ускорения поиска бага.
Kost286
Родился
Сообщения: 10
Зарегистрирован: Пт окт 23, 2015 18:25:40

Re: stm32l051 не реагирует на ресет.

Сообщение Kost286 »

У меня лежит один на окне уже с зимы и работает, питание батарейки снизилось на 0.1В, передаёт без нареканий, прошивка одна и та же.

Добавлено after 4 minutes 59 seconds:
вот фото

Добавлено after 12 minutes 29 seconds:
AlanDrakes в самом верху же написал, что тактирование HSI отрубается. У меня только внутренний использован. Если бы в коде ошибка, он бы или не засыпал, или не работал бы вообще, а не так, что хз когда перестанет. Если бы случайно уходил на большое время в сон, то ресет срабатывал бы (из сна он выводит). Если бы не уходил в сон - батарейку бы жрал.

Добавлено after 4 minutes 42 seconds:
там кода то всего
int main(void)
{
uint16_t volt=0;

HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC_Init();
MX_RTC_Init();
MX_USART1_UART_Init();
MX_NVIC_Init();

//BKP Registers enabled
HAL_PWR_EnableBkUpAccess();
i_rtc = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1); //чтение нового случайного числа из памяти и подстановка его в random
m_rtc = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);
if (m_rtc > 59) m_rtc = 59;
if (i_rtc > 59) i_rtc = 59;
//установка выводов в 1 редима работы ЛОРЫ (это спящий режим)

HAL_GPIO_WritePin(LORA_Mode1_GPIO_Port, LORA_Mode1_Pin, SET);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);

if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST)){
RTC_Delay(m_rtc, i_rtc); // Установка времени на энергосбережение
__HAL_RCC_CLEAR_RESET_FLAGS();
HAL_PWR_EnterSTANDBYMode();
}
else{
MX_IWDG_Init();
//чтение напряжения питания
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc,1000);
volt=HAL_ADC_GetValue(&hadc)>>2;
if (volt==0) volt=1;
HAL_ADC_Stop(&hadc);
__HAL_RCC_CLEAR_RESET_FLAGS();
}

HAL_IWDG_Refresh(&hiwdg);

while (1)
{
HAL_GPIO_WritePin(DS18_VCC_new_GPIO_Port, DS18_VCC_new_Pin, SET);
HAL_Delay(25);
status = ds18b20_init(SKIP_ROM);
HAL_Delay(2);
ds18b20_MeasureTemperCmd(SKIP_ROM, 0);

HAL_Delay(610);

//чтение температуры
ds18b20_ReadStratcpad(SKIP_ROM, dt, 0);
raw_temper = ((uint16_t)dt[1]<<8)|dt[0];
temper = ds18b20_Convert(raw_temper);
HAL_Delay(3);
HAL_GPIO_WritePin(DS18_VCC_new_GPIO_Port, DS18_VCC_new_Pin, RESET);

HAL_GPIO_WritePin(LORA_Mode1_GPIO_Port, LORA_Mode1_Pin, RESET);
if (temper >= 100.0 || temper <= 1.0) temper = 1.0;
HAL_Delay(28);

srand(volt+/*(uint16_t)i_rtc+*/(uint16_t)temper); //установка начального числа для рандома
i_rtc=rand()%(59); //вычисление рандома в диапазоне от 0 до 59 //i_rtc=rand()%(59-5+1) + 5;
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, i_rtc); //Запись рандома для следующего захода после сна
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, 6);
if (i_rtc >= 59) i_rtc = 59;

str1[0]='A';
str1[1]=DAT_addr;
str1[2]=(uint8_t)(temper);//
str1[3]=0xff-volt;
str1[4]='\r';
HAL_UART_Transmit(&huart1, str1, 5/*strlen(str1)*/, 1000);

RTC_Delay(5, 0/*i_rtc*/); // Установка времени на энергосбережение
HAL_Delay(35);

HAL_GPIO_WritePin(LORA_Mode1_GPIO_Port, LORA_Mode1_Pin, SET);
HAL_IWDG_Refresh(&hiwdg);
HAL_PWR_EnterSTANDBYMode();
}
}

Добавлено after 1 minute 23 seconds:
IWDG добавлен уже потом на крайний случай, а вдруг чего, но не помог.
Вложения
IMG_20250826_141232[1].png
фото
(227.47 КБ) 104 скачивания
Nranddek
Вымогатель припоя
Сообщения: 598
Зарегистрирован: Сб авг 09, 2025 22:08:28

Re: stm32l051 не реагирует на ресет.

Сообщение Nranddek »

оберните код в тэг [ code] [ /code]

ну, как бы это не "всего", это вызов кучи функций (без них там десяток строк едва ли наберётся), если их развернуть, то станет немного больше ;)

Добавлено after 6 minutes 34 seconds:
а флаг PWR_FLAG_SB не надо сбрасывать каждое пробуждение?
Kost286
Родился
Сообщения: 10
Зарегистрирован: Пт окт 23, 2015 18:25:40

Re: stm32l051 не реагирует на ресет.

Сообщение Kost286 »

сбрасывается __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
Nranddek
Вымогатель припоя
Сообщения: 598
Зарегистрирован: Сб авг 09, 2025 22:08:28

Re: stm32l051 не реагирует на ресет.

Сообщение Nranddek »

в блоке while (1) не увидел...

Добавлено after 2 hours 10 minutes 32 seconds:
у ST видел такую конструкцию:

Код: Выделить всё

PWR_ClearFlag(PWR_FLAG_SB); 
PWR_EnterSTANDBYMode();
у Вас:

Код: Выделить всё

while (1)
{
...
HAL_IWDG_Refresh(&hiwdg);
HAL_PWR_EnterSTANDBYMode();
}
(полагаю, на HAL тут можно не обращать внимания)
Хотя, сомневаюсь, что это приведёт к такому поведению. Скорее, просто невозможно будет узнать событие, вызвавшее возврат в активный режим.
Бубоник
Мучитель микросхем
Сообщения: 449
Зарегистрирован: Вс авг 16, 2015 13:08:53

Re: stm32l051 не реагирует на ресет.

Сообщение Бубоник »

Код: Выделить всё

str1[4]='\r';
А как это он лихо два символа в один байт затолкал?
Nranddek
Вымогатель припоя
Сообщения: 598
Зарегистрирован: Сб авг 09, 2025 22:08:28

Re: stm32l051 не реагирует на ресет.

Сообщение Nranddek »

'\r' = 13
Size of '\r' in bytes: 1
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: stm32l051 не реагирует на ресет.

Сообщение jcxz »

[uquote="Kost286",url="/forum/viewtopic.php?p=4741587#p4741587"]if (temper >= 100.0 || temper <= 1.0) temper = 1.0;[/uquote]Используем double на таком дохлом МК??? :facepalm:
У меня на Cortex-M7 ни одного дабла нет.

[uquote="Kost286",url="/forum/viewtopic.php?p=4741587#p4741587"]i_rtc=rand()%(59); //вычисление рандома в диапазоне от 0 до 59 //i_rtc=rand()%(59-5+1) + 5;[/uquote]Это не в диапазоне 0...59, а в дипазоне 0...58.
Да и нафига тут деление? Здесь эффективнее умножение использовать.

[uquote="Kost286",url="/forum/viewtopic.php?p=4741587#p4741587"]str1[2]=(uint8_t)(temper);//[/uquote]Оказывается нужен только один байт от temper... нафига тогда ранее аж с double-ом тягались?
Я уж не говорю что double и float могут принимать и спец.значения типа NaN, +inf, -inf, etc.. Обработки коих тут совсем не наблюдается...

[uquote="Kost286",url="/forum/viewtopic.php?p=4741587#p4741587"]HAL_PWR_EnterSTANDBYMode();[/uquote]А где выключение тактирования всей периферии и всего остального, не нужного во сне? Или Хал это сам делает?

Вобщем - вы понадеялись на Хал. Что он сам всё сделает правильно в HAL_PWR_EnterSTANDBYMode(). А нужно было открывать мануал на МК и изучать регистры и биты для состояния сна. И самостоятельно ими управлять. Отсюда и проблемы.

PS: Код весьма отстойный: Задержки, "магические числа", неоптимальные операции, Хал, ... Не мудрено что он глючит...
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Re: stm32l051 не реагирует на ресет.

Сообщение AlanDrakes »

Я чаще загонял чип в режим DeepSleep, нежели в Standby. Да, потребление выше, но он выходит из сна даже на той же инструкции, где был.
Спойлер

Код: Выделить всё

volatile uint8_t TIM21_WAKE = 0;
volatile uint8_t ButtonPressed = 0;

void TIM21_IRQHandler(void) {
	TIM21->SR &= ~TIM_SR_UIF;
	TIM21_WAKE = 1;
}

void EXTI0_1_IRQHandler(void) {
	EXTI->PR = EXTI_PR_PR0;
	ButtonPressed = 1;
}

void deep_sleep(void) {
	uint32_t tmp;
	SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk);	// Deep sleep
	RCC->APB2ENR &= ~(RCC_APB2ENR_DBGEN);
	RCC->IOPSMENR &= ~(RCC_IOPSMENR_IOPBSMEN);
	RCC->APB1SMENR &= ~(RCC_APB1SMENR_PWRSMEN);
	PWR->CR |= PWR_CR_ULP | PWR_CR_FWU;	// Ultra low power
	FLASH->ACR |= FLASH_ACR_SLEEP_PD; // <- Вот тут я теотерически мог поймать аппаратный баг. Но, видимо, ревизия более свежая.
	while (DMA_TTY0_TX); // Ждём окончания передачи текста. Если есть.
	while (!(USART1->ISR & USART_ISR_TC)); // Ждём полного окончания передачи (уже опрашиваем UART)
	RCC->APB1ENR |= RCC_APB1ENR_PWREN;
	PWR->CR |= PWR_CR_LPSDSR; // Регулятор напряжения в маломощный режим.
	SCB->SCR &= ~( SCB_SCR_SLEEPDEEP_Msk ); // Глубокий сон
	
	__WFI(); // Проваливаемся в сон и останавливаемся тут.
	
	RCC->APB2ENR |= (RCC_APB2ENR_DBGEN); // После пробуждения - возвращаем всё как было.
	RCC->IOPSMENR |= (RCC_IOPSMENR_IOPBSMEN);
	RCC->APB1SMENR |= (RCC_APB1SMENR_PWRSMEN);
}

void InitIO(void) {
	// Enable USART1 (tty0), DBG, TIM22, TIM21
	RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_DBGEN | RCC_APB2ENR_TIM22EN | RCC_APB2ENR_TIM21EN;
	RCC->APB2SMENR = RCC_APB2SMENR_USART1SMEN | RCC_APB2SMENR_DBGSMEN | RCC_APB2SMENR_TIM22SMEN | RCC_APB2SMENR_TIM21SMEN;
	// Reset ADC, Timers, USART
	RCC->APB2RSTR = RCC_APB2RSTR_ADCRST | RCC_APB2RSTR_TIM22RST | RCC_APB2RSTR_TIM21RST | RCC_APB2RSTR_USART1RST;
	RCC->APB2RSTR = 0;
	// Разрешаем отладку
	DBGMCU->CR |= DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STANDBY | DBGMCU_CR_DBG_STOP;
	// Включаем GPIOA + GPIOB
	// Enable DMA1 (UART)
	RCC->AHBENR |= RCC_AHBENR_DMA1EN;
	// GPIOA, GPIOB.
	RCC->IOPENR |= RCC_IOPENR_IOPAEN | RCC_IOPENR_IOPBEN;
	RCC->IOPSMENR = RCC_IOPSMENR_IOPASMEN | RCC_IOPSMENR_IOPBSMEN;
	
	// PA0 - WkUP
	// PA3 - Res power
	// PA4, PA5 - ADC
	// PA9, PA10 - USART
	// PA13, PA14 - SWD
	
	// PB4 - LED_EN
	// PB5 - LED_2
	// PB6 - Low batt LED
	
	// GPIOA.MODER = [aAAaaAAa|aaaaOaaI] -> 1110.1011.1110.1011.1111.1111.0111.1100
	GPIOA->MODER = 		0xEBEBFF7C;
	GPIOA->AFR[1] |=	0x00000440;	// GPIOA[9,10]->AF-> USART
	
	// GPIOB.MODER = [aaaaaaaa|aOAAaaaa] -> 1111.1111.1111.1111.1101.1010.1111.1111
	GPIOB->MODER = 		0xFFFFDAFF;
	GPIOB->AFR[0] =		0x00440000;	// GPIOB[4,5]->AF-> TIM22_CH[1,2]
	GPIOB->ODR = 0;
	
	
	// PWR ---> Range 3
	RCC->ICSCR = (3 <<  13);			// MSI range 3
	RCC->APB1ENR |= RCC_APB1ENR_PWREN;		// Enable PWR module
	RCC->APB2ENR |= RCC_APB2ENR_TIM22EN;		// Enable TIM22
	RCC->APB2SMENR |= RCC_APB2SMENR_TIM22SMEN;	// Enable TIM22 in SLEEP mode
	
	PWR->CSR = PWR_CSR_EWUP1;			// Enable WakeUP1 (PA0) pin
	FLASH->ACR |= FLASH_ACR_PRFTEN;			// Enable flash prefetch
	
	RCC->CR |= RCC_CR_MSION;			// Enable MSI generator
	while (!(RCC->CR & RCC_CR_MSIRDY)) {};		// Wait till ready
	RCC->CIER &= 0xFFFFFFFC;			// Core clock -> MSI
	while (RCC->CIER & 0x0C) {};			// Wait till switch
	
	RCC->CR &= ~(RCC_CR_HSION);			// Disable HSI
	
	TIM21->CR1 = TIM_CR1_ARPE;			// TIM21 Разрешаем автозагрузку значений.
	TIM21->PSC = 523;				// 524288/524 = 1000.55 LSB / second. ~1 ms/LSB
	
	TIM21->EGR = TIM_EGR_UG;			// TIM21 -> Генерируем событие обновления регистров.
	TIM21->SR &= ~TIM_SR_UIF;			// Сброс флага (если взвёлся)
	TIM21->DIER = TIM_DIER_UIE;			// Разрешаем прерывание по переполнению (~65`535мс)
	TIM21->CR1 |= TIM_CR1_CEN;			// TIM21 -> Запуск
	
	TIM22->CR1 = 0;					// TIM22 - Сброс битов настроек. Запись в ->ARR - прямая.
	TIM22->PSC = 523;				// 524288/524 = 1000.55 LSB / second. ~1 ms/LSB
	TIM22->CCMR1 = TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE;
	TIM22->CCER = TIM_CCER_CC2E | TIM_CCER_CC1E;
	TIM22->CCR1 = 0x0100;
	TIM22->CCR2 = 0x0100;
	TIM22->EGR = TIM_EGR_UG;			// TIM22 -> Генерируем событие обновления регистров.
	TIM22->SR &= ~TIM_SR_UIF;			// Сброс флага (если взвёлся)
	TIM22->CR1 |= TIM_CR1_CEN;			// TIM22 -> Запуск
	
	NVIC_EnableIRQ(TIM21_IRQn);
	
	// Enable PWR in range 3
	PWR->CR |= PWR_CR_VOS_0 | PWR_CR_VOS_1;
	// Clear [Wakeup] flag
	PWR->CR |= PWR_CR_CWUF;

	EXTI->IMR |= EXTI_IMR_IM0;
	EXTI->RTSR |= EXTI_RTSR_RT0;
	NVIC_SetPriority(EXTI0_1_IRQn, 2);
	NVIC_EnableIRQ(EXTI0_1_IRQn);
}




// ....

	while(1) {
		deep_sleep();
		while (tty_IsSymbolReady()) {
			microrl_insert_char(prl, tty_GetChar());
		}
		if (ButtonPressed) {
			ButtonPressed = 0;
			console_timestamp();
			console_put("Config button pressed.\r\n");
			
			SleepTimeout_Minutes = 3;
			// Enable LED2
			// PB5 -> Floating -> Alternative
			GPIOB->MODER &= ~(0x00000400);
			SystemCoreClockUpdate();
			SysTick_Config(SystemCoreClock / 5);
		}
		if (TIM21_WAKE) {
			TIM21_WAKE = 0;
			if (SleepTimeout_Minutes) {
				if (--SleepTimeout_Minutes == 0) {
					// Disable LED2
					// PB5 -> Alternative -> Floating
					GPIOB->MODER |=   0x00000400;
					SysTick->CTRL &= ~(SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk);
					console_timestamp();
					console_put("Returning to idle mode.\r\n");
				}
			}
		}
		if (TickWake) {
			TickWake = 0;
			UpdateValues();
			FindRange();
		}
	}
Примерно так.
Из минусов - приходится при прошивке изменять OptionBytes, чтобы выставить BOR в 0xxx - "выключен". Иначе при низком напряжении пары С-батареек чип может не запуститься в случае сброса.

Кстати, да. Kost286, а какой диапазон напряжения у прибора? Может у Вас при падении напряжения до [примерного] уровня срабатывания BOR'а происходит защёлкивание? У него ведь некоторый гистерезис срабатывания и отпускания сброса.

Посмотрите биты FLASH->OTPR[19:16]
Bits 19:16 BOR_LEV: Brownout reset threshold level
These bits reset the threshold level for a 1.45 V to 1.55 V voltage range (power-down only). In
this particular case, VDD must have been above VBOR0 to start the device OBL sequence, in
order to disable the BOR. The power-down is then monitored by the PDR. If the BOR is
disabled, a “grey zone” exists between 1.65 V and the VPDR threshold (this means VDD can
be below the minimum operating voltage (1.65 V) without any reset until the VPDR threshold).
If there is a mismatch on this configuration during the Option bytes loading, it is loaded with
0x8.
0xxx: BOR OFF. This is the reset threshold level for the 1.45 V - 1.55 V voltage range
(power-down only).
In this particular case, VDD must have been above BOR LEVEL 1 to start the device OBL
sequence in order to disable the BOR. The power-down is then monitored by the PDR.
Note: If the BOR is disabled, a "grey zone" exists between 1.65 V and the VPDR threshold
(this means that VDD may be below the minimum operating voltage (1.65 V) without
causing a reset until it crosses the VPDR threshold)
1000: BOR LEVEL 1 is the reset threshold level for VBOR0 (around 1.8 V)
1001: BOR LEVEL 2 is the reset threshold level for VBOR1 (around 2.0 V)
1010: BOR LEVEL 3 is the reset threshold level for VBOR2 (around 2.5 V)
1011: BOR LEVEL 4 is the reset threshold level for VBOR3 (around 2.7 V).
1100: BOR LEVEL 5 is the reset threshold level for VBOR4 (around 3.0 V)
Note: Refer to the device datasheets for the exact definition of BOR levels.
И в datasheet'е описаны типичные значения напряжений для срабатывания и отпускания сброса. Так-то он вроди бы настроен на 1.8В, но мало ли.
Kost286
Родился
Сообщения: 10
Зарегистрирован: Пт окт 23, 2015 18:25:40

Re: stm32l051 не реагирует на ресет.

Сообщение Kost286 »

Nranddek писал(а):Скорее, просто невозможно будет узнать событие, вызвавшее возврат в активный режим.
Всё узнаётся.

Добавлено after 2 minutes 22 seconds:
AlanDrakes, напряжение при передаче падает до 3,5 вольт всего. Даже без батарейки одних кондёров хватает на 2 передачи.

Добавлено after 4 minutes 31 second:
jcxz, приёчем здесь доублы и прочее? Вопрос же не в том как лучше в коде сделать, а почему из сна не выходит и можно ли узнать почему и можно ли исправить.
Nranddek
Вымогатель припоя
Сообщения: 598
Зарегистрирован: Сб авг 09, 2025 22:08:28

Re: stm32l051 не реагирует на ресет.

Сообщение Nranddek »

[uquote="Kost286",url="/forum/viewtopic.php?p=4741789#p4741789"]Всё узнаётся.[/uquote]
не сбрасывая флаг? каким же образом?
Ответить

Вернуться в «ARM»