打印
[CW32L083系列]

请教关于rtc一晚上偏差时间过大的问题

[复制链接]
1630|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
rtc运行一晚上时间比实际实际快了十多分钟 ,程序运行逻辑,程序运行后5分钟进入休眠模式,10分钟后rtc唤醒并打印当前时间
请教出现这种情况的原因是什么
rtc 配置
void my_rtc_Init(void)
{
    RTC_InitTypeDef RTC_InitStruct = {0};

     RTC_InitStruct.DateStruct.Day = 0x20;             //设置日期,DAY、MONTH、YEAR必须为BCD方式,星期为0~6,代表星期日,星期一至星期六

    RTC_InitStruct.DateStruct.Month = RTC_Month_March;

    RTC_InitStruct.DateStruct.Week = RTC_Weekday_Wednesday;

    RTC_InitStruct.DateStruct.Year = 0x24;



    RTC_InitStruct.TimeStruct.Hour = 0x09;         //设置时间,HOUR、MINIUTE、SECOND必须为BCD方式,用户须保证HOUR、AMPM、H24之间的关联正确性

    RTC_InitStruct.TimeStruct.Minute = 0x09;

    RTC_InitStruct.TimeStruct.Second = 0x00;

    RTC_InitStruct.TimeStruct.AMPM = 0;

    RTC_InitStruct.TimeStruct.H24 = 1;

    RTC_InitStruct.RTC_ClockSource = RTC_RTCCLK_FROM_LSI;

    RTC_Init(&RTC_InitStruct);    //  用户需选定需要使用的时钟源

}

/* 设置时钟 */
unsigned char at_cmd_setrtc(Timestamp  tm){

        RTC_DateTypeDef RTC_DateStruct = {0};
        RTC_TimeTypeDef RTC_TimeStruct = {0};
        RTC_DateStruct.Year = HexToBcd((unsigned char) tm.year);
        RTC_DateStruct.Month = HexToBcd((unsigned char) tm.month);
        RTC_DateStruct.Day = HexToBcd((unsigned char) tm.day);
        RTC_DateStruct.Week = HexToBcd((unsigned char) tm.week);
        RTC_TimeStruct.Hour = HexToBcd((unsigned char) tm.hour);
        RTC_TimeStruct.Minute = HexToBcd((unsigned char) tm.minute);
        RTC_TimeStruct.Second = HexToBcd((unsigned char) tm.second);
        RTC_TimeStruct.AMPM = 0;
        RTC_TimeStruct.H24 = 1;
        RTC_SetTime(&RTC_TimeStruct);
        RTC_SetDate(&RTC_DateStruct);
    return 0;
}


uint8_t *WeekdayStr[7]= {"SUN","MON","TUE","WED","THU","FRI","SAT"};

void showrtctime(void)
{
    char out[20];

    RTC_TimeTypeDef RTC_TimeStruct = {0};

    RTC_DateTypeDef RTC_DateStruct = {0};

    RTC_GetDate(&RTC_DateStruct);

    RTC_GetTime(&RTC_TimeStruct);

    sprintf(out,"20%02d-%02d-%02d %s",BcdToHex(RTC_DateStruct.Year),BcdToHex(RTC_DateStruct.Month),BcdToHex(RTC_DateStruct.Day),WeekdayStr[RTC_DateStruct.Week]);

    printf("current time: %s ",out);

    sprintf(out,"%02d:%02d:%02d",BcdToHex(RTC_TimeStruct.Hour),BcdToHex(RTC_TimeStruct.Minute),BcdToHex(RTC_TimeStruct.Second));

    printf(" %s \r\n",out);

}


void set_rtcAwk(uint16_t interval)
{
        RTC_AWTTypeDef RTC_AWTStruct = {0};
    RTC_AWTCmd(DISABLE);
    NVIC_DisableIRQ(RTC_IRQn);
      
    interval = (uint16_t)(interval*0.125) - 1;
      
        printf("set_rtcAwk  %d \r\n", interval);
    showrtctime();

    RTC_AWTStruct.AWT_ARRValue = interval;  //(interval+1)/0.125
    RTC_AWTStruct.AWT_ClockSource = RTC_AWTSOURCE_FROM_RTC1HZ_8; //0.125hz
    RTC_AWTConfig(&RTC_AWTStruct);

        RTC_ClearITPendingBit(RTC_IT_AWTIMER);
    RTC_AWTCmd(ENABLE);
    RTC_ITConfig(RTC_IT_AWTIMER, ENABLE);
    NVIC_EnableIRQ(RTC_IRQn);
}

