Прощу помощи.
Задача такова... Надо загонять кристалл в STOP, пробуждаться при изменении состояния внешних линий и раз в хх сек. Кристалл тактируется от внутреннего HS, часы так же запускаю от внутреннего LS.
Загнать кристалл в STOP проблем не составляет. Проблема пробудить его от туда.
Пробовал как режим WFI, так и WFE... Суть дела не меняет.
По часам - такое ощущение, что LSI выключается при переходе в STOP. Однозначно остается включенным если задействован IWDT. Но мне решение с wd не очень нравиться... Если есть возможность - надо её использовать, а не строить обходные тропинки.
По внешним линиям... Мысли вообще нет. В этом примере использую PA0. Но в настоящем устройстве PA12-15. Этот пример - пытаюсь дома с дискавери понять в чем фикус.
В общем - прощу тех, кто с этой проблемой сталкивался - подскажите куда капать...
Заранее спасибо !
CODE
#include "stm32f10x.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_pwr.h"
#include "stm32f10x_rtc.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_bkp.h"
#include "misc.h"
/***************************************************************************//**
* Global variables
******************************************************************************/
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/***************************************************************************//**
* Declare function prototype
******************************************************************************/
void RCC_Configuration(void);
void RTC_Configuration(void);
void GPIO_Configuration(void);
void EXTI_Configuration(void);
void delay(void);
/***************************************************************************//**
*
******************************************************************************/
void RCC_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
}
/***************************************************************************//**
*
******************************************************************************/
void RTC_Configuration(void)
{
PWR_BackupAccessCmd(ENABLE);
/* RTC clock source configuration ----------------------------------------*/
/* Reset Backup Domain */
BKP_DeInit();
// Enable LSE OSC
RCC_LSICmd(ENABLE);
// Wait till LSE is ready
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
// Select the RTC Clock Source
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* RTC configuration -----------------------------------------------------*/
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
/* Set the RTC time base to 1s */
RTC_SetPrescaler(32767);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
RTC_SetCounter(0);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set the RTC Alarm after 3s */
RTC_SetAlarm(3);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_ALR,ENABLE);
}
/***************************************************************************//**
*
******************************************************************************/
void GPIO_Configuration(void)
{
// User button
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// LED's
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// Switch off LED's
GPIO_ResetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9);
// Disable tamper pin. PORTA.0
PWR_WakeUpPinCmd(DISABLE);
}
/***************************************************************************//**
*
******************************************************************************/
void EXTI_Configuration(void)
{
GPIO_EventOutputConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
GPIO_EventOutputCmd(ENABLE);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
/***************************************************************************//**
*
******************************************************************************/
void NVIC_Configuration(void)
{
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the WAKEUP_BUTTON_IRQn Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/***************************************************************************//**
*
******************************************************************************/
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_ALR) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_ALR);
RTC_WaitForLastTask();
RCC_Configuration();
GPIO_Configuration();
GPIO_SetBits(GPIOC, GPIO_Pin_8);
delay();
GPIO_ResetBits(GPIOC, GPIO_Pin_8);
RTC_SetCounter(0);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set the RTC Alarm after 3s */
RTC_SetAlarm(3);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
}
/***************************************************************************//**
*
******************************************************************************/
void delay(void)
{
volatile unsigned int a=1000;
while(a--)
{
volatile unsigned int b=1000;
while(b--);
}
}
/***************************************************************************//**
*
******************************************************************************/
void main(void)
{
RCC_Configuration();
GPIO_Configuration();
EXTI_Configuration();
RTC_Configuration();
NVIC_Configuration();
GPIO_SetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9);
delay();
GPIO_ResetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9);
while (1)
{
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);
if ( EXTI_GetFlagStatus(EXTI_Line0) == SET )
{
EXTI_ClearFlag(EXTI_Line0);
RCC_Configuration();
GPIO_Configuration();
GPIO_SetBits(GPIOC, GPIO_Pin_9);
delay();
GPIO_ResetBits(GPIOC, GPIO_Pin_9);
}
}
}
#include "stm32f10x_exti.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_pwr.h"
#include "stm32f10x_rtc.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_bkp.h"
#include "misc.h"
/***************************************************************************//**
* Global variables
******************************************************************************/
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/***************************************************************************//**
* Declare function prototype
******************************************************************************/
void RCC_Configuration(void);
void RTC_Configuration(void);
void GPIO_Configuration(void);
void EXTI_Configuration(void);
void delay(void);
/***************************************************************************//**
*
******************************************************************************/
void RCC_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
}
/***************************************************************************//**
*
******************************************************************************/
void RTC_Configuration(void)
{
PWR_BackupAccessCmd(ENABLE);
/* RTC clock source configuration ----------------------------------------*/
/* Reset Backup Domain */
BKP_DeInit();
// Enable LSE OSC
RCC_LSICmd(ENABLE);
// Wait till LSE is ready
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
// Select the RTC Clock Source
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* RTC configuration -----------------------------------------------------*/
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
/* Set the RTC time base to 1s */
RTC_SetPrescaler(32767);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
RTC_SetCounter(0);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set the RTC Alarm after 3s */
RTC_SetAlarm(3);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_ALR,ENABLE);
}
/***************************************************************************//**
*
******************************************************************************/
void GPIO_Configuration(void)
{
// User button
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// LED's
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// Switch off LED's
GPIO_ResetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9);
// Disable tamper pin. PORTA.0
PWR_WakeUpPinCmd(DISABLE);
}
/***************************************************************************//**
*
******************************************************************************/
void EXTI_Configuration(void)
{
GPIO_EventOutputConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
GPIO_EventOutputCmd(ENABLE);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
/***************************************************************************//**
*
******************************************************************************/
void NVIC_Configuration(void)
{
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the WAKEUP_BUTTON_IRQn Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/***************************************************************************//**
*
******************************************************************************/
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_ALR) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_ALR);
RTC_WaitForLastTask();
RCC_Configuration();
GPIO_Configuration();
GPIO_SetBits(GPIOC, GPIO_Pin_8);
delay();
GPIO_ResetBits(GPIOC, GPIO_Pin_8);
RTC_SetCounter(0);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set the RTC Alarm after 3s */
RTC_SetAlarm(3);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
}
/***************************************************************************//**
*
******************************************************************************/
void delay(void)
{
volatile unsigned int a=1000;
while(a--)
{
volatile unsigned int b=1000;
while(b--);
}
}
/***************************************************************************//**
*
******************************************************************************/
void main(void)
{
RCC_Configuration();
GPIO_Configuration();
EXTI_Configuration();
RTC_Configuration();
NVIC_Configuration();
GPIO_SetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9);
delay();
GPIO_ResetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9);
while (1)
{
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);
if ( EXTI_GetFlagStatus(EXTI_Line0) == SET )
{
EXTI_ClearFlag(EXTI_Line0);
RCC_Configuration();
GPIO_Configuration();
GPIO_SetBits(GPIOC, GPIO_Pin_9);
delay();
GPIO_ResetBits(GPIOC, GPIO_Pin_9);
}
}
}