在线时间37 小时
UID2024419
注册时间2015-3-2
NXP金币0
该用户从未签到
中级会员
 
- 积分
- 484
- 最后登录
- 2016-3-28
|
本代码基于KSDK 1.3,可实现KL17MCU进入低功耗模式(VLPS),可通过GPIO引脚触发唤醒或定时器自动唤醒。
GPIO PTC1 采用LLWU方式唤醒KL17。
- #include "fsl_clock_manager.h"
- #include "fsl_port_hal.h"
- #include "fsl_pmc_hal.h"
- #include "fsl_smc_hal.h"
- #include "fsl_rtc_hal.h"
- #include "fsl_sim_hal.h"
- #include "fsl_interrupt_manager.h"
- #include "fsl_lptmr_driver.h"
- #include "fsl_gpio_driver.h"
- #include "fsl_power_manager.h"
- #include "fsl_llwu_hal.h"
- #include "fsl_debug_console.h"
- /* Function to initialize OSC0 base on board configuration. */
- void InitOsc0(void)
- {
- // OSC0 configuration.
- osc_user_config_t osc0Config =
- {
- .freq = 32768U,
- .hgo = kOscGainLow,
- .range = kOscRangeLow,
- .erefs = kOscSrcOsc,
- .enableCapacitor2p = false,
- .enableCapacitor4p = false,
- .enableCapacitor8p = false,
- .enableCapacitor16p = false,
- };
- CLOCK_SYS_OscInit(0U, &osc0Config);
- }
- /* Function to initialize RTC external clock base on board configuration. */
- void InitRtcOsc(void)
- {
- rtc_osc_user_config_t rtcOscConfig =
- {
- .freq = 0,
- .enableCapacitor2p = false,
- .enableCapacitor4p = false,
- .enableCapacitor8p = false,
- .enableCapacitor16p = false,
- .enableOsc = false,
- .enableClockOutput = false,
- };
- CLOCK_SYS_RtcOscInit(0U, &rtcOscConfig);
- }
- /* Configuration for enter RUN mode. Core clock = 48MHz. */
- const clock_manager_user_config_t g_defaultClockConfigRun =
- {
- .mcgliteConfig =
- {
- .mcglite_mode = kMcgliteModeHirc48M, // Work in HIRC mode.
- .irclkEnable = false, // MCGIRCLK disable.
- .irclkEnableInStop = false, // MCGIRCLK disable in STOP mode.
- .ircs = kMcgliteLircSel2M, // Select LIRC_2M.
- .fcrdiv = kMcgliteLircDivBy1, // FCRDIV is 0.
- .lircDiv2 = kMcgliteLircDivBy1, // LIRC_DIV2 is 0.
- .hircEnableInNotHircMode = true, // HIRC disable.
- },
- .simConfig =
- {
- .er32kSrc = kClockEr32kSrcOsc0, // ERCLK32K selection, use OSC.
- .outdiv1 = 0U,
- .outdiv4 = 1U,
- },
- .oscerConfig =
- {
- .enable = false, // OSCERCLK disable.
- .enableInStop = false, // OSCERCLK disable in STOP mode.
- }
- };
- /* Initialize clock. */
- void ClockInit(void)
- {
- /* enable clock for PORTs */
- CLOCK_SYS_EnablePortClock(PORTA_IDX);
- /* Power mode protection initialization */
- SMC_HAL_SetProtection(SMC, kAllowPowerModeAll);
- /* Setup board clock source. */
- // Setup OSC0 if used.
- // Configure OSC0 pin mux.
- PORT_HAL_SetMuxMode(PORTA, 18, kPortPinDisabled);
- PORT_HAL_SetMuxMode(PORTA, 19, kPortPinDisabled);
- InitOsc0();
- // Setup RTC external clock if used.
- #if RTC_XTAL_FREQ
- /* enable clock for PORTs */
- CLOCK_SYS_EnablePortClock(PORTC_IDX);
- // If RTC_CLKIN is connected, need to set pin mux. Another way for
- // RTC clock is set RTC_OSC_ENABLE_CONFIG to use OSC0, please check
- // reference manual for datails.
- PORT_HAL_SetMuxMode(PORTC, 1, kPortMuxAsGpio);
- #endif
- InitRtcOsc();
- /* Set system clock configuration. */
- CLOCK_SYS_SetConfiguration(&g_defaultClockConfigRun);
- }
- void DebugConsole_Init(void)
- {
- CLOCK_SYS_EnablePortClock(PORTA_IDX);
- PORT_HAL_SetMuxMode(PORTA,1u, kPortMuxAlt2);
- PORT_HAL_SetMuxMode(PORTA,2u, kPortMuxAlt2);
- CLOCK_SYS_SetLpuartSrc(0, kClockLpuartSrcIrc48M);
- DbgConsole_Init(0, 9600, kDebugConsoleLPUART);
- }
- /*!
- * @brief LPTMR interrupt callback
- */
- volatile uint32_t lptmrCounter=0;
- void lptmr_isr_callback(void)
- {
- lptmrCounter++;
- PRINTF("\n\rLPTMR0_IRQHandler No.%d\n\r\n\r", lptmrCounter);
- }
- lptmr_state_t lptmrState;
- lptmr_user_config_t lptmrUserConfig;
- void LPTMR_Init(void)
- {
- lptmrUserConfig.timerMode = kLptmrTimerModeTimeCounter; /*! Use LPTMR in Time Counter mode */
- lptmrUserConfig.freeRunningEnable = false; /*! When hit compare value, set counter back to zero */
- lptmrUserConfig.prescalerEnable = false; /*! bypass prescaler */
- lptmrUserConfig.prescalerClockSource = kClockLptmrSrcLpoClk; /*! use 1kHz Low Power Clock */
- lptmrUserConfig.isInterruptEnabled = true;
- // Initialize LPTMR
- LPTMR_DRV_Init(0U, &lptmrState, &lptmrUserConfig);
- // Set the timer period for 5 second
- <b> LPTMR_DRV_SetTimerPeriodUs(0U, 5000000);</b>
- // Specify the callback function when a LPTMR interrupt occurs
- LPTMR_DRV_InstallCallback(0U, lptmr_isr_callback);
- // Start counting
- LPTMR_DRV_Start(0U);
- }
- void lptmrEnableWakeUp(void)
- {
- LLWU_HAL_SetInternalModuleCmd(LLWU_BASE_PTR, kLlwuWakeupModule0, true);
- }
- void GPIO_Init(void)
- {
- //配置输入GPIO口
- gpio_input_pin_user_config_t inputPin = {
- .pinName = GPIO_MAKE_PIN(GPIOC_IDX, 1), //PTC1
- .config.isPullEnable = true,
- .config.pullSelect = kPortPullUp,
- .config.interrupt = kPortIntFallingEdge,
- };
- GPIO_DRV_InputPinInit(&inputPin);
- }
- void gpioEnableWakeUp(void)
- {
- LLWU_HAL_ClearExternalPinWakeupFlag(LLWU_BASE_PTR, kLlwuWakeupPin6);
- //falling edge detection
- LLWU_HAL_SetExternalInputPinMode(LLWU_BASE_PTR, kLlwuExternalPinFallingEdge, kLlwuWakeupPin6);
- }
- ///////////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////////
- void LPTMR0_IRQHandler(void)
- {
- LPTMR_DRV_IRQHandler(0U);
- }
- void PORTBCDE_IRQHandler(void)
- {
- PORT_HAL_ClearPortIntFlag(PORTC);
- PRINTF("\n\rPORTBCDE_IRQHandler\n\r\n\r");
- }
- /*
- void LLWU_IRQHandler(void)
- {
- if(LLWU_HAL_GetExternalPinWakeupFlag(LLWU_BASE_PTR, kLlwuWakeupPin6))
- {
- LLWU_HAL_ClearExternalPinWakeupFlag(LLWU_BASE_PTR, kLlwuWakeupPin6);
- PRINTF("\n\rLLWU_IRQHandler PTC1\n\r\n\r");
- }
- if(LLWU_HAL_GetInternalModuleWakeupFlag(LLWU_BASE_PTR, kLlwuWakeupModule0))
- {
- PRINTF("\n\rLLWU_IRQHandler LPTMR\n\r\n\r");
- }
- }
- */
- ///////////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////////
- #define VLPS_mode
- int main(void)
- {
- /* Write your code here */
- if(PMC_HAL_GetAckIsolation(PMC_BASE_PTR) != 0)
- {
- PMC_HAL_ClearAckIsolation(PMC_BASE_PTR);
- }
- ClockInit();
- DebugConsole_Init();
- LPTMR_Init();
- GPIO_Init();
- /*
- // Enables LLWU interrupt
- INT_SYS_EnableIRQ(LLWU_IRQn);
- <font color="#ff0000"><b> lptmrEnableWakeUp(); //LPTMR 模块实现5秒定时,超时将产生中断并唤醒MCU。</b></font>
- <b><font color="#ff0000"> gpioEnableWakeUp();</font></b>
- */
- /* First, setup an smc_power_mode_config_t variable to be passed to the SMC
- * HAL function
- */
- #ifdef VLPS_mode
- smc_power_mode_config_t smc_power_config =
- {
- .powerModeName = <b>kPowerModeVlps</b>, // Set the desired power mode
- };
- #endif
- /* This for loop should be replaced. By default this loop allows a single stepping. */
- while (1) {
- #ifdef VLPS_mode
- PRINTF("\n\rEnter Into Low Power\n\r\n\r");
- /* Now call the SMC HAL SetMode function to move to the desired power mode. */
- if (SMC_HAL_SetMode(SMC, &smc_power_config) != kSmcHalSuccess) PRINTF("\n\rFail\n\r\n\r");
- #endif
- }
- /* Never leave main */
- return 0;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // EOF
- ////////////////////////////////////////////////////////////////////////////////
复制代码
代码分析:
1,LPTMR唤醒MCU的原理
- KL系列的MCU中的LPTMR模块在任何功耗模式下都可以工作,使用前应先配置时钟和模式
lptmrUserConfig.timerMode = kLptmrTimerModeTimeCounter; /*! Use LPTMR in Time Counter mode */
lptmrUserConfig.freeRunningEnable = false; /*! When hit compare value, set counter back to zero */
lptmrUserConfig.prescalerEnable = false; /*! bypass prescaler */
lptmrUserConfig.prescalerClockSource = kClockLptmrSrcLpoClk; /*! use 1kHz Low Power Clock */
lptmrUserConfig.isInterruptEnabled = true;
// Set the timer period for 5 second
LPTMR_DRV_SetTimerPeriodUs(0U, 5000000);
// Specify the callback function when a LPTMR interrupt occurs
LPTMR_DRV_InstallCallback(0U, lptmr_isr_callback);
void lptmrEnableWakeUp(void)
{
LLWU_HAL_SetInternalModuleCmd(LLWU_BASE_PTR, kLlwuWakeupModule0, true);
}
LPTMR_DRV_Start(0U);
2,GPIO触发唤醒
- 配置GPIO PTC1作为输入口,且脉冲触发方式(上升沿或下降沿)
void GPIO_Init(void)
{
//配置输入GPIO口
gpio_input_pin_user_config_t inputPin = {
.pinName = GPIO_MAKE_PIN(GPIOC_IDX, 1), //PTC1
.config.isPullEnable = true,
.config.pullSelect = kPortPullUp,
.config.interrupt = kPortIntFallingEdge,
};
GPIO_DRV_InputPinInit(&inputPin);
}
void gpioEnableWakeUp(void)
{
LLWU_HAL_ClearExternalPinWakeupFlag(LLWU_BASE_PTR, kLlwuWakeupPin6);
//falling edge detection
LLWU_HAL_SetExternalInputPinMode(LLWU_BASE_PTR, kLlwuExternalPinFallingEdge, kLlwuWakeupPin6);
}
|
|