打印
[AT32F421]

AT32F421使用内部低速时钟如何每5分钟一次唤醒,可以有偿

[复制链接]
796|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
目前我如图配置只能实现进入一次时钟中断,如何配置ertc_alarm_value_set(3)这个函数实现每5分钟进一次ERTC闹钟中断,有没有大神指点一下。
1、
static void ERTC_AlarmConfig(void)
{
  EXTI_InitType EXTI_InitStructure;
//  ERTC_AlarmType ERTC_AlarmStructure;
  NVIC_InitType NVIC_InitStructure;

  /* EXTI configuration */
  EXTI_ClearIntPendingBit(EXTI_Line17);
  EXTI_InitStructure.EXTI_Line = EXTI_Line17;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineEnable = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  /* Enable the ERTC Alarm Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = ERTC_IRQn;//ERTCAlarm_IRQn
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* Set the alarm A Masks */
  ERTC_AlarmStructure.ERTC_AlarmMask = ERTC_AlarmMask_DateWeek | ERTC_AlarmMask_Hours | ERTC_AlarmMask_Seconds;
  ERTC_AlarmStructure.ERTC_AlarmDateWeekSel = ERTC_AlarmDateWeekSel_Date;
  ERTC_AlarmStructure.ERTC_AlarmDateWeek = ERTC_Week_MON;
  ERTC_AlarmStructure.ERTC_AlarmTime.ERTC_Hours = 0X0;
  ERTC_AlarmStructure.ERTC_AlarmTime.ERTC_Minutes = 0X5;
  ERTC_AlarmStructure.ERTC_AlarmTime.ERTC_Seconds = 0X0;
  ERTC_SetAlarmValue(ERTC_Format_BCD, ERTC_AlA, &ERTC_AlarmStructure);

  /* Enable alarm A interrupt */
  ERTC_INTConfig(ERTC_INT_ALA, ENABLE);

  /* Enable the alarmA */
  ERTC_AlarmCmd(ERTC_AlA, ENABLE);
}

2、static void ERTC_Config(void)
{
  /* Enable the PWR clock */
//  RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_PWR, ENABLE);
  /* Allow access to ERTC */
  PWR_BackupAccessCtrl(ENABLE);
  /* Reset ERTC Domain */
  RCC_BackupResetCmd(ENABLE);
  RCC_BackupResetCmd(DISABLE);
  /* Enable the LSE OSC */
//  RCC_HSEConfig(RCC_HSE_ENABLE);  //启用HSE
    RCC_LSICmd(ENABLE);             //启用LSI
  /* Wait till LSE is ready */  
  while(RCC_GetFlagStatus(RCC_FLAG_LSISTBL) == RESET)
  {
  }
  /* Select the ERTC Clock Source */
  RCC_ERTCCLKConfig(RCC_ERTCCLKSelection_LSI);


  /* Enable the ERTC Clock */
  RCC_ERTCCLKCmd(ENABLE);
  /* Deinitializes the ERTC registers */  
  ERTC_Reset();  
  /* Wait for ERTC APB registers synchronisation */
  ERTC_WaitForSynchro();
  /* Configure the ERTC data register and ERTC prescaler */
  /* ck_spre(1Hz) = ERTCCLK(LSI) /(AsynchPrediv + 1)*(SynchPrediv + 1)*/
  ERTC_InitStructure.ERTC_AsynchPrediv = 0x7F;
  ERTC_InitStructure.ERTC_SynchPrediv  = 0x13F;//0xFF;
  ERTC_InitStructure.ERTC_HourFormat   = ERTC_HourFormat_24;
  ERTC_Init(&ERTC_InitStructure);

  /* Set the time to 00h 00mn 00s AM */
  ERTC_TimeStruct.ERTC_AMPM     = ERTC_H12_AM;
  ERTC_TimeStruct.ERTC_Hours   = 0;
  ERTC_TimeStruct.ERTC_Minutes = 0;
  ERTC_TimeStruct.ERTC_Seconds = 0;  
  ERTC_SetTimeValue(ERTC_Format_BCD, &ERTC_TimeStruct);
}



3、
int main(void)
{
    __IO uint32_t systick_index = 0;
        System_Init();                                                                 //硬件初始化
    Init_Function();                 //功能部件初始化
        init_sucess_flag = 1;
//    bsp_StartAutoTimer(3, 30000);          //50ms定时器
                            //初始化看门狗,时间3S左右
    //stop      
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_PWR, ENABLE);

    ERTC_Config();
    ERTC_AlarmConfig();   
    EXTI9_Config();
    EXTI15_Config();
        //进入主程序循环体
//    _IWDG_Init();
        while (1)
        {
                //UpdateJudge();                 //判断是否有更新程序
                bsp_Idle();                                                         //调用MODS_Poll()
                Modbus_Data_P();
                RCC_GetClocksFreq(&get_rcc_clock);
                PLC_Function();
                LED_RUN_Function();
//                Sys_Reboot_Count_Function();
        ConfigModuleNoBlock();
//        ertc_alarm_value_set(3);
        len = rbCanRead(&rb_t_usart1_read);//读取数据
        if(len > 0)
        {
            memset(usart1_read_buff_copy, 0, rb_t_usart1_read_buff_len);
            rbRead(&rb_t_usart1_read, usart1_read_buff_copy, len);//!!!!!!!!!!!!!!!!!!!!!!!!!!
            if(ConfigConnectDispose != NULL)
            {
               ConfigConnectDispose((char*)usart1_read_buff_copy, len);
            }

        }
//
        if(Stop_Flag == 0 && SYS_start == 0)
        {
//            systick_index = SysTick->CTRL;
//            systick_index &= ~((uint32_t)0xFFFFFFFE);
//            SysTick->CTRL &= (uint32_t)0xFFFFFFFE;
//            ertc_alarm_value_set(3);
//          ERTC_TimeStruct.ERTC_AMPM     = ERTC_H12_AM;
//          ERTC_TimeStruct.ERTC_Hours   = 0;
//          ERTC_TimeStruct.ERTC_Minutes = 0;
//          ERTC_TimeStruct.ERTC_Seconds = 0;  
//          ERTC_SetTimeValue(ERTC_Format_BCD, &ERTC_TimeStruct);
            PWR_EnterSTOPMode(PWR_Regulator_LowPower_Extra, PWR_STOPEntry_WFI);
//            SysTick->CTRL |= 0x1;
//            SysTick->CTRL |= systick_index;
            SYSCLKConfig_STOP();
        }
    }
}

4、
void ertc_alarm_value_set(uint32_t alam_index)
{
//    ERTC_InitType  ERTC_InitStructure;
    ERTC_TimeType  ERTC1_TimeStruct;
//    ERTC_AlarmType ERTC_AlarmStructure;
//  ERTC_TimeType ERTC_TimeStruct;

  /* disable the alarm */
//  ertc_alarm_enable(ERTC_ALA, FALSE);
  ERTC_AlarmCmd(ERTC_AlA, DISABLE);

  //ertc_calendar_get(&ertc_time_struct);
  ERTC_GetTimeValue(ERTC_Format_BCD, &ERTC1_TimeStruct);
//ertc_alarm_set(ERTC_ALA, ertc_time_struct.day, ertc_time_struct.hour, ertc_time_struct.min, (ertc_time_struct.sec + alam_index)% 60, ertc_time_struct.ampm);
  ERTC_AlarmStructure.ERTC_AlarmMask = ERTC_AlarmMask_DateWeek | ERTC_AlarmMask_Hours | ERTC_AlarmMask_Seconds;
  ERTC_AlarmStructure.ERTC_AlarmDateWeekSel = ERTC_AlarmDateWeekSel_Date;
//  ERTC_AlarmStructure.ERTC_AlarmDateWeek = ERTC_Week_MON;
  ERTC_AlarmStructure.ERTC_AlarmTime.ERTC_Hours = ERTC1_TimeStruct.ERTC_Hours;
  ERTC_AlarmStructure.ERTC_AlarmTime.ERTC_Minutes = (ERTC1_TimeStruct.ERTC_Minutes+alam_index) % 60;
  ERTC_AlarmStructure.ERTC_AlarmTime.ERTC_Seconds = ERTC1_TimeStruct.ERTC_Seconds;
  ERTC_AlarmStructure.ERTC_AlarmTime.ERTC_AMPM    = ERTC1_TimeStruct.ERTC_AMPM;
  ERTC_SetAlarmValue(ERTC_Format_BCD, ERTC_AlA, &ERTC_AlarmStructure);
  ERTC_AlarmCmd(ERTC_AlA, ENABLE);
  /* disable the alarm */
  ERTC_AlarmCmd(ERTC_AlA, ENABLE);
}
void SYSCLKConfig_STOP(void)
{
  RCC_HSEConfig(RCC_HSE_ENABLE);
  HSEStartUpStatus = RCC_WaitForHSEStable();
  if(HSEStartUpStatus == SUCCESS)
  {
    RCC_PLLCmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_PLLSTBL) == RESET)
    {
    }
    RCC_SYSCLKConfig(RCC_SYSCLKSelction_PLL);
    while(RCC_GetSYSCLKSelction() != 0x08)
    {
    }
  }
}

5、
oid ERTC_IRQHandler(void)
{
    if(ERTC_GetINTStatus(ERTC_INT_ALA) != RESET)
    {
        /* Clear ERTC AlarmA Flags */
        Stop_Flag = 1;
        Report_5min_flag = 1;
        ERTC_ClearINTPendingBINT(ERTC_INT_ALA);

    }
    /* Clear the EXTI line 17 */
    EXTI_ClearIntPendingBit(EXTI_Line17);
}

使用特权

评论回复
沙发
chenqianqian| | 2023-6-11 22:19 | 只看该作者
定时器计时中断唤醒。

使用特权

评论回复
板凳
yh1634803087|  楼主 | 2023-6-12 08:50 | 只看该作者
chenqianqian 发表于 2023-6-11 22:19
定时器计时中断唤醒。

你好,请问有例程吗?我这个ertc_alarm_value_set()的函数是看最新的库里有个调整闹钟时间的函数仿写的。我这个库怎么才能进入低功耗前重新设置闹钟时间+5分钟?

使用特权

评论回复
地板
muyichuan2012| | 2023-6-12 16:08 | 只看该作者
参考BSP中如下案例
AT32F421_Firmware_Library/ project / at_start_f421 / examples / pwc / standby_ertc_alarm
调用如下函数将对应Hour/data进行mask即可。
ertc_alarm_mask_set(ERTC_ALA, ERTC_ALARM_MASK_DATE_WEEK | ERTC_ALARM_MASK_HOUR | ERTC_ALARM_MASK_MIN);
对应RTC应用指南第2.58章节有描述原理
https://www.arterytek.com/downlo ... _Note_ZH_V2.0.2.pdf

使用特权

评论回复
5
Henryko| | 2023-6-12 22:58 | 只看该作者
直接用定时器计数不就行了

使用特权

评论回复
评论
yh1634803087 2023-6-13 08:32 回复TA
你好,STOP模式下,定时器可以用吗,没试过。 
6
yh1634803087|  楼主 | 2023-6-16 08:46 | 只看该作者
谢谢各位关注,问题解决了,老版本的库STOP模式是有问题的,加上我图上那段后也能 用,但还是建议使用STANDBY模式吧。

使用特权

评论回复
7
qcliu| | 2023-7-1 15:50 | 只看该作者
楼主的意思是 现有代码可以进入中断 但是只能进入一次 不能再次进入了是吗

使用特权

评论回复
8
drer| | 2023-7-1 16:05 | 只看该作者
楼主的代码里边使能的是哪个模块的中断啊

使用特权

评论回复
9
coshi| | 2023-7-1 16:45 | 只看该作者
yh1634803087 发表于 2023-6-16 08:46
谢谢各位关注,问题解决了,老版本的库STOP模式是有问题的,加上我图上那段后也能用,但还是建议使用STANDB ...

楼主有没有对比 新老版本 他们的差别在哪里啊

使用特权

评论回复
10
kxsi| | 2023-7-1 17:04 | 只看该作者
yh1634803087 发表于 2023-6-16 08:46
谢谢各位关注,问题解决了,老版本的库STOP模式是有问题的,加上我图上那段后也能用,但还是建议使用STANDB ...

也就是说在老版本下 这个定时器的中断是不支持的是吗

使用特权

评论回复
11
wiba| | 2023-7-1 17:23 | 只看该作者
也就是说得明确各种模式下那么模块是可以正常工作的吧

使用特权

评论回复
12
tpgf| | 2023-7-1 17:38 | 只看该作者
内部时钟在停止模式下是不是已经完全不能正常工作了啊

使用特权

评论回复
13
yh1634803087|  楼主 | 2023-7-10 09:03 | 只看该作者
tpgf 发表于 2023-7-1 17:38
内部时钟在停止模式下是不是已经完全不能正常工作了啊

内部低速时钟可以工作的。

使用特权

评论回复
14
yh1634803087|  楼主 | 2023-7-10 09:04 | 只看该作者
wiba 发表于 2023-7-1 17:23
也就是说得明确各种模式下那么模块是可以正常工作的吧

嗯,合理选择模式,我这个是因为库太老了,可能有点问题,好在解决了,都能实现的。

使用特权

评论回复
15
yh1634803087|  楼主 | 2023-7-10 09:06 | 只看该作者
kxsi 发表于 2023-7-1 17:04
也就是说在老版本下 这个定时器的中断是不支持的是吗

支持的,只不过要在进入之前再清一下ERTC的初始值,具体啥原因不清楚,自己一直一直试出来的。

使用特权

评论回复
16
yh1634803087|  楼主 | 2023-7-10 09:06 | 只看该作者
coshi 发表于 2023-7-1 16:45
楼主有没有对比 新老版本 他们的差别在哪里啊

我一开始发的就是没解决的版本,后面发的就是解决了修改的地方

使用特权

评论回复
17
yh1634803087|  楼主 | 2023-7-10 09:08 | 只看该作者
qcliu 发表于 2023-7-1 15:50
楼主的意思是 现有代码可以进入中断 但是只能进入一次 不能再次进入了是吗 ...

嗯,之前是这个问题,后面加入我最新的修改,就好了,就达到了我的目的,每5分钟唤醒进入一次中断。

使用特权

评论回复
18
chenjun89| | 2023-7-11 08:12 | 只看该作者
中断后有没有重新对定时器进行赋值

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

9

帖子

0

粉丝