1972120_zh-CN

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

1972120_zh-CN

1972120_zh-CN

用LPTMR定时器中断无法从VLPS到VLPR的唤醒问题

我在仿真调试的时候,程序进入VLPS后,LPTMR定时器设定10秒中断,定时器中断可以从VLPS到VLPR的正常唤醒。但是不仿真的时候,关电重新上电,程序从RUN进入VLPR,然后程序进入VLPS后,之后无法进入LPTMR定时器中断,也无法唤醒到VLPR模式,一直处在VLPS状态。

但是外部IO口中断从VLPS到VLPR可以正常唤醒,不管是在仿真模式还是不仿真的情况都可以从VLPS正常唤醒到VLPR。

难道不仿真的时候VLPS导致LPTMR定时器时钟关了,还是有其他的问题?

VLPR用的慢速时钟源8M,分频后慢系统时钟为4M,FLASH时钟为1M,LPTMR定时器时钟源用的慢系统时钟4M分4096分频,10000计数大约10s中断一次。


主函数主函数主函数Run to VLPR函数Run to VLPR函数Run to VLPR函数VLPR  to VLPS函数VLPR to VLPS函数VLPR to VLPS函数

Re: 用LPTMR定时器中断无法从VLPS到VLPR的唤醒问题

问题已经解决,要提前设置使能VLPS模式下SIRC时钟,默认是关闭的,程序中增加一句宏定义就可以了

#define  SCG_ENABLE_SIRC_IN_VLPS  1

Re: 用LPTMR定时器中断无法从VLPS到VLPR的唤醒问题

这是我的源代码。不管是仿真还是断开下载器,在VLPR模式下LPTMR都正常工作。但是就是在VLPS模式下LPTMR无法唤醒到VLPR模式。用外部IO中断唤醒都正常。但是下载仿真时在VLPS模式LPTMR又可以唤醒到VLPR模式。我的初始化时钟就在Run_to_VLPR(void)函数中的scg_vlpr_configuration()函数中。

#include "include.h"


/* 中断优先级组 */
#define NVIC_Group0   0x07
#define NVIC_Group1   0x06
#define NVIC_Group2   0x05
#define NVIC_Group3   0x04
#define NVIC_Group4   0x03


typedef enum _mode {
	eRun 	= 1,
	eStop	= 2,
	eVLPR	= 4,
	eVLPS   = 16,
	eHSRun	= 128
}eLowPowerMode;

void delay(uint32_t cycles)
{
    /* Delay function - do nothing for a number of cycles */
    while(cycles--)
    {
        __asm("nop");
    }
}

void error_trap (void)
{
    while (1)
    {
			
    }
}

void disable_clock_monitors(void)
{
    /* Disable Clock monitor for System Oscillator */
    SCG->SOSCCSR &= ~(SCG_SOSCCSR_SOSCCM_MASK);
    /* Disable Clock monitor for System PLL */
    SCG->SPLLCSR &= ~(SCG_SPLLCSR_SPLLCM_MASK);
}

void scg_vlps_configuration (void)
{
    uint32_t tempSIRC = SCG->SIRCCSR;
    /* Disable in VLPS */
    tempSIRC &= ~(SCG_SIRCCSR_SIRCLPEN_MASK |
                SCG_SIRCCSR_SIRCSTEN_MASK);
#if SCG_ENABLE_SIRC_IN_VLPS
    /* Enable in VLPS */
    tempSIRC |= SCG_SIRCCSR_SIRCLPEN_MASK |
                SCG_SIRCCSR_SIRCSTEN_MASK;
#endif
    SCG->SIRCCSR = tempSIRC;
}


