STM32F103 энергосберегающий режим STOP

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Аватара пользователя
vikonik
Открыл глаза
Сообщения: 46
Зарегистрирован: Сб дек 13, 2014 16:32:13

STM32F103 энергосберегающий режим STOP

Сообщение vikonik »

Здравствуйте.
Помогите разобраться с энергосберегающими режимами микроконтроллера 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
  }
}

Реклама
Аватара пользователя
vikonik
Открыл глаза
Сообщения: 46
Зарегистрирован: Сб дек 13, 2014 16:32:13

Re: STM32F103 энергосберегающий режим STOP

Сообщение vikonik »

Проблема решилась следующим образом:

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

/*Настраиваем таймер для сна*/
RTC->CRL |= RTC_CRL_CNF;//Разрешаем запись
RTC->CNTH = 0;//обнуляем счетчик
RTC->CNTL = 0;//обнуляем счетчик
RTC->ALRH = 0;
RTC->ALRL = 3;//заводим будильник на 3 мекунды
RTC->CRL &= (uint16_t)~((uint16_t)RTC_CRL_CNF); //закрываем запись
Реклама
Ответить

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