реклама на сайте
подробности

 
 
> RTC в STM32
123kill12
сообщение Oct 27 2011, 07:06
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 96
Регистрация: 12-05-10
Пользователь №: 57 217



что то не могу разобраться с RTC.

схема RTC

тактирование


у меня нет LSE поэтому буду питаться от HSE/128

вот моя иницилизация его
Код
void mcu_rtc_init(void)
{
    int rtc_value = 0x00;
        
    if ((RCC->BDCR & RCC_BDCR_RTCEN) != RCC_BDCR_RTCEN)                     //      если RTC отключен
    {
        RCC->BDCR |= RCC_BDCR_RTCSEL_0 | RCC_BDCR_RTCSEL_1;             //    выбираем внешний кварц 12MHz /128 =93750 Hz.
                
                RCC->BDCR |= RCC_BDCR_BDRST;                          //    сброс
        RCC->BDCR &= ~RCC_BDCR_BDRST;
        RCC->BDCR |= RCC_BDCR_RTCEN;                    //    разрешить работу RTC
                
        RTC->CRL |= RTC_CRL_CNF;                             //    заходим в режим конфигурации
        
        RTC->PRLH = 0;
        RTC->PRLL = 2-1;                         //    93750Hz/3=31250Hz
                                        //    1/31250Hz ->0.000032c
        RTC->ALRH = 0;                            //    0.000032c*125=0.004c=4mc
        RTC->ALRL = 125;    
        
        RTC->CNTH = rtc_value >> 16;
        RTC->CNTL = rtc_value;
        
        RTC->CRH |= RTC_CRH_ALRIE;                     //    разрешение прерывания по аларму.
        NVIC->ISER[0] |= ena_RTC_GLOBAL;                //    разрешить прерывание от RTC.
        //NVIC->ISER[1] |= ena_RTC_ALARM;                //    разрешить прерывание от alarm RTC.
        
        RTC->CRL &= ~RTC_CRL_CNF;                    //    выходим из режима конфигурации

        RTC->CRL &=~RTC_CRL_RSF;                    //    запустить синхронизацию
        while((RTC->CRL & RTC_CRL_RSF) != RTC_CRL_RSF){}            //    ожидание синхронизации
    }
}


void RTC_IRQHandler(void)
{
    count4ms++;
    if(count4ms==250)
    {
        count4ms=0;
        count1s++;
        if(count1s==86400)
        {
            count1s=0;
        }
    }
}


и он повисает тут
RTC->CRL &=~RTC_CRL_RSF; // запустить синхронизацию
while((RTC->CRL & RTC_CRL_RSF) != RTC_CRL_RSF){} // ожидание синхронизации

значит часы не запускаются(((

Сообщение отредактировал 123kill12 - Oct 27 2011, 10:16
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 8)
AHTOXA
сообщение Oct 27 2011, 09:00
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



А где включение тактирования?
Код
    RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;

потом надо отключить защиту backup domain:
Код
    PWR->CR |= PWR_CR_DBP;

Дальше. Сначала надо делать резет, а уже потом выбирать внешний кварц.
Пока хватитsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
123kill12
сообщение Oct 27 2011, 10:14
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 96
Регистрация: 12-05-10
Пользователь №: 57 217



а можно по подробнее?

выполнил две команды
RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
PWR->CR |= PWR_CR_DBP;
затем что за ресет? сброс часов или что?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 27 2011, 10:36
Сообщение #4


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Вот рабочий кусок:
CODE
// enable APB1 clocks
RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;

// disable backup domain write protection
PWR->CR |= PWR_CR_DBP;

// reset Backup Domain
RCC->BDCR |= RCC_BDCR_BDRST;
RCC->BDCR &= ~RCC_BDCR_BDRST;

RCC->BDCR &= ~(RCC_BDCR_LSEON | RCC_BDCR_LSEBYP);
// enable LSE
RCC->BDCR |= RCC_BDCR_LSEON;
// wait till LSE is ready
while (!(RCC->BDCR & RCC_BDCR_LSERDY)) ;
// select LSE as RTC clock source
RCC->BDCR |= RCC_BDCR_RTCSEL_LSE;

// enable RTC clock
RCC->BDCR |= RCC_BDCR_RTCEN;

// wait for RTC registers synchronization
wait_sync();

wait_ready();

// set RTC prescaler: set RTC period to 1sec
RTC->CRL |= RTC_CRL_CNF; // enter config mode
RTC->PRLH = 0;
RTC->PRLL = 32767;
RTC->CRL &= ~RTC_CRL_CNF; // exit config mode

wait_ready();

// enable backup domain write protection
PWR->CR &= ~PWR_CR_DBP;

wait_ready();


функции wait_ready() и wait_sync():
Код
void wait_sync(void) {
    RTC->CRL &= ~RTC_CRL_RSF;
    while (!(RTC->CRL & RTC_CRL_RSF));
}

void wait_ready(void) {
    while (!(RTC->CRL & RTC_CRL_RTOFF));
}




--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
123kill12
сообщение Oct 27 2011, 11:28
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 96
Регистрация: 12-05-10
Пользователь №: 57 217



Не пример понятно. но у меня нет LSE. есть LSI и HSE.
но все равно спасибо. завтра попробую.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 27 2011, 14:21
Сообщение #6


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Пардон, я не ту ветку вырезалsm.gif
Вот так:
Код
    if (use_lse)
    {
        // enable LSE
        RCC->BDCR |= RCC_BDCR_LSEON;

        // wait till LSE is ready
        while (!(RCC->BDCR & RCC_BDCR_LSERDY));

        // select LSE as RTC clock source
        RCC->BDCR |= RCC_BDCR_RTCSEL_LSE;
    } else {
        // enable LSI
        RCC->CSR |= RCC_CSR_LSION;

        // wait till LSI is ready
        while (!(RCC->CSR & RCC_CSR_LSIRDY));

        // select LSI as RTC clock source
        RCC->BDCR |= RCC_BDCR_RTCSEL_LSI;
    }


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
123kill12
сообщение Oct 31 2011, 07:53
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 96
Регистрация: 12-05-10
Пользователь №: 57 217



Так.

непонятно. от LSI все пашит, а от HSE/128 нет. просто не питается. кто знает что не так?
Go to the top of the page
 
+Quote Post
VslavX
сообщение Oct 31 2011, 08:30
Сообщение #8


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(123kill12 @ Oct 31 2011, 10:53) *
Так.

непонятно. от LSI все пашит, а от HSE/128 нет. просто не питается. кто знает что не так?

У меня сейчас вообще прикол получился. Я в своем коде, который отлажен на LSE, решил попробовать тактирование HSE/128. Так вот - битики SELECT_HSE в RCC_BDCR чудненько записались. И все - часики не тактируются, стоят. Вернулся на LSE и оказалось невозможно откатить битики выбора тактирования RTC в RCC_BDCR - они после аппаратного сброса оставались в HSE/128, код записи-настройки RCC_BDCR тоже отказался работать. Помогло только полное отключение питания, включая резервную батарейку. ИМХО, где-то тактовый сигнал при HSE/128 не доходит, при этом также смена настройки не происходит.

Go to the top of the page
 
+Quote Post
uriy
сообщение Dec 21 2012, 06:10
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



У меня тоже не тактируется от HSE/128. Часы стоят на месте. От LSI часы идут.
Началось все с того что у меня перестал генерить часовой кварц. Несколько недель работал, потом перестал.
Похоже для STM это огромная проблема с RTC. Очень много постов с проблемами RTC.
Уже попробовал 3 вида кварцев, правда они все китайские нонеймы.
Пробовал без кондеров и с кондерами от 5 до 22 пФ.
Ставил резистор на 5 МОм.
Все без толку.

Код
    /* Enable PWR and BKP clocks */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

    /* LSI clock stabilization time */
    //for(i=0;i<5000;i++) {; }

    if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) {
        /* Backup data register value is not correct or not yet programmed (when
           the first time the program is executed) */

        /* Allow access to BKP Domain */
        PWR_BackupAccessCmd(ENABLE);

        /* Reset Backup Domain */
        BKP_DeInit();

        /* Enable LSE */
        RCC_LSEConfig(RCC_LSE_ON);

        // enable LSI
        RCC_LSICmd(ENABLE);

        /* Wait till LSE is ready */
        os_dly_wait(10*SEC);


        //        while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
        //            {
        //
        //             }

        if(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
        {
            // LSE is not ready
            // select HSE/128 as RTC clock source
#warning dont' forget
            //RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);
            RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

            /* Enable RTC Clock */
            RCC_RTCCLKCmd(ENABLE);

            /* Wait for RTC registers synchronization */
            RTC_WaitForSynchro();

            /* Wait until last write operation on RTC registers has finished */
            RTC_WaitForLastTask();

            /* Set RTC prescaler: set RTC period to 1sec */
            //RTC_SetPrescaler((HSE_VALUE/128)-1);
            RTC_SetPrescaler(62499);

            printf("RTC clock source is HSE/128\r\n");
        }
        else
        {
            /* Select LSE as RTC Clock Source */
            RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

            /* Enable RTC Clock */
            RCC_RTCCLKCmd(ENABLE);

            /* Wait for RTC registers synchronization */
            RTC_WaitForSynchro();

            /* Wait until last write operation on RTC registers has finished */
            RTC_WaitForLastTask();

            /* Set RTC prescaler: set RTC period to 1sec */
            RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
            printf("RTC clock source is LSE\r\n");
        }

        /* Wait until last write operation on RTC registers has finished */
        RTC_WaitForLastTask();

        /* Set initial value */
        RTC_SetCounter( (uint32_t)((11*60+55)*60) ); // here: 1st January 2000 11:55:00

        /* Wait until last write operation on RTC registers has finished */
        RTC_WaitForLastTask();

        BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);

        /* Lock access to BKP Domain */
        PWR_BackupAccessCmd(DISABLE);

    } else {

        /* Wait for RTC registers synchronization */
        RTC_WaitForSynchro();
    }

Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 11:19
Рейтинг@Mail.ru


Страница сгенерированна за 0.01432 секунд с 7
ELECTRONIX ©2004-2016