2023-06-26 05:54 AM
Can someone please help me to sort it out?Please
I am stuck at a project.In the attached code I am unable to wake up the code after sleep.Rest of the functions working once in sleep it shoild wakeup at if(MV>20)
#include "stm8s.h"
#include "stm8s_clk.h"
#include "stm8s_adc1.h"
#include "stm8s_gpio.h"
#include "stm8s_tim2.h"
#include "main.h"
#include "flash.h"
//#include "stm8s_awu.h"
#include "stm8s_exti.h"
volatile unsigned short _500ms_tick;
volatile unsigned short idle_counter;
volatile uint16_t MV;
void Clk_Config(void);
void ADC_Config(void);
void GPIO_Config(void);
void EXTI_Setup(void);
void ADC_Read1(uint16_t *MV);
void ADC_Read2(uint16_t *Vbat);
void ADC_Read3(uint16_t *Ocd);
void ADC_Read4(uint16_t *Temp);
void EXTI_PortD_Callback(void);
main()
{
uint16_t MV=0,Vbat=0,Ocd=0,Temp=0;
unsigned short i;
int counting = 0;
Clk_Config();
ADC_Config();
GPIO_Config();
EXTI_Setup();
while(MV<100)
{
ADC_Read1(&MV);
delay_ms(100);
Set_LED(0);
idle_counter++;
if (idle_counter>=300)
{
EnterSleepMode();
}
}
while (1)
{
ADC_Read1(&MV);
delay_ms(100);
ADC_Read2(&Vbat);
delay_ms(100);
ADC_Read3(&Ocd);
delay_ms(100);
ADC_Read4(&Temp);
delay_ms(100);
if (MV > 20) // Mains Detect
{
if ((MV < 370) && (Vbat > 227)) // Mains Fail
{
En_Emergency(1);
Set_LED(0);
}
else
{
En_Emergency(0);
Set_LED(0);
}
}
if(MV<=10)
{
ADC_Read3(&Ocd);
delay_ms(100);
Set_LED(0);
if(Ocd<93 || Ocd>186)
{
Set_LED(1);
delay_ms(1000);
Set_LED(0);
delay_ms(1000);
Set_LED(1);
delay_ms(1000);
Set_LED(0);
delay_ms(1000);
Set_LED(1);
delay_ms(1000);
Set_LED(0);
delay_ms(5000);
}
else if(Ocd>93 || Ocd<186)
{
Set_LED(0);
}
}
ADC_Read2(&Vbat);
if (MV < 250)
{
Set_LED(0);
}
if(Vbat>460 || Vbat < 155)
{
Set_Bch(1);
Set_LED(0);
}
else if( Vbat>395)
{
Set_LED(1);
Set_Bch(0);
}
else if(Vbat<383)
{
Set_LED(1);
Set_Bch(1);
}
ADC_Read4(&Temp);
if(Temp>87 && Temp<425)
{
Set_Bch(1);
}
else if(Temp<87 || Temp>425)
{
Set_Bch(0);
Set_LED(1);
delay_ms(1000);
Set_LED(0);
delay_ms(1000);
Set_LED(1);
delay_ms(1000);
Set_LED(0);
delay_ms(5000);
}
}
}
void Clk_Config() // INTERNAL CLOCK CONFIGUARATION
{
CLK_DeInit();
CLK_HSECmd(DISABLE);
CLK_LSICmd(DISABLE);
CLK_HSICmd(ENABLE);
while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);
CLK_ClockSwitchCmd(ENABLE);
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2);
CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI,
DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, ENABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);
}
void ADC_Config() // ADC INITIALIZATION
{
ADC1_DeInit();
ADC1_Cmd(ENABLE);
ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE);
}
void ADC_Read1(uint16_t *MV)
{
ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, // MAINS INPUT
ADC1_CHANNEL_5,
ADC1_PRESSEL_FCPU_D2,
ADC1_EXTTRIG_GPIO,
DISABLE,
ADC1_ALIGN_RIGHT,
ADC1_SCHMITTTRIG_CHANNEL5,
DISABLE);
ADC1_StartConversion();
while (!ADC1_GetFlagStatus(ADC1_FLAG_EOC))
{
// Wait for conversion to complete
}
*MV= ADC1_GetConversionValue();
}
void ADC_Read2(uint16_t *Vbat)
{
ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, //ADC Channel_4 VBATT
ADC1_CHANNEL_4,
ADC1_PRESSEL_FCPU_D2,
ADC1_EXTTRIG_GPIO,
DISABLE,
ADC1_ALIGN_RIGHT,
ADC1_SCHMITTTRIG_CHANNEL4,
DISABLE);
ADC1_StartConversion();
while (!ADC1_GetFlagStatus(ADC1_FLAG_EOC))
{
// Wait for conversion to complete
}
*Vbat=ADC1_GetConversionValue();
}
void ADC_Read3(uint16_t *Ocd) // ADC Channel_2 OPEN CIRCUIT DETECTION
{
ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS,
ADC1_CHANNEL_2,
ADC1_PRESSEL_FCPU_D2,
ADC1_EXTTRIG_GPIO,
DISABLE,
ADC1_ALIGN_RIGHT,
ADC1_SCHMITTTRIG_CHANNEL2,
DISABLE);
ADC1_StartConversion();
while (!ADC1_GetFlagStatus(ADC1_FLAG_EOC))
{
// Wait for conversion to complete
}
*Ocd=ADC1_GetConversionValue();
}
void ADC_Read4(uint16_t *Temp) // ADC Channel_2 TEMPARATURE MONITORING
{
ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS,
ADC1_CHANNEL_3,
ADC1_PRESSEL_FCPU_D2,
ADC1_EXTTRIG_GPIO,
DISABLE,
ADC1_ALIGN_RIGHT,
ADC1_SCHMITTTRIG_CHANNEL3,
DISABLE);
ADC1_StartConversion();
while (!ADC1_GetFlagStatus(ADC1_FLAG_EOC))
{
// Wait for conversion to complete
}
*Temp=ADC1_GetConversionValue();
}
void GPIO_Config(void)
{
//GPIO INPUTS
//GPIO_Init(GPIOD,GPIO_PIN_2,GPIO_MODE_IN_FL_NO_IT); // TEMP SENSE
GPIO_Init(GPIOD,GPIO_PIN_3,GPIO_MODE_IN_FL_NO_IT); //VBATT
GPIO_Init(GPIOD,GPIO_PIN_5,GPIO_MODE_IN_FL_NO_IT); //MAINS INPUT
GPIO_Init(GPIOC,GPIO_PIN_4,GPIO_MODE_IN_FL_NO_IT); // OCD SENSE
//GPIO OUTPUTS
GPIO_Init(GPIOA,GPIO_PIN_3,GPIO_MODE_OUT_PP_LOW_FAST); // MAIN LAMP
GPIO_Init(GPIOC,GPIO_PIN_3,GPIO_MODE_OUT_PP_HIGH_FAST); //LED O/P
GPIO_Init(GPIOC,GPIO_PIN_5,GPIO_MODE_OUT_PP_LOW_FAST); //BCH
}
void TIM2_Config(void)
{
TIM2_TimeBaseInit(TIM2_PRESCALER_32768, 244);
TIM2_ClearFlag(TIM2_FLAG_UPDATE);
TIM2_ITConfig(TIM2_IT_UPDATE, ENABLE);
TIM2_Cmd(ENABLE);
}
INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)
{
if (TIM2_GetITStatus(TIM2_IT_UPDATE) != RESET)
{
// Increment the idle_counter every 500ms
idle_counter++;
// Enter sleep mode if idle for approximately 30 seconds (60 * 500ms)
if (idle_counter >= 300)
{
EnterSleepMode();
}
TIM2_ClearITPendingBit(TIM2_IT_UPDATE);
}
}
void EnterSleepMode(void)
{
// Disable TIM2 interrupt
TIM2_ITConfig(TIM2_IT_UPDATE, DISABLE);
// Disable ADC peripheral
ADC1_Cmd(DISABLE);
// Disable GPIO inputs
GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_IN_PU_NO_IT);
GPIO_Init(GPIOD, GPIO_PIN_5, GPIO_MODE_IN_FL_IT);
GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_IN_PU_NO_IT);
halt();
// Re-enable ADC peripheral
}
void Inc500mSCounter(void)
{
if (_500ms_tick < 500)
{
_500ms_tick++;
}
else
{
_500ms_tick = 0;
idle_counter++;
}
}
void IWDG_Config(void)
{
uint8_t WTG_TIME;
IWDG_Enable();
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(IWDG_Prescaler_128);
IWDG_SetReload( 127);
IWDG_ReloadCounter();
}
void EXTI_Setup(void)
{
EXTI_DeInit();
EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOD, EXTI_SENSITIVITY_RISE_ONLY);
EXTI_SetTLISensitivity(EXTI_TLISENSITIVITY_RISE_ONLY);
}
void WakeupFromSleep(void)
{
ADC1_Cmd(ENABLE);
// Re-enable GPIO inputs
GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_IN_FL_NO_IT);
GPIO_Init(GPIOD, GPIO_PIN_5, GPIO_MODE_IN_FL_NO_IT);
GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_IN_FL_NO_IT);
// Reset idle counter
idle_counter = 0;
// Re-enable TIM2 interrupt
TIM2_ITConfig(TIM2_IT_UPDATE, ENABLE);
}
INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6)
{
//EXTI_ClearITPendingBit(EXTI_PORT_GPIOD);
{ // Wake up from sleep mode
WakeupFromSleep();
}
}
2023-06-26 08:12 AM
As I said before, you should not enter sleep mode in an interrupt handler. In this case in TIM2 interrupt handler. I know that you also call EnterSleepMode() from main, but I don't know which one is executed first.
And you should not start with a complex program and expect it will work. I believe that you use PD5 pin as the wakeup event. Did you test before and without sleep mode, if this pin generates an interrupt?
2023-06-26 09:02 AM
hi thanks for the reply.I will give a try as what you said .