股票

SAM4S低功耗模式的启用与唤醒设置

集中折腾了两天,终于把低功耗搞定!以下操作都是调用的ASF函数,没有直接操作寄存器。

sleep模式就不说了,使用官方例程,任意中断都可以把系统唤醒,要不要再次进入低功耗就可以随意设置了。我不用它主要是定时中断的时间间隔太短了,而使用wait mode则可以让我想什么时候唤醒就什么时候唤醒,不唤醒的时候定时中断的时钟还不工作,多么省事啊!下面,我就主要讲一下wait模式低功耗的启用与唤醒问题。

wait模式下,主时钟、PLL时钟、快速时钟全部掉电,可以唤醒系统的时钟只剩下了RTT和RTC。所以要想没有外部中断的情况下唤醒时钟,只能从这两个地方下手了。Atmel的说明文档介绍wait Mode下的唤醒方式的时候,反复列举的项目就三种:WKUP0-15 pins, RTT or RCC alarm, USB Wake-up。我在测试RTT在ASF下的示例程序时,也能进入RTT alarm,但是现在想来当时只是一个似懂非懂的状态而已。

在RTT_Handler这个中断函数里,有一个函数rtt_get_status(RTT)这个获取的是RTT初始化之后到现在的时间值,同时清除中断标志位。注意这个值:因为wait模式下,RTT时钟依然运行,所以进入wait模式后,这个值是一直在增加的!因此官方文档里面介绍的时候才说,RTT定时器可以累积2^32s的时间,大概一两百年吧。开始没意识到这一点,直到我反复读文档,才想明白。当我使用MCU进入休眠,过一会儿用外部中断把它唤醒的时候,再读取RTT时间,发现果然是一直增加。知道这点就好办了,RTT alarm可以唤醒wait mode下的MCU,那么设置好alarm时间,就相当于定时,一到时间就会把MCU唤醒啦!虽然在 wait mode下,RTT_Handle中断函数也进不去,但是不耽误进入RTT alarm。设置唤醒时间用的函数是rtt_write_alarm_time(Rtt *p_rtt, uint32_t ul_alarm_time)。

好了,到这里就简单了,整个流程:

1,初始化 RTT;

2,设置唤醒时间(先设置是为了减少执行后续程序产生的时钟误差);

3,设置wait mode唤醒方式是RTT alarm;

4,进入 wait mode 等待到时间唤醒;

5,唤醒之后立即再次设置下次唤醒时间,依次循环。

下面来点儿干货:

RTT初始化与中断函数:

 
  1. /************************************************************************/
  2. /* @brief RTT configuration function.
  3. /* Configure the RTT to generate a one second tick, which triggers the 
  4. /* RTTINC interrupt
  5. /************************************************************************/
  6. void configure_rtt(void)
  7. {
  8.     uint32_t ul_previous_time;
  9.     // Configure RTT for a 1 second tick interrupt
  10.     rtt_sel_source(RTT, false);
  11.     rtt_init(RTT, 32768);
  12.     ul_previous_time = rtt_read_timer_value(RTT);
  13.     while(ul_previous_time == rtt_read_timer_value(RTT));
  14.     // Enable RTT interrupt
  15.     NVIC_DisableIRQ(RTT_IRQn);
  16.     NVIC_ClearPendingIRQ(RTT_IRQn);
  17.     NVIC_SetPriority(RTT_IRQn, 0);
  18.     NVIC_EnableIRQ(RTT_IRQn);
  19.     rtt_enable_interrupt(RTT, RTT_MR_RTTINCIEN);
  20. }
  21. /************************************************************************/
  22. /* @brief Set alarm time.
  23. /************************************************************************/
  24. void alarm_set(uint32_t alarm_time)
  25. {
  26.     rtt_write_alarm_time(RTT, alarm_time);
  27. }
  28. /************************************************************************/
  29. /* @brief Interrupt handler for the RTT
  30. /* Display the current time on the terminal.
  31. /************************************************************************/
  32. void RTT_Handler(void)
  33. {
  34.     uint32_t ul_status;
  35.     // Get RTT status
  36.     ul_status = rtt_get_status(RTT);
  37.     printf(“Time = %d\n”, rtt_read_timer_value(RTT));
  38.     if((ul_status & RTT_SR_RTTINC) == RTT_SR_RTTINC)
  39.     {
  40.         printf(“ALARM OVER!\n”);
  41.     }
  42.     if((ul_status & RTT_SR_ALMS) == RTT_SR_ALMS)
  43.     {
  44.         printf(“ALARM!\n”);
  45.     }
  46.     LED_Toggle(LED0_GPIO);
  47. }

进入wait mode模式函数:

 
  1. // Wakeup pin for wait mode: RTTAL (rtt alarm enable)
  2. #define WAKEUP_WAIT_RTTAL_ENABLE (1u<<16)
  3. /**
  4.   * @brief  Enter Wait Mode.
  5.   * @param  None
  6.   * @retval None
  7.   */
  8. void enter_wait_mode(void)
  9. {
  10.     printf(“Enter into wait Mode.\n”);
  11.     while(!uart_is_tx_empty(CONSOLE_UART))
  12.     {
  13.     }
  14.     // Configure fast RC oscillator
  15.     pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1);
  16.     pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz);
  17.     pmc_switch_mck_to_mainck(PMC_PCK_PRES_CLK_1);
  18.     g_ul_current_mck = 4000000; // 4MHz
  19.     // Disable unused clock to save power
  20.     pmc_osc_disable_xtal(0);
  21.     pmc_disable_pllack();
  22.     // Set wakeup input for fast startup
  23.     pmc_set_fast_startup_input(WAKEUP_WAIT_RTTAL_ENABLE);
  24.     // enter into wait Mode
  25.     pmc_enable_waitmode();
  26.     // Set default clock and re-configure UART
  27.     set_default_working_clock();
  28.     reconfigure_console(g_ul_current_mck, CONF_UART_BAUDRATE);
  29.     delay_ms(1);
  30.     printf(“Exit from wait Mode.\n”);
  31. }
打赏
原文链接:,转发请注明来源!

发表评论