|
LPC2387, PLLSTAT |
|
|
|
Feb 24 2011, 04:46
|
Знающий
   
Группа: Участник
Сообщений: 679
Регистрация: 9-08-06
Пользователь №: 19 422

|
Здравствуйте Вопрос по поводу установки клоков, значения PLLCFG не отражаются в PLLSTAT, исполнение виснет на проверки соответствующего бита Может кто скалкиваоя, прошу помочь Код void ConfigurePLL ( void ) { DWORD MValue, NValue;
if ( PLLSTAT & (1 << 25) ) { PLLCON = 1; /* Enable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55; }
PLLCON = 0; /* Disable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55; SCS |= 0x20; /* Enable main OSC */ while( !(SCS & 0x40) ); /* Wait until main OSC is usable */
CLKSRCSEL = 0x1; /* select main OSC, 16MHz, as the PLL clock source */
PLLCFG = PLL_MValue | (PLL_NValue << 16); PLLFEED = 0xaa; PLLFEED = 0x55; PLLCON = 1; /* Enable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55;
CCLKCFG = CCLKDivValue; /* Set clock divider */ #if USE_USB USBCLKCFG = USBCLKDivValue; /* usbclk = 288 MHz/6 = 48 MHz */ #endif //while ( ((PLLSTAT & (1 << 26)) == 0) ); /* Check lock bit status */ while (!(PLLSTAT & 0x02000000)); /* Check lock bit status */ - здесь стоим.....
|
|
|
|
|
 |
Ответов
(1 - 13)
|
Feb 26 2011, 08:26
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
Вообще-то while ( ((PLLSTAT & (1 << 26)) == 0) ); и while (!(PLLSTAT & 0x02000000)); не синонимы. Надо-бы: while (!(PLLSTAT & 0x04000000)); У меня работает так: CODE m_val = 0x0B; n_val = 0; do { stat_value = PLLSTAT; } while (((stat_value & 0x00007FFF) != m_val) || (((stat_value & 0x00FF0000) >> 16) != n_val) || !(stat_value & (1 << 26)));
|
|
|
|
|
Mar 20 2011, 11:33
|
Знающий
   
Группа: Участник
Сообщений: 679
Регистрация: 9-08-06
Пользователь №: 19 422

|
Цитата(Axel @ Feb 26 2011, 11:26)  Вообще-то while ( ((PLLSTAT & (1 << 26)) == 0) ); и while (!(PLLSTAT & 0x02000000)); не синонимы. Надо-бы: while (!(PLLSTAT & 0x04000000)); У меня работает так: CODE m_val = 0x0B; n_val = 0; do { stat_value = PLLSTAT; } while (((stat_value & 0x00007FFF) != m_val) || (((stat_value & 0x00FF0000) >> 16) != n_val) || !(stat_value & (1 << 26))); никак не могу добится нужного бодрейта на ЮАРТе, делаю все как написано, получается погрешность почти в 20% 16Мгц резонатор, хочу чтобы было 72Мгц и 921600, реальна получается гдето 740000 Настройка колоков: /* Fcck = 72Mhz */ #define PLL_MValue 8 #define PLL_NValue 0 #define CCLKDivValue 4 /* System configuration: Fosc, Fcclk, Fcco, Fpclk must be defined */ /* PLL input Crystal frequence range 4KHz~20MHz. */ #define Fosc 16000000 /* System frequence,should be less than 72MHz. */ #define Fcclk 72000000 #define Fcco 288000000 #define Fpclk (Fcclk / 1) Код void ConfigurePLL ( void ) { DWORD MValue, NValue;
if ( PLLSTAT & (1 << 25) ) { PLLCON = 1; /* Enable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55; }
PLLCON = 0; /* Disable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55; SCS |= 0x20; /* Enable main OSC */ while( !(SCS & 0x40) ); /* Wait until main OSC is usable */
CLKSRCSEL = 0x1; /* select main OSC, 16MHz, as the PLL clock source */
PLLCFG = PLL_MValue | (PLL_NValue << 16); PLLFEED = 0xaa; PLLFEED = 0x55; PLLCON = 1; /* Enable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55;
CCLKCFG = CCLKDivValue; /* Set clock divider */ #if USE_USB USBCLKCFG = USBCLKDivValue; /* usbclk = 288 MHz/6 = 48 MHz */ #endif
//while ( ((PLLSTAT & (1 << 26)) == 0) ); /* Check lock bit status */ while (!(PLLSTAT & 0x04000000)); /* Check lock bit status */
MValue = PLLSTAT & 0x00007FFF; NValue = (PLLSTAT & 0x00FF0000) >> 16; while ((MValue != PLL_MValue) && ( NValue != PLL_NValue) );
PLLCON = 3; /* enable and connect */ PLLFEED = 0xaa; PLLFEED = 0x55; //while ( ((PLLSTAT & (1 << 25)) == 0) ); /* Check connect bit status */ while (!(PLLSTAT & 0x07000000)); /* Check lock bit status */ return; } настройка ЮАРТа Код DWORD UARTInit( DWORD PortNum, DWORD baudrate ) { DWORD Fdiv; // PortNum = 0 ; // if ( PortNum == 0 ) // { PINSEL0 = 0x00000050; /* RxD0 and TxD0 */
U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ Fdiv = ( Fpclk / 16 ) / baudrate; /*baud rate */ //U0DLM = Fdiv / 256; //U0DLL = Fdiv % 256; // more accurate settings U0DLM = 0; U0DLL = 3; U0FDR = 0x000000E5; /* DIVADDVAL = 5, MULVAL = 8 */ U0LCR = 0x03; /* DLAB = 0 */ U0FCR = 0x07; /* Enable and reset TX and RX FIFO. */ /* if ( install_irq( UART0_INT, (void *)UART0Handler, HIGHEST_PRIORITY ) == FALSE ) { return (FALSE); } */ U0IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART0 interrupt */ return (TRUE); /* } else if ( PortNum == 1 ) { #if EA_BOARD_LPC24XX PINSEL7 |= 0x0000000F; // P3.16 TXD1, P3.17 RXD1 #else // Default is Keil MCB2300 board PINSEL0 |= 0x40000000; // Enable TxD1 P0.15 PINSEL1 |= 0x00000001; // Enable RxD1 P0.16 #endif U1LCR = 0x83; // 8 bits, no Parity, 1 Stop bit Fdiv = ( Fpclk / 16 ) / baudrate; //baud rate U1DLM = Fdiv / 256; U1DLL = Fdiv % 256; U1LCR = 0x03; // DLAB = 0 U1FCR = 0x07; // Enable and reset TX and RX FIFO.
if ( install_irq( UART1_INT, (void *)UART1Handler, HIGHEST_PRIORITY ) == FALSE ) { return (FALSE); } U1IER = IER_RBR | IER_THRE | IER_RLS; // Enable UART0 interrupt return (TRUE); } */ //return( FALSE ); } прощу помочь разобратся что не так, с NXP первый раз....
Сообщение отредактировал addi - Mar 20 2011, 11:36
|
|
|
|
|
Mar 22 2011, 06:08
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 31-08-10
Из: Минск-Витебск
Пользователь №: 59 203

|
Для какого именна NXP это код?? Код U0FDR = 0x000000E5; /* DIVADDVAL = 5, MULVAL = 8 */ Предпологаю, что в строке ошибочный коомент. MULVAL = 14, поэтому подсчеты ошибочны. Код U1DLL = Fdiv % 256; Попробуйте просто Код U1DLL = Fdiv Еще бы не плохо было бы явно настраивать рабочую частоту для модулей UART. Что бы точно было 72 MHz.
|
|
|
|
|
Mar 22 2011, 08:52
|
Знающий
   
Группа: Участник
Сообщений: 679
Регистрация: 9-08-06
Пользователь №: 19 422

|
Цитата(yashok @ Mar 22 2011, 09:08)  Для какого именна NXP это код?? Код U0FDR = 0x000000E5; /* DIVADDVAL = 5, MULVAL = 8 */ Предпологаю, что в строке ошибочный коомент. MULVAL = 14, поэтому подсчеты ошибочны. Код U1DLL = Fdiv % 256; Попробуйте просто Код U1DLL = Fdiv Еще бы не плохо было бы явно настраивать рабочую частоту для модулей UART. Что бы точно было 72 MHz. Спасибо за поддержку Запутался в версиях кода, как следствие U0FDR был указан для 60 МГц Изначально Резонатор на 16 МГц Необходимо сделать 72МГц частоту тактирования ядра и периферии Получается M = 72 N = 8 ClkDiv = 4 для Fcco = 288 МГц Необходимый бодрейт - 921600 б/с Тогда DIVADDVAL = 5, MULVAL = 8 В итоге получается в районе 740000 б/с при передачи и соотвественно прием на 921600 б/с передатчика заершается с ошибками фрейма Почитал эррату, там говорится что желательно 72 МГц добиватся при 12 МГц на входе и Fcco = 288 МГц В итоге настроил какбы на 12 Мгц(при оставшемся кварце 16 Мгц) - M = 12, N = 1, получается теперь почти как нада, дительность бита как на картинке 1 Но прием попрежнему с ошибками, длительность бита передатчика на рис 2 Микроконтролер LPC2387
Сообщение отредактировал addi - Mar 22 2011, 12:17
Прикрепленные файлы
1.bmp ( 146.3 килобайт )
Кол-во скачиваний: 6
2.bmp ( 146.3 килобайт )
Кол-во скачиваний: 4
|
|
|
|
|
Mar 22 2011, 09:36
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(addi @ Mar 22 2011, 12:52)  Резонатор на 16 МГц Необходимо сделать 72МГц частоту тактирования ядра и периферии
Микроконтролер LPC2387 Для достижения Fcclk=72MHz при Fosc=16MHz параметры PLL должны быть такие: (при условии что используется USB) Код #define PLL_MValue 17 //(16MHz*18 = 288MHz) #define PLL_NValue 0 #define CCLKDivValue 3 // 288/4=72MHz #define USBCLKDivValue 5 Процедура инициализации PLL взята из примера и 1 в 1 как Ваша только без исправлений CODE void ConfigurePLL ( void ) { unsigned int MValue, NValue;
if ( PLLSTAT & (1 << 25) ) { PLLCON = 1; /* Enable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55; }
PLLCON = 0; /* Disable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55;
SCS |= 0x20; /* Enable main OSC */ while( !(SCS & 0x40) ); /* Wait until main OSC is usable */
CLKSRCSEL = 0x1; /* select main OSC, 12MHz, as the PLL clock source */
PLLCFG = PLL_MValue | (PLL_NValue << 16); PLLFEED = 0xaa; PLLFEED = 0x55;
PLLCON = 1; /* Enable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55;
CCLKCFG = CCLKDivValue; /* Set clock divider */ #if USE_USB USBCLKCFG = USBCLKDivValue; /* usbclk = 288 MHz/6 = 48 MHz */ #endif
while ( ((PLLSTAT & (1 << 26)) == 0) ); /* Check lock bit status */
MValue = PLLSTAT & 0x00007FFF; NValue = (PLLSTAT & 0x00FF0000) >> 16; while ((MValue != PLL_MValue) && ( NValue != PLL_NValue) );
PLLCON = 3; /* enable and connect */ PLLFEED = 0xaa; PLLFEED = 0x55; while ( ((PLLSTAT & (1 << 25)) == 0) ); /* Check connect bit status */ return; } Процедура инициализации USART1, тоже взята из примера, работает в широком диапазоне baudrate Код //------------------------------------------- //константа определена в target.h #define Fcclk = 72000000 //-------------------------------------------
//------------------------------------------- //параметры uart #define CHL_5 (0ul<<0) //длина символа #define CHL_6 (1ul<<0) #define CHL_7 (2ul<<0) #define CHL_8 (3ul<<0)
#define STOP_1 (0ul<<2) //кол-во стоповых бит #define STOP_2 (1ul<<2)
#define PAR_OFF (0ul<<3) //контроль чётности #define PAR_ON (1ul<<3)
#define DLC_ENA (1ul<<7) //разрешение доступа к Divisor Latch //-------------------------------------------
void UART1_init( unsigned int baudrate ) { //разрешаем переферийное питание uart3 PCONP |= (1ul<<4); //определяем делитель тактовой частоты uart3 PCLKSEL0 |= (2ul<<8); //делитель на 2
//выбираем альтернативные ф-ии выводов PINSEL4 |= (2ul<<0)|(2ul<<2); /* RxD1 and TxD1 */ unsigned int Fdiv; U1LCR = DLC_ENA|STOP_1|CHL_8; /* 8 bits, no Parity, 1 Stop bit */ Fdiv = ( (Fcclk/2) / 16) / baudrate; /*baud rate */ U1DLM = Fdiv / 256; U1DLL = Fdiv % 256; U1LCR = STOP_1|CHL_8; /* 8 bits, no Parity, 1 Stop bit */ U1FCR = FIFO_LEV_0|RES_TX_FIFO|RES_RX_FIFO|FIFO_ENA; /* Enable and reset TX and RX FIFO. */
//инсталлируем обработчик прерываний install_irq( UART1_INT, (void *)UART1_Handler, HIGHEST_PRIORITY );
U1IER = IER_RBR | IER_RLS; /* Enable UART0 interrupt */ } По-поводу Fcclk процессора - разве в lpc23xx она не ограничена 60MHz? Сам работаю с lpc2368 - читал доки там вроде такое ограничение. Вот lpc24xx точно могут работать на 72MHz.
|
|
|
|
|
Mar 22 2011, 12:27
|
Знающий
   
Группа: Участник
Сообщений: 679
Регистрация: 9-08-06
Пользователь №: 19 422

|
Цитата(mempfis_ @ Mar 22 2011, 12:36)  Для достижения Fcclk=72MHz при Fosc=16MHz параметры PLL должны быть такие: (при условии что используется USB) Код #define PLL_MValue 17 //(16MHz*18 = 288MHz) #define PLL_NValue 0 #define CCLKDivValue 3 // 288/4=72MHz #define USBCLKDivValue 5 Процедура инициализации PLL взята из примера и 1 в 1 как Ваша только без исправлений CODE void ConfigurePLL ( void ) { unsigned int MValue, NValue;
if ( PLLSTAT & (1 << 25) ) { PLLCON = 1; /* Enable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55; }
PLLCON = 0; /* Disable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55;
SCS |= 0x20; /* Enable main OSC */ while( !(SCS & 0x40) ); /* Wait until main OSC is usable */
CLKSRCSEL = 0x1; /* select main OSC, 12MHz, as the PLL clock source */
PLLCFG = PLL_MValue | (PLL_NValue << 16); PLLFEED = 0xaa; PLLFEED = 0x55;
PLLCON = 1; /* Enable PLL, disconnected */ PLLFEED = 0xaa; PLLFEED = 0x55;
CCLKCFG = CCLKDivValue; /* Set clock divider */ #if USE_USB USBCLKCFG = USBCLKDivValue; /* usbclk = 288 MHz/6 = 48 MHz */ #endif
while ( ((PLLSTAT & (1 << 26)) == 0) ); /* Check lock bit status */
MValue = PLLSTAT & 0x00007FFF; NValue = (PLLSTAT & 0x00FF0000) >> 16; while ((MValue != PLL_MValue) && ( NValue != PLL_NValue) );
PLLCON = 3; /* enable and connect */ PLLFEED = 0xaa; PLLFEED = 0x55; while ( ((PLLSTAT & (1 << 25)) == 0) ); /* Check connect bit status */ return; } Процедура инициализации USART1, тоже взята из примера, работает в широком диапазоне baudrate Код //------------------------------------------- //константа определена в target.h #define Fcclk = 72000000 //-------------------------------------------
//------------------------------------------- //параметры uart #define CHL_5 (0ul<<0) //длина символа #define CHL_6 (1ul<<0) #define CHL_7 (2ul<<0) #define CHL_8 (3ul<<0)
#define STOP_1 (0ul<<2) //кол-во стоповых бит #define STOP_2 (1ul<<2)
#define PAR_OFF (0ul<<3) //контроль чётности #define PAR_ON (1ul<<3)
#define DLC_ENA (1ul<<7) //разрешение доступа к Divisor Latch //-------------------------------------------
void UART1_init( unsigned int baudrate ) { //разрешаем переферийное питание uart3 PCONP |= (1ul<<4); //определяем делитель тактовой частоты uart3 PCLKSEL0 |= (2ul<<8); //делитель на 2
//выбираем альтернативные ф-ии выводов PINSEL4 |= (2ul<<0)|(2ul<<2); /* RxD1 and TxD1 */ unsigned int Fdiv; U1LCR = DLC_ENA|STOP_1|CHL_8; /* 8 bits, no Parity, 1 Stop bit */ Fdiv = ( (Fcclk/2) / 16) / baudrate; /*baud rate */ U1DLM = Fdiv / 256; U1DLL = Fdiv % 256; U1LCR = STOP_1|CHL_8; /* 8 bits, no Parity, 1 Stop bit */ U1FCR = FIFO_LEV_0|RES_TX_FIFO|RES_RX_FIFO|FIFO_ENA; /* Enable and reset TX and RX FIFO. */
//инсталлируем обработчик прерываний install_irq( UART1_INT, (void *)UART1_Handler, HIGHEST_PRIORITY );
U1IER = IER_RBR | IER_RLS; /* Enable UART0 interrupt */ } По-поводу Fcclk процессора - разве в lpc23xx она не ограничена 60MHz? Сам работаю с lpc2368 - читал доки там вроде такое ограничение. Вот lpc24xx точно могут работать на 72MHz. Сапсибо за поддержку) А если USB не используется всеравно надо настраивать как на использования для достижения 72Мгц при 16 Мгц на входе? и еще хотел спросить почему "#define CCLKDivValue 3 // 288/4=72MHz"???, вроде 4 получается или слесь необходимо надо непосредственно в регистр записывать "расчитанное значение"-1, как в случае UDLL+UDLM -> M-1, N-1????
|
|
|
|
|
Mar 22 2011, 13:16
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(addi @ Mar 22 2011, 15:27)  Сапсибо за поддержку)
А если USB не используется всеравно надо настраивать как на использования для достижения 72Мгц при 16 Мгц на входе? и еще хотел спросить почему "#define CCLKDivValue 3 // 288/4=72MHz"???, вроде 4 получается или слесь необходимо надо непосредственно в регистр записывать "расчитанное значение"-1, как в случае UDLL+UDLM -> M-1, N-1???? Я Вам немного наврал. Согласно формуле FCCO = (2 × M × FIN) / N PLL_MValue = 8 (т.е. 9-1) PLL_NValue = 0 (т.е. 1-1) В результате FCCO = 2*9*16/1=288MHz Всё это написано в Chapter 4 User Manual стр 52 Для USB необходима максимально близкая к 48 MHz частота. Поэтому подходят не все PLL_MValue и PLL_NValue т.к. тактирование USB берётся из FCCO делённой на делитель USB. Если USB не планируете использовать то можете настроить FCCO каки-угодно (с учётом ограничений PLL)
|
|
|
|
|
Mar 22 2011, 14:24
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(addi @ Mar 22 2011, 17:48)  К сожалению при M = 9 N = 1 ClkDiv = 4 Fcco = 288 МГц
также получается 740000 вместо ожидаемых 921600(((..... А куда Вы свои 921600 пытаетесь отправить? И через что (мах232 или ftdi)? Не пробовали заводить уарт на 115200 или другом стандартном boadrate? Может быть Ваше железо просто не тянет такой поток. Вы уверены что точно установили частоту ? Попробуйте подать на уарт частоту пониже напр Fcclk/2 (PCLKSEL0 |= (2ul<<8); //делитель на 2) p.s. нашёл в эррате пункт 3.14 Flash.1: Operating speed out of on-chip flash is restricted в котором указано что мах. частота работы из flash ограничена в 60MHz вместо заявленных 72. Проверьте ревизию своего чипа.
Сообщение отредактировал mempfis_ - Mar 22 2011, 14:58
|
|
|
|
|
Mar 22 2011, 17:28
|
Знающий
   
Группа: Участник
Сообщений: 679
Регистрация: 9-08-06
Пользователь №: 19 422

|
Цитата(mempfis_ @ Mar 22 2011, 17:24)  А куда Вы свои 921600 пытаетесь отправить? И через что (мах232 или ftdi)? Не пробовали заводить уарт на 115200 или другом стандартном boadrate? Может быть Ваше железо просто не тянет такой поток.
Вы уверены что точно установили частоту ? Попробуйте подать на уарт частоту пониже напр Fcclk/2 (PCLKSEL0 |= (2ul<<8); //делитель на 2)
p.s. нашёл в эррате пункт 3.14 Flash.1: Operating speed out of on-chip flash is restricted в котором указано что мах. частота работы из flash ограничена в 60MHz вместо заявленных 72. Проверьте ревизию своего чипа. Спасибо большое за поддержку Я пытаюсь разогнатся до 921600 для того чтобы по блютуш(WT32) принимать данные на 550 кб/с Попробую разогнатся на 60 МГц), если конечно получится добится 60 МГц....
|
|
|
|
|
Mar 23 2011, 04:42
|
Знающий
   
Группа: Участник
Сообщений: 679
Регистрация: 9-08-06
Пользователь №: 19 422

|
Цитата(addi @ Mar 22 2011, 20:28)  Спасибо большое за поддержку Я пытаюсь разогнатся до 921600 для того чтобы по блютуш(WT32) принимать данные на 550 кб/с Попробую разогнатся на 60 МГц), если конечно получится добится 60 МГц.... не вышло(((.... M = 225 N = 25 clkdiv= 5 рассчитывал на 60 , в итоге рассчитывается на 57600000 Сответственно получается для ЮАРТ: DL = 3, DIV = 3, MUl = 10 Скорость та же( чего та совсем не понятна как настраивать.....
|
|
|
|
|
Mar 25 2011, 04:16
|
Знающий
   
Группа: Участник
Сообщений: 679
Регистрация: 9-08-06
Пользователь №: 19 422

|
Цитата(mempfis_ @ Mar 23 2011, 12:13)  Возможно Вы всё настраиваете правильно, просто скорость большая. Если есть возможность поставте кварц из серии 7372800/14745600 - для них точно можно будет подобрать M/N такими чтобы Fpclk/(16*baudrate) было целым числом. Тогда дробный делитель вообще не нужно будет использовать. наконецта все получилось) Нада быдл все сделать согласно errata) поставить 12 Мгц от него получить 60 Мгц при Fcco = 288 Мгц M = 12, N = 1, clkdiv = 4 Для 921600 необходимо чтобы DL = 3, DIV = 5, MUL = 14 Огромное спасибо за поддержку
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|