void scg_vlpr_configuration(void)
{
    uint8_t tempRCM = RCM->SRIE;
    uint32_t temp;
    /* Check if core is not using SIRC */
    if ((SCG->CSR & SCG_CSR_SCS_MASK) != SCG_CSR_SCS(2))
    {
        /* Disable SIRC */
        SCG->SIRCCSR &= ~SCG_SIRCCSR_SIRCEN_MASK;
        /* Wait until SIRC is disabled */
        while (SCG->SIRCCSR & SCG_SIRCCSR_SIRCVLD_MASK) {}
        /* Enable SIRC in VLP modes */
        SCG->SIRCCSR = SCG_SIRCCSR_SIRCSTEN_MASK
#if SCG_ENABLE_SIRC_IN_VLPS
                | SCG_SIRCCSR_SIRCLPEN_MASK
#endif
                ;
        /* Enable SIRC */
        SCG->SIRCCSR |= SCG_SIRCCSR_SIRCEN_MASK;
        /* Wait until SIRC is enabled */
        while (0 == (SCG->SIRCCSR & SCG_SIRCCSR_SIRCVLD_MASK)) {}

        temp = SCG_RCCR_DIVCORE(1) |   /* Core clock is SIRC/8 = 4MHz */
                SCG_RCCR_DIVBUS(0) |   /* Bus clock is Core clock / 1 = 4MHz */
                SCG_RCCR_DIVSLOW(3) |  /* Flash clock is Core clock / 1 = 1MHz */
                SCG_RCCR_SCS(2);       /* Select SIRC as system clock */

        SCG->RCCR = temp;               /* Select SIRC as system clock */

        /* Wait until SIRC is used as system clock */
        while ((SCG->CSR & SCG_CSR_SCS_MASK) != SCG_CSR_SCS(2)) {}
        /* Configure SIRC as system clock in VLPR modes */
        SCG->VCCR = SCG_VCCR_DIVCORE(1) |   /* Core clock is SIRC/8 = 1MHz */
                SCG_VCCR_DIVBUS(0) |   /* Bus clock is Core clock / 1 = 1MHz */
                SCG_VCCR_DIVSLOW(3) |  /* Flash clock is Core clock / 1 = 1MHz */
                SCG_VCCR_SCS(2);       /* Select SIRC as system clock */

        /* Disable FIRC and SPLL */
        /* ?Configurable SIRC as system clock */
        /* ?Configure all reset sources to be 'Reset' (not as Interrupt) via RCM_SRIE */
        /* ?Program each reset source as interrupt via RCM_SRIE for a minimum delay time of 10 LPO */
        RCM->SRIE &= 0;
        /* ?Disable FIRC */
        SCG->FIRCCSR = SCG_FIRCCSR_FIRCREGOFF_MASK;
        /* ?Execute few nops to ensure an interval of 45 ns */
        delay(10);
        while (0 != (SCG->FIRCCSR & SCG_FIRCCSR_FIRCVLD_MASK)) { };
        /* ?Configure every reset source back to original intended reset configuration (Interrupt or Reset) via RCM_SRIE */
        RCM->SRIE = tempRCM;

        /* Set SIRCDIV2 value to 1MHz (SIRC /  */
        SCG->SIRCDIV = SCG_SIRCDIV_SIRCDIV2(2);
    }
}

void scg_configure_freq_for_VLPR()
{
	
}


void Run_to_VLPR(void)
{
    /* Disable clock monitors on SCG module */
    disable_clock_monitors();
    /* Adjust SCG settings to meet maximum frequencies values */
    scg_vlpr_configuration();
    /* Allow very low power run mode */
    SMC->PMPROT |= SMC_PMPROT_AVLP_MASK;
    /* Check if current mode is RUN mode */
    if (eRun == SMC->PMSTAT)
    {
        /* This bit enables source and well biasing for the core logic,
         * this is useful to further reduce MCU power consumption */
        PMC->REGSC |= PMC_REGSC_BIASEN_MASK;
        /* Move to VLPR mode */
        SMC->PMCTRL = SMC_PMCTRL_RUNM(2);
        /* Wait for transition */
        while (SMC->PMSTAT != eVLPR) {}
    }
    else
    {
        /* Error trap */
        error_trap();
    }
}
#define SCG_ENABLE_SIRC_IN_VLPS 1

