查看: 4624|回复: 7

[原创] KL17低功耗测试 + GPIO + LPTMR

[复制链接]

该用户从未签到

27

主题

320

帖子

0

中级会员

Rank: 3Rank: 3

积分
484
最后登录
2016-3-28
发表于 2015-11-3 10:56:45 | 显示全部楼层 |阅读模式
本代码基于KSDK 1.3,可实现KL17MCU进入低功耗模式(VLPS),可通过GPIO引脚触发唤醒或定时器自动唤醒。
GPIO  PTC1 采用LLWU方式唤醒KL17。

  1. #include "fsl_clock_manager.h"
  2. #include "fsl_port_hal.h"
  3. #include "fsl_pmc_hal.h"
  4. #include "fsl_smc_hal.h"
  5. #include "fsl_rtc_hal.h"
  6. #include "fsl_sim_hal.h"
  7. #include "fsl_interrupt_manager.h"
  8. #include "fsl_lptmr_driver.h"

  9. #include "fsl_gpio_driver.h"
  10. #include "fsl_power_manager.h"
  11. #include "fsl_llwu_hal.h"

  12. #include "fsl_debug_console.h"

  13. /* Function to initialize OSC0 base on board configuration. */
  14. void InitOsc0(void)
  15. {
  16.     // OSC0 configuration.
  17.     osc_user_config_t osc0Config =
  18.     {
  19.         .freq                = 32768U,
  20.         .hgo                 = kOscGainLow,
  21.         .range               = kOscRangeLow,
  22.         .erefs               = kOscSrcOsc,
  23.         .enableCapacitor2p   = false,
  24.         .enableCapacitor4p   = false,
  25.         .enableCapacitor8p   = false,
  26.         .enableCapacitor16p  = false,
  27.     };

  28.     CLOCK_SYS_OscInit(0U, &osc0Config);
  29. }
  30. /* Function to initialize RTC external clock base on board configuration. */
  31. void InitRtcOsc(void)
  32. {

  33.     rtc_osc_user_config_t rtcOscConfig =
  34.     {
  35.         .freq                = 0,
  36.         .enableCapacitor2p   = false,
  37.         .enableCapacitor4p   = false,
  38.         .enableCapacitor8p   = false,
  39.         .enableCapacitor16p  = false,
  40.         .enableOsc           = false,
  41.         .enableClockOutput   = false,
  42.     };

  43.     CLOCK_SYS_RtcOscInit(0U, &rtcOscConfig);
  44. }
  45. /* Configuration for enter RUN mode. Core clock = 48MHz. */
  46. const clock_manager_user_config_t g_defaultClockConfigRun =
  47. {
  48.     .mcgliteConfig =
  49.     {
  50.         .mcglite_mode        = kMcgliteModeHirc48M,   // Work in HIRC mode.
  51.         .irclkEnable        = false, // MCGIRCLK disable.
  52.         .irclkEnableInStop  = false, // MCGIRCLK disable in STOP mode.
  53.         .ircs               = kMcgliteLircSel2M, // Select LIRC_2M.
  54.         .fcrdiv             = kMcgliteLircDivBy1,    // FCRDIV is 0.
  55.         .lircDiv2           = kMcgliteLircDivBy1,    // LIRC_DIV2 is 0.
  56.         .hircEnableInNotHircMode         = true,  // HIRC disable.
  57.     },
  58.     .simConfig =
  59.     {
  60.         .er32kSrc  = kClockEr32kSrcOsc0,  // ERCLK32K selection, use OSC.
  61.         .outdiv1   = 0U,
  62.         .outdiv4   = 1U,
  63.     },
  64.     .oscerConfig =
  65.     {
  66.         .enable       = false, // OSCERCLK disable.
  67.         .enableInStop = false, // OSCERCLK disable in STOP mode.
  68.     }
  69. };

  70. /* Initialize clock. */
  71. void ClockInit(void)
  72. {
  73.     /* enable clock for PORTs */
  74.     CLOCK_SYS_EnablePortClock(PORTA_IDX);

  75.     /* Power mode protection initialization */
  76.         SMC_HAL_SetProtection(SMC, kAllowPowerModeAll);

  77.     /* Setup board clock source. */
  78.     // Setup OSC0 if used.
  79.     // Configure OSC0 pin mux.
  80.     PORT_HAL_SetMuxMode(PORTA, 18, kPortPinDisabled);
  81.     PORT_HAL_SetMuxMode(PORTA, 19, kPortPinDisabled);
  82.     InitOsc0();

  83.     // Setup RTC external clock if used.
  84. #if RTC_XTAL_FREQ
  85.     /* enable clock for PORTs */
  86.     CLOCK_SYS_EnablePortClock(PORTC_IDX);
  87.     // If RTC_CLKIN is connected, need to set pin mux. Another way for
  88.     // RTC clock is set RTC_OSC_ENABLE_CONFIG to use OSC0, please check
  89.     // reference manual for datails.
  90.     PORT_HAL_SetMuxMode(PORTC, 1, kPortMuxAsGpio);
  91. #endif
  92.     InitRtcOsc();

  93.     /* Set system clock configuration. */
  94.     CLOCK_SYS_SetConfiguration(&g_defaultClockConfigRun);

  95. }
  96. void DebugConsole_Init(void)
  97. {
  98.         CLOCK_SYS_EnablePortClock(PORTA_IDX);
  99.         PORT_HAL_SetMuxMode(PORTA,1u, kPortMuxAlt2);
  100.         PORT_HAL_SetMuxMode(PORTA,2u, kPortMuxAlt2);
  101.         CLOCK_SYS_SetLpuartSrc(0, kClockLpuartSrcIrc48M);
  102.         DbgConsole_Init(0, 9600, kDebugConsoleLPUART);
  103. }
  104. /*!
  105. * @brief LPTMR interrupt callback
  106. */
  107. volatile uint32_t lptmrCounter=0;
  108. void lptmr_isr_callback(void)
  109. {
  110.         lptmrCounter++;
  111.         PRINTF("\n\rLPTMR0_IRQHandler No.%d\n\r\n\r", lptmrCounter);
  112. }

  113. lptmr_state_t lptmrState;
  114. lptmr_user_config_t lptmrUserConfig;
  115. void LPTMR_Init(void)
  116. {
  117.         lptmrUserConfig.timerMode            = kLptmrTimerModeTimeCounter; /*! Use LPTMR in Time Counter mode */
  118.         lptmrUserConfig.freeRunningEnable    = false; /*! When hit compare value, set counter back to zero */
  119.         lptmrUserConfig.prescalerEnable      = false; /*! bypass prescaler */
  120.         lptmrUserConfig.prescalerClockSource = kClockLptmrSrcLpoClk; /*! use 1kHz Low Power Clock */
  121.         lptmrUserConfig.isInterruptEnabled   = true;

  122.         // Initialize LPTMR
  123.         LPTMR_DRV_Init(0U, &lptmrState, &lptmrUserConfig);

  124.         // Set the timer period for 5 second
  125. <b>        LPTMR_DRV_SetTimerPeriodUs(0U, 5000000);</b>

  126.         // Specify the callback function when a LPTMR interrupt occurs
  127.         LPTMR_DRV_InstallCallback(0U, lptmr_isr_callback);

  128.         // Start counting
  129.         LPTMR_DRV_Start(0U);
  130. }
  131. void lptmrEnableWakeUp(void)
  132. {
  133.         LLWU_HAL_SetInternalModuleCmd(LLWU_BASE_PTR, kLlwuWakeupModule0, true);
  134. }

  135. void GPIO_Init(void)
  136. {
  137.         //配置输入GPIO口
  138.         gpio_input_pin_user_config_t inputPin = {
  139.                         .pinName = GPIO_MAKE_PIN(GPIOC_IDX, 1), //PTC1
  140.                         .config.isPullEnable = true,
  141.                         .config.pullSelect = kPortPullUp,
  142.                         .config.interrupt = kPortIntFallingEdge,
  143.                 };
  144.         GPIO_DRV_InputPinInit(&inputPin);
  145. }
  146. void gpioEnableWakeUp(void)
  147. {
  148.         LLWU_HAL_ClearExternalPinWakeupFlag(LLWU_BASE_PTR, kLlwuWakeupPin6);
  149.         //falling edge detection
  150.         LLWU_HAL_SetExternalInputPinMode(LLWU_BASE_PTR, kLlwuExternalPinFallingEdge, kLlwuWakeupPin6);
  151. }
  152. ///////////////////////////////////////////////////////////////////////////////////
  153. ///////////////////////////////////////////////////////////////////////////////////
  154. void LPTMR0_IRQHandler(void)
  155. {
  156.     LPTMR_DRV_IRQHandler(0U);
  157. }
  158. void PORTBCDE_IRQHandler(void)
  159. {
  160.     PORT_HAL_ClearPortIntFlag(PORTC);
  161.     PRINTF("\n\rPORTBCDE_IRQHandler\n\r\n\r");
  162. }
  163. /*
  164. void LLWU_IRQHandler(void)
  165. {
  166.         if(LLWU_HAL_GetExternalPinWakeupFlag(LLWU_BASE_PTR, kLlwuWakeupPin6))
  167.         {
  168.                 LLWU_HAL_ClearExternalPinWakeupFlag(LLWU_BASE_PTR, kLlwuWakeupPin6);
  169.                 PRINTF("\n\rLLWU_IRQHandler PTC1\n\r\n\r");
  170.         }
  171.     if(LLWU_HAL_GetInternalModuleWakeupFlag(LLWU_BASE_PTR, kLlwuWakeupModule0))
  172.     {
  173.             PRINTF("\n\rLLWU_IRQHandler LPTMR\n\r\n\r");
  174.     }
  175. }
  176. */
  177. ///////////////////////////////////////////////////////////////////////////////////
  178. ///////////////////////////////////////////////////////////////////////////////////
  179. #define VLPS_mode

  180. int main(void)
  181. {

  182.     /* Write your code here */

  183.         if(PMC_HAL_GetAckIsolation(PMC_BASE_PTR) != 0)
  184.         {
  185.                 PMC_HAL_ClearAckIsolation(PMC_BASE_PTR);
  186.         }

  187.         ClockInit();

  188.         DebugConsole_Init();

  189.         LPTMR_Init();
  190.         GPIO_Init();

  191. /*
  192.         // Enables LLWU interrupt
  193.         INT_SYS_EnableIRQ(LLWU_IRQn);
  194. <font color="#ff0000"><b>        lptmrEnableWakeUp();          //LPTMR 模块实现5秒定时,超时将产生中断并唤醒MCU。</b></font>
  195. <b><font color="#ff0000">        gpioEnableWakeUp();</font></b>
  196. */

  197.     /* First, setup an smc_power_mode_config_t variable to be passed to the SMC
  198.     * HAL function
  199.     */

  200. #ifdef VLPS_mode
  201.          smc_power_mode_config_t smc_power_config =
  202.          {
  203.                          .powerModeName = <b>kPowerModeVlps</b>, // Set the desired power mode
  204.          };
  205. #endif

  206.     /* This for loop should be replaced. By default this loop allows a single stepping. */
  207.     while (1) {
  208. #ifdef VLPS_mode
  209.             PRINTF("\n\rEnter Into Low Power\n\r\n\r");
  210.                 /* Now call the SMC HAL SetMode function to move to the desired power mode. */
  211.                 if (SMC_HAL_SetMode(SMC, &smc_power_config) != kSmcHalSuccess) PRINTF("\n\rFail\n\r\n\r");
  212. #endif
  213.     }
  214.     /* Never leave main */
  215.     return 0;
  216. }
  217. ////////////////////////////////////////////////////////////////////////////////
  218. // EOF
  219. ////////////////////////////////////////////////////////////////////////////////
复制代码



代码分析:
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);


  • 使能LPTMR模块的中断作为唤醒源
       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);
        }




回复

使用道具 举报

该用户从未签到

2

主题

189

帖子

0

中级会员

Rank: 3Rank: 3

积分
244
最后登录
2020-10-19
发表于 2015-11-3 16:05:45 | 显示全部楼层
感谢分享
回复

使用道具 举报

该用户从未签到

34

主题

135

帖子

0

中级会员

Rank: 3Rank: 3

积分
387
最后登录
2016-1-13
发表于 2015-11-4 14:23:31 | 显示全部楼层
如果用来申请KL26Z ,按照规则写主题帖,审核方便也助于申请
回复 支持 反对

使用道具 举报

该用户从未签到

4

主题

78

帖子

0

中级会员

Rank: 3Rank: 3

积分
209
最后登录
2015-12-11
发表于 2015-11-4 14:54:15 | 显示全部楼层
测试结果怎么样啊
回复 支持 反对

使用道具 举报

该用户从未签到

2

主题

109

帖子

0

中级会员

Rank: 3Rank: 3

积分
278
最后登录
2016-6-10
发表于 2015-11-4 19:27:54 | 显示全部楼层

感谢分享
回复

使用道具 举报

该用户从未签到

27

主题

320

帖子

0

中级会员

Rank: 3Rank: 3

积分
484
最后登录
2016-3-28
 楼主| 发表于 2015-11-6 08:56:23 | 显示全部楼层

互相支持
回复 支持 反对

使用道具 举报

  • TA的每日心情
    慵懒
    2017-3-12 12:14
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    7

    主题

    556

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1601
    最后登录
    2017-3-12
    发表于 2015-11-6 11:05:59 | 显示全部楼层
    感谢分享,
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    58

    帖子

    0

    注册会员

    Rank: 2

    积分
    131
    最后登录
    2015-11-19
    发表于 2015-11-9 17:33:33 | 显示全部楼层
    好东西啊,支持
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-27 04:15 , Processed in 0.098201 second(s), 26 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表