我在仿真调试的时候,程序进入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函数
VLPR to VLPS函数VLPR to VLPS函数
问题已经解决,要提前设置使能VLPS模式下SIRC时钟,默认是关闭的,程序中增加一句宏定义就可以了
#define SCG_ENABLE_SIRC_IN_VLPS 1
这是我的源代码。不管是仿真还是断开下载器,在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;
}
Hi@yankui666
MCU在进入低功耗的时候要断开调试器,否则MCU可能并不会成功进入低功耗模式
1.我没看到你初始化时钟的示例代码
2.请先初始化完成时钟,外设后再去执行RUN_TO_VLPR
3.先调通RUN模式下LPTMR再去排查