void VLPR_to_VLPS (void)
{
    uint32_t tempPMC_ctrl = SMC->PMCTRL;
    /* Disable FIRC and SPLL and configure VLPS */
    scg_vlps_configuration();
    /* Enable SLEEPDEEP bit in the Core
     * (Allow deep sleep modes) */
    S32_SCB->SCR |= S32_SCB_SCR_SLEEPDEEP_MASK;
    /* Allow very low power run mode */
    SMC->PMPROT |= SMC_PMPROT_AVLP_MASK;
    /* Select VLPS Mode */
    tempPMC_ctrl &= ~SMC_PMCTRL_STOPM_MASK;
    tempPMC_ctrl |= SMC_PMCTRL_STOPM(2);
    SMC->PMCTRL = tempPMC_ctrl;
    /* Reduce power consumption */
    PMC->REGSC |= PMC_REGSC_BIASEN_MASK
#if (0 == SCG_ENABLE_SIRC_IN_VLPS)
            | PMC_REGSC_CLKBIASDIS_MASK
#endif
            ;
    /* Check if current mode is VLPR mode */
    if(eVLPR == SMC->PMSTAT)
    {
				STANDBY();  // Move to Stop mode
//        __asm("DSB");
//        __asm("ISB");
        /* Go to deep sleep mode */
//        __asm("WFI");
    }
    else
    {
        /* Error trap */
        error_trap();
    }
    /* Verify VLPSA bit is not set */
    if (0 != (SMC->PMCTRL & SMC_PMCTRL_VLPSA_MASK))
    {
//        error_trap();
    }
}

#define KEY0_IO         PTD5
void Key_Init(void)
{
    
    /* 配置按键 内部上拉 下降沿触发中断 */
    GPIO_ExtiInit(KEY0_IO, falling_up);

    /*优先级配置 抢占优先级1  子优先级2   越小优先级越高  抢占优先级可打断别的中断  */    
    NVIC_SetPriority(PORTD_IRQn,NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1,2)); 
    NVIC_EnableIRQ(PORTD_IRQn);			         //使能PORTD_IRQn的中断  	
    
}

 #define LED1_IO  PTC17     //核心板LED
 #define LED2_IO  PTC16
 #define LED3_IO  PTD15     //母板LED
 #define LED4_IO  PTD16 

void LED_Init(void)
{
    GPIO_PinInit(LED1_IO,GPO,0);
    GPIO_PinInit(LED2_IO,GPO,0);
    GPIO_PinInit(LED3_IO,GPO,0);
    GPIO_PinInit(LED4_IO,GPO,0);
}

int main(void)
{
	uint16 w1;
	uint16 wCnt=0;

		Run_to_VLPR();

    NVIC_SetPriorityGrouping(NVIC_Group2);

		LPTMR_Init(5000);

    /* 优先级配置 抢占优先级1  子优先级2   越小优先级越高  抢占优先级可打断别的中断 */
    NVIC_SetPriority(LPTMR0_IRQn,NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1,2));  
    NVIC_EnableIRQ(LPTMR0_IRQn);			         //使能LPTMR0_IRQn的中断 

		Key_Init();
		LED_Init();		
		while(1)
    {
		
				wCnt++;
				if(wCnt>=100){
					wCnt=0;
					VLPR_to_VLPS();					
				}
				delay(0x00007fff);
				LED_Reverse(1);
		}
//    return 0;
}






Re: 用LPTMR定时器中断无法从VLPS到VLPR的唤醒问题

Hi@yankui666

MCU在进入低功耗的时候要断开调试器,否则MCU可能并不会成功进入低功耗模式

1.我没看到你初始化时钟的示例代码

2.请先初始化完成时钟,外设后再去执行RUN_TO_VLPR

3.先调通RUN模式下LPTMR再去排查

タグ(1)
評価なし
バージョン履歴
最終更新日:
‎11-21-2025 10:28 AM
更新者: