Перейти к содержанию
    

LPC2387

Здравствуйте

 

Вопрос по поводу установки клоков, значения 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 */  - здесь стоим.....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще-то

while ( ((PLLSTAT & (1 << 26)) == 0) );

и

while (!(PLLSTAT & 0x02000000));

не синонимы. Надо-бы:

while (!(PLLSTAT & 0x04000000));

 

У меня работает так:

 

        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)));

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще-то

while ( ((PLLSTAT & (1 << 26)) == 0) );

и

while (!(PLLSTAT & 0x02000000));

не синонимы. Надо-бы:

while (!(PLLSTAT & 0x04000000));

 

У меня работает так:

 

        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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для какого именна NXP это код??

 

U0FDR = 0x000000E5;    /* DIVADDVAL = 5, MULVAL = 8 */

Предпологаю, что в строке ошибочный коомент. MULVAL = 14, поэтому подсчеты ошибочны.

 

U1DLL = Fdiv % 256;

Попробуйте просто

U1DLL = Fdiv

 

Еще бы не плохо было бы явно настраивать рабочую частоту для модулей UART. Что бы точно было 72 MHz.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для какого именна 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

1.bmp

2.bmp

Изменено пользователем addi

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Резонатор на 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 как Ваша только без исправлений

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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для достижения 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 как Ваша только без исправлений

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????

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сапсибо за поддержку)

 

А если 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)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

К сожалению при

M = 9

N = 1

ClkDiv = 4

Fcco = 288 МГц

 

также получается 740000 вместо ожидаемых 921600(((.....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

К сожалению при

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_

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А куда Вы свои 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 МГц....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо большое за поддержку

Я пытаюсь разогнатся до 921600 для того чтобы по блютуш(WT32) принимать данные на 550 кб/с

Попробую разогнатся на 60 МГц), если конечно получится добится 60 МГц....

не вышло(((....

M = 225

N = 25

clkdiv= 5

рассчитывал на 60 , в итоге рассчитывается на 57600000

 

Сответственно получается для ЮАРТ:

 

DL = 3, DIV = 3, MUl = 10

 

Скорость та же(

 

чего та совсем не понятна как настраивать.....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно Вы всё настраиваете правильно, просто скорость большая.

Если есть возможность поставте кварц из серии 7372800/14745600 - для них точно можно будет подобрать M/N такими чтобы Fpclk/(16*baudrate) было целым числом. Тогда дробный делитель вообще не нужно будет использовать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно Вы всё настраиваете правильно, просто скорость большая.

Если есть возможность поставте кварц из серии 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

 

Огромное спасибо за поддержку :beer:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...