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

 
 
 
Reply to this topicStart new topic
> Проблемы тактирования периферии LPC1768
GetSmart
сообщение Oct 28 2010, 23:58
Сообщение #1


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Вот вырезка из инициализации PLL0 проца LPC1768 в последней FreeRTOS (6.1.0). насколько я понял, в ней PLL работает на 400 МГц (что в разрешённом диапазоне 275-550). CCLKCFG равен 3, значит проц работает на 400/4 = 100 МГц.
Код
    /* select main OSC, 12MHz, as the PLL clock source. */
    SC->CLKSRCSEL = 0x1;        
    
    SC->PLL0CFG = 0x20031;
    SC->PLL0FEED = PLLFEED_FEED1;
    SC->PLL0FEED = PLLFEED_FEED2;
          
    /* Enable PLL, disconnected. */
    SC->PLL0CON = 1;                
    SC->PLL0FEED = PLLFEED_FEED1;
    SC->PLL0FEED = PLLFEED_FEED2;
    
    /* Set clock divider. */
    SC->CCLKCFG = 0x03;
    
    /* Configure flash accelerator. */
    SC->FLASHCFG = 0x403a;

Кварц у меня на плате (как и в исходниках фриртоса) = 12 МГц.

После этого я запускаю таймер 3, у которого ставлю делитель PCLK = 1/2 и следующее
Код
    SC->PCONP |= 1<<23;
    SC->PCLKSEL1 = (SC->PCLKSEL1 & ~(0x3<<14)) | (0x02 << 14);

    TIM3->TCR = 0x02;
    TIM3->CTCR = 0;
    TIM3->PR = 0;
    TIM3->MR0 = 100000000UL/2/100;

    TIM3->MCR = 0x03;
    TIM3->TCR = 0x01;
    TIM3->IR = 0xff;

    NVIC_SetPriority( TIMER3_IRQn, 6 );
    NVIC_EnableIRQ( TIMER3_IRQn );

А далее я вижу, что прерывание от таймера 3 происходит не 100, а 200 раз в секунду. Изменением делителя в PCLKSEL1 можно ускорить в 2 раза или замедлить в 2/4 раза. То есть он нормально работает. Получается, что тактирование таймера происходит не от CCLK (то есть от ядра проца), а от частоты в 2 раза выше.

У меня мануал кривой или что это за глюк?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
bseyur
сообщение Oct 29 2010, 06:14
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 8-01-07
Из: Томск
Пользователь №: 24 208



Требования эрраты не соблюдаете? PCLKSEL нужно инициализировать до включения PLL0.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 29 2010, 07:49
Сообщение #3


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Сомневаюсь, что в этом дело.
Во фриртосе в той же функции инициализации PLL-ов сразу после их инициализации стоит код
Код
    
    /*  Setup the peripheral bus to be the same as the PLL output (64 MHz). */
    SC->PCLKSEL0 = 0x05555555;

Камент жжот smile.gif


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
miv
сообщение Oct 29 2010, 08:58
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 41
Регистрация: 29-08-05
Из: С-Петербург
Пользователь №: 8 055



Цитата(bseyur @ Oct 29 2010, 10:14) *
Требования эрраты не соблюдаете? PCLKSEL нужно инициализировать до включения PLL0.

PLCKSEL и до работают wink.gif Для новых чипов.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 2 2010, 02:49
Сообщение #5


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Странно. UART1 работат нормально по частоте. А вот таймеры 1/2/3 на частоте в 2 раза большей.
Код
static uInt LedCnt;

void TMR3_IRQHandler()        // 100 Hz
{
    if (++LedCnt >= 100)
    {    LedCnt = 0;
        if( GPIO0->FIOSET & (1 << 22) )
                GPIO0->FIOCLR = 1 << 22;
        else    GPIO0->FIOSET = 1 << 22;
    }
    TIM3->IR = 0x3f;
}

На всякий случай вот прерывание, которое моргает светодиодом. Вдруг кто захочет проверить у себя.

На плате у меня проц с "-" ревизией. Перенос инициализации PCONP и PCLKSELх до запуска PLL не помогает.

Сообщение отредактировал GetSmart - Nov 2 2010, 02:50


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 2 2010, 06:25
Сообщение #6


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Не оказалось в конце прерывания строчки
Код
NVIC_ClearPendingIRQ(TIMER3_IRQn);

Когда она стоит, прерывания с нормальной частотой отрабатываются. А когда её нет, то видимо 2 раза подряд идёт залёт в прерывание. И если при первом залёте бит Pending устанавливался, то во втором залёте он автоматически сбрасывается. Странно всё это.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 28th June 2025 - 16:24
Рейтинг@Mail.ru


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