AnsweredAssumed Answered

issue about stm32l431 rtc second register update

Question asked by cai.bai on Jul 19, 2017

hi,i initialize and set rtc as follow

 

int rtcInit(void){

 

    RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;    // enable PWR clock
    PWR->CR1 |= 0x00000100; // disable BD write protect
    while(0 == (PWR->CR1 & 0x00000100));
    RCC->BDCR |= ((1 << 15) | (3 << 8));    // enable RTC clock,select HSE/32 as clock source of rtc,HSE is 8M
    PWR->CR1 &= 0xFFFFFEFF; // enable BD write protect
    RCC->APB1ENR1 &= ~(RCC_APB1ENR1_PWREN); // disable PWR clock

 

    return 0;
}

 

int rtcSet(unsigned short year,unsigned char month,unsigned char day,unsigned char hours,unsigned char minute,unsigned char second,unsigned int mSecond){

 

    RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;    // enable PWR clock
    PWR->CR1 |= 0x00000100; // disable BD write protect
    while(0 == (PWR->CR1 & 0x00000100));
    RTC->WPR = 0xCA;
    RTC->WPR = 0x53;    // disable rtc write protect
    RTC->CR = 0x00000000;
    RTC->ISR |= (1 << 7);   // enter initialize mode
    while (0 == (RTC->ISR & (1 << 6))); // wait for enter initialize mode
    RTC->PRER = (124 << 16) | (1999 << 0);  // rtcSrcClock is HSE/32 = 250000
    RTC->TR = (((hours/10)%10) << 20) | ((hours%10) << 16) | (((minute/10)%10) << 12) | ((minute%10) << 8) | (((second/10)%10) << 4) | ((second%10) << 0);
    RTC->DR = (((year/10)%10) << 20) | ((year%10) << 16) | (((month/10)%10) << 12) | ((month%10) << 8) | (((day/10)%10) << 4) | ((day%10) << 0);
    RTC->ISR &= ~(1 << 7);  // exit initialize mode
    PWR->CR1 &= 0xFFFFFEFF; // enable BD write protect
    RCC->APB1ENR1 &= ~(RCC_APB1ENR1_PWREN); // disable PWR clock
    return (0 == (RTC->ISR & (1 << 4)));
}

 

int rtcGet(unsigned short * year,unsigned char * month,unsigned char * day,unsigned char * hours,unsigned char * minute,unsigned char * second,unsigned int * mSecond){

 

    unsigned int rtcd,rtct,rtcss,rst;
    if((NULL == year) ||
       (NULL == month) ||
       (NULL == day) ||
       (NULL == hours) ||
       (NULL == minute) ||
       (NULL == second) ||
       (NULL == mSecond)) {
        logWarnFL("invalid argument %p %p %p %p %p %p %p\r\n",year,month,day,hours,minute,second,mSecond);
        return -1;
    }
    if(0 == (RTC->ISR & (1 << 4))) {
        // RTC not initialize
        logWarnFL("rtc not initialize\r\n");
        return -2;
    }

 

    RTC->ISR |= (1 << 5);   // clear RSF
    while (0 == (RTC->ISR & (1 << 5))); // wait for RSF assert
    RTC->ISR |= (1 << 5);   // clear RSF
    rtct = RTC->TR;
    rtcss = RTC->SSR;
    rtcd = RTC->DR;
    rst = RTC->SSR & (1 << 5);

 

    *year = ((rtcd >> 20) & 0x0F) * 10 + ((rtcd >> 16) & 0x0F) + 2000;
    *month = ((rtcd >> 12) & 0x01) * 10 + ((rtcd >>  8) & 0x0F);
    *day = ((rtcd >>  4) & 0x03) * 10 + ((rtcd >>  0) & 0x0F);
    *hours = ((rtct >> 20) & 0x03) * 10 + ((rtct >> 16) & 0x0F);
    *minute = ((rtct >> 12) & 0x07) * 10 + ((rtct >>  8) & 0x0F);
    *second = ((rtct >>  4) & 0x07) * 10 + ((rtct >>  0) & 0x0F);
    *mSecond = (2000 - rtcss)/2;
    return rst;
}

 

void rtcPrint(void){

 

    unsigned short year;
    unsigned char month,day,hours,minute,second;
    unsigned int mSecond;
    int rst = rtcGet(&year,&month,&day,&hours,&minute,&second,&mSecond);

 

    logInfo("%02d-%02d-%02d %02d:%02d:%02d %03d  ---->    %d\r\n",year,month,day,hours,minute,second,mSecond,rst);
    return;
}

 

then i initialize it

...

rtcInit();
rtcSet(2017,1,10,12,0,0,0)

 

finally,i print date and time on a dead-loop

    while(1) {        
      int i = 0x1FFFFF;while(i--);        
      rtcPrint();    
   }

as follow

Outcomes