[活动专区] 【AT-START-L021测评】06 基于AT32L021 低功耗框架设计

[复制链接]
 楼主| 怀揣少年梦 发表于 2024-12-9 23:13 | 显示全部楼层 |阅读模式
一、设计目的
在低功耗模式下正常运行以下功能:
1、能够在正常进行LED翻转;
4e923f6729c0098fd4e9427f0fd12ced.gif
2、能够正常以115200波特率接收串口数据;并进行数据处理
串口接收.png
3、能够适用物联网进行周期性收发数据的低功耗场景,并且能够进行设备状态的正常显示。

二、设计思路
1、设计基础
1)基于AT32L021的深度休眠模式下,SRAM和寄存器的内容是保持的,并且IO口的状态与运行模式保持一样状态,从以上特性可以获取以下信息:
——进出低功耗模式,不需要重新配置相关外设或者IO参数
——关于电源的配置可以在初始化里面进行操作,不需要每次进行操作;
DEEPMODE SLEEP.png

2)AT32L021系统从深度睡眠模式退出时,默认选择HICK RC 振荡器开启并在稳定后被选为系统时钟,那么可以只配置LEXT外部晶振,高速晶振选择HICK,并进行分频。
PixPin_2024-12-09_23-04-14.png

2、思路
1)使用内置ERTC对于系统周期性唤醒,并点亮LED;为了加强秒的精度,不使用内置晶振;
2)配置内置HICK为系统时钟,为了进一步降低功耗,就选择16Mhz作为是系统时钟频率,另外一方面,16Mhz唤醒的时间也不会短。
3)设置内置LDO为低功耗模式。

三、代码编写
1、按照上述思路,配置LEXT和系统时钟
1)使能LEXT
使能外置晶振.png

2)设置系统时钟源为HICK 48,并设置分频值为4;
PLL.png

2、使能ERTC,启用内部唤醒,并开启中断
ERTC.png

3、使能串口,并开启中断
串口.png

4、编写串口唤醒代码
  1. void usart1_wakeup_config(void)
  2. {
  3.   exint_init_type exint_init_struct;
  4.   
  5.   /* keep usart work when deepsleep */
  6.   usart_deep_sleep_mode_enable(USART1, TRUE);
  7.   
  8.   /* low power wakeup method is receive data buffer full */
  9.   usart_low_power_wakeup_set(USART1, USART_WAKEUP_METHOD_RDBF);
  10.   
  11.   usart_interrupt_enable(USART1, USART_LPWUF_INT, TRUE);
  12.   
  13.   /* config the exint line of the usart1 */
  14.   exint_init_struct.line_select   = EXINT_LINE_25;
  15.   exint_init_struct.line_enable   = TRUE;
  16.   exint_init_struct.line_mode     = EXINT_LINE_INTERRUPT;
  17.   exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
  18.   exint_init(&exint_init_struct);
  19. }


5、编写ERTC中断和串口中断处理函数
ERTC中断和串口处理函数
  1. void ERTC_IRQHandler(void)
  2. {
  3.   /* add user code begin ERTC_IRQ 0 */
  4.   if(ertc_interrupt_flag_get(ERTC_WATF_FLAG) != RESET)
  5.   {
  6.     /* clear ertc alarm flag */
  7.     ertc_flag_clear(ERTC_WATF_FLAG);
  8.                 wakeUpFalg = ERTC_WAKE_UP;
  9.                 g_exitLowPower = 1;
  10.     /* toggle led */
  11.   }
  12.   if(exint_interrupt_flag_get(EXINT_LINE_20) != RESET)
  13.   {
  14.     /* clear exint line flag */
  15.     exint_flag_clear(EXINT_LINE_20);
  16.   }
  17.   /* add user code end ERTC_IRQ 0 */
  18.   /* add user code begin ERTC_IRQ 1 */

  19.   /* add user code end ERTC_IRQ 1 */
  20. }
  1. void USART1_IRQHandler(void)
  2. {
  3.   /* add user code begin USART1_IRQ 0 */
  4. if(usart_flag_get(USART1, USART_RDBF_FLAG) != RESET)
  5.   {
  6.     /* clear rdbf flag */
  7.     usart1RxBuf[usart1RxIndex++] = usart_data_receive(USART1);
  8.                 g_exitLowPower = 1;

  9.   }

  10.   if(usart_interrupt_flag_get(USART1, USART_LPWUF_FLAG) != RESET)
  11.   {
  12.     usart_flag_clear(USART1, USART_LPWUF_FLAG);
  13.   }

  14.   if(exint_interrupt_flag_get(EXINT_LINE_25) != RESET)
  15.   {
  16.     exint_flag_clear(EXINT_LINE_25);
  17.   }
  18.   /* add user code end USART1_IRQ 0 */
  19.   /* add user code begin USART1_IRQ 1 */

  20.   /* add user code end USART1_IRQ 1 */
  21. }


6、编写主函数
  1. int main(void)
  2. {
  3.   /* add user code begin 1 */
  4. pwc_ldo_output_voltage_set(PWC_LDO_OUTPUT_1V2);
  5.   /* add user code end 1 */

  6.   /* system clock config. */
  7.   wk_system_clock_config();

  8.   /* config periph clock. */
  9.   wk_periph_clock_config();

  10.   /* nvic config. */
  11.   wk_nvic_config();

  12.   /* timebase config. */
  13.   wk_timebase_init();

  14.   /* usart1 already supports printf. */
  15.   /* init usart1 function. */
  16.   wk_usart1_init();

  17.   /* init ertc function. */
  18.   wk_ertc_init();

  19.   /* init gpio function. */
  20.   wk_gpio_config();

  21.   /* add user code begin 2 */

  22.         gpio_bits_set(GPIOB,GPIO_PINS_11);
  23.         wk_delay_ms(5000);
  24.   /* add user code end 2 */

  25.   while(1)
  26.   {
  27.     /* add user code begin 3 */
  28.     if (g_enterLowPower) {
  29.                         g_enterLowPower = 0;
  30.                         enter_lower_power_mode();
  31.                 }
  32.                
  33.                 if (g_exitLowPower) {
  34.                         g_exitLowPower = 0;
  35.                         exit_lower_power_mode();
  36.                         /*这里放置相关处理函数,处理完就进入低功耗模式*/
  37.                         g_enterLowPower = 1;
  38.                 }

  39.                 gpio_bits_toggle(GPIOB,GPIO_PINS_11);
  40.     /* add user code end 3 */
  41.   }
  42. }
        四、最后下载验证即可。

代码,如下:
LPFrame.zip (2.42 MB, 下载次数: 3)



问天少年 发表于 2024-12-10 18:41 | 显示全部楼层
运行这两个功能的情况下功耗多少
 楼主| 怀揣少年梦 发表于 2024-12-11 09:12 | 显示全部楼层
问天少年 发表于 2024-12-10 18:41
运行这两个功能的情况下功耗多少

没有实测,没有相应的监测平均电流的仪器。使用万用表看到的数据,在200uA左右跳动
呐咯密密 发表于 2024-12-12 10:01 | 显示全部楼层
怀揣少年梦 发表于 2024-12-11 09:12
没有实测,没有相应的监测平均电流的仪器。使用万用表看到的数据,在200uA左右跳动 ...

200ua的话还是很低的
 楼主| 怀揣少年梦 发表于 2024-12-12 17:02 | 显示全部楼层
呐咯密密 发表于 2024-12-12 10:01
200ua的话还是很低的

整体来看,功耗做的还是挺不错的
可怜的小弗朗士 发表于 2024-12-18 14:09 | 显示全部楼层
这个唤醒只用初始化时钟就行了吗

评论

还需要配置进入什么模式,唤醒串口的配置  发表于 2024-12-18 14:13
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:一切皆有可能

45

主题

473

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部
个人签名:一切皆有可能

45

主题

473

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部