void RTC_IRQHandlerCallBack(void)
{
    if (RTC_GetITState(RTC_IT_AWTIMER ))
    {
        showrtctime();
               
        RTC_ClearITPendingBit(RTC_IT_AWTIMER);
    }
}




/******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
void System_Clk_Config(void)
{
        uint8_t res;
      
        RCC_HSI_Enable( RCC_HSIOSC_DIV2 );     //配置系统时钟为HSI 24M
        RCC_LSI_Enable();
      
        RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_FLASH, ENABLE);  //打开FLASH时钟      
        FLASH_SetLatency(FLASH_Latency_1);    //频率小等于24M需要配置FlashWait=1  
        REGBITS_SET(CW_FLASH->CR1, FLASH_CR1_STANDBY_Msk); //打开FLASH低功耗使能控制
        res = RCC_SysClk_Switch( RCC_SYSCLKSRC_HSI );                        //切换系统时钟到HSI
        if( res == 0x0U )                                                    //切换系统时钟成功
        {                                                                                    
                RCC_SystemCoreClockUpdate(24000000);
                RCC_HCLKPRS_Config(RCC_HCLK_DIV1); //HCLK(不分频)=PCLK
                RCC_PCLKPRS_Config(RCC_PCLK_DIV1);                       
        }
        else
        {
                while(1)
                {
                        
                }
        }
                       
               
}
void RCC_CLK_Config(void)
{

        //外设时钟使能
        __RCC_GPIOA_CLK_ENABLE();
        __RCC_GPIOB_CLK_ENABLE();
        __RCC_GPIOC_CLK_ENABLE();
        __RCC_GPIOF_CLK_ENABLE();
        __RCC_UART1_CLK_ENABLE();
        __RCC_UART2_CLK_ENABLE();
        __RCC_UART3_CLK_ENABLE();
        __RCC_UART4_CLK_ENABLE();
        __RCC_UART5_CLK_ENABLE();
        __RCC_UART6_CLK_ENABLE();
        //__RCC_SPI1_CLK_ENABLE();
        __RCC_RTC_CLK_ENABLE();
        __RCC_BTIM_CLK_ENABLE();
        __RCC_DMA_CLK_ENABLE();      



}
/******************************************************************************
* Local variable definitions ('static')                                      *
******************************************************************************/

/******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/

/*****************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/




/**
******************************************************************************
** \brief  Main function of project
**
** \return uint32_t return value, if needed
**
** This sample HSI switch to PLL, PLL switch to HSI.
**
******************************************************************************/
int32_t main(void)
{
      
      
        System_Clk_Config();      
        RCC_CLK_Config();
      
        //InitTick(24000000);
      
      
        my_rtc_Init();
        set_rtcAwk(600);
      
      
        Sleep_Mode_Config(DEEP_SLEEP_MODE); //DEEP_SLEEP_MODE
      

        printf("test...\r\n");
        while (1)
        {
                /* code */
               
               
                if(1==devParam_t.enter_sleep)
                {
                       
                        showrtctime();
                        printf("enter_low_power_consumption_mode...\r\n");
                        Enter_Deep_Sleep_Mode();
                        devParam_t.enter_sleep=0;
                        printf("exit_low_power_consumption_mode...\r\n");
                        showrtctime();
                }

        }
               

      
}

使用特权

评论回复
沙发
pssyx| | 2024-3-21 10:06 | 只看该作者
本帖最后由 pssyx 于 2024-3-21 10:16 编辑

RTC时钟24H误差正常。
CW32L083的低速内部(LSI)RC 振荡器的典型值为32.8kHz,且25度时,LSI精度为+-1%。
如果对RTC时钟精度有要求,建议使用外部32768晶体。

LSI.png (84.39 KB )

LSI.png

使用特权

评论回复
板凳
jf101| | 2024-3-22 12:31 | 只看该作者
系统使用有时会卡顿的

使用特权

评论回复
地板
szt1993| | 2024-3-25 15:15 | 只看该作者
理论上应该是程序运行的累计误差

使用特权

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

本版积分规则

4

主题

8

帖子

0

粉丝