Здравствуйте. Помогите разобраться с энергосберегающими режимами микроконтроллера STM32F103. Нужно переходить в режим STOP и раз в секунду просыпаться для подсчета времени(пока просто светодиодом помигаем). После чтения документов и поиска в интернете установлено следующее, в режим STOP контроллер переводится командой PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE); после чего его могут разбудить только внешние прерывания/события EXTI. В моем случае с будильником работает событие EXTI_Line17. Чтобы «завести» будильник нужно в регистры RTC->ALRH и ALRL записать число при достижении которого счетным регистром сработает будильник. Вроде все просто. Проблема: контроллер не просыпается при наступлении события. Если остановить отладку, курсор буден находится на строке 228, а счетчик "утикал" далеко за установленное время.
 Если продолжить пошаговую отладку, то контроллер выполняет один цикл, уходит в спячку и останавливается на том же месте Вопрос, что я делаю не так. Вот код проекта
Код: #include "stm32f10x.h" // Device header #include "stm32f10x_exti.h" // Keil::Device:StdPeriph Drivers:EXTI #include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO #include "stm32f10x_pwr.h" // Keil::Device:StdPeriph Drivers:PWR #include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC #include "stm32f10x_rtc.h" // Keil::Device:StdPeriph Drivers:RTC #include "misc.h" // Keil::Device:StdPeriph Drivers:Framework #include "stm32f10x_dbgmcu.h" // Keil::Device:StdPeriph Drivers:DBGMCU GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStruct; /* Инициализация RTC */ unsigned char RTC_Init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); PWR_BackupAccessCmd(ENABLE); if ((RCC->BDCR & RCC_BDCR_RTCEN) != RCC_BDCR_RTCEN) { RCC_BackupResetCmd(ENABLE); RCC_BackupResetCmd(DISABLE);
RCC_LSEConfig(RCC_LSE_ON); while ((RCC->BDCR & RCC_BDCR_LSERDY) != RCC_BDCR_LSERDY) {} RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
/* Set prescaler */ RTC_SetPrescaler(0x7FFF);
/* Enable RTC */ RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
return 1; } return 0; }
int main(void) {
DBGMCU->CR |=(DBGMCU_CR_DBG_STOP );//Чтобы работала отладка в режиме STOP /* Инициализация светодиода на PINB_12*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // /* Configure the GPIO_LED pin */ // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO_Init(GPIOC, &GPIO_InitStructure); RTC_Init();//Инициализация RTC
/*Настраиваем событие по будильнику, линия EXTI_Line17 */ EXTI_DeInit(); EXTI_StructInit(&EXTI_InitStruct); EXTI_InitStruct.EXTI_Line = EXTI_Line17; /* Enable interrupt */ EXTI_InitStruct.EXTI_LineCmd = ENABLE; /* Interrupt mode */ EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Event; /* Triggers on falling edge */ EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;//;EXTI_Trigger_Falling /* Add to EXTI */ EXTI_Init(&EXTI_InitStruct);
while (1) { GPIOB->ODR ^= GPIO_Pin_12;//Дрыгаем ногой /*Настраиваем таймер для сна*/ RTC->CRL |= RTC_CRL_CNF;//Разрешаем запись RTC->CNTL = 0;//обнуляем счетчик, ну надо мне так.. RTC->ALRL = 3;//заводим будильник на 3 мекунды RTC->CRL &= (uint16_t)~((uint16_t)RTC_CRL_CNF); //закрываем запись
RTC_WaitForLastTask();
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);//Переводим контроллер в режим STOP } }
|