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

Кто может подсказать калькулятор расчета скорости UART для LPC2148.

Ни как не могу найти сайт.

 

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


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

Кто может подсказать калькулятор расчета скорости UART для LPC2148.

От калькулятора вреда больше, чем пользы. Скорость там задается довольно просто. Разобраться с этим необходимо лично, иначе вы не сможете разобраться с самим UART ...

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


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

Так в User Manual есть раздел baud rate calculation, там блоксхема есть как считать.

Ну и для стандартных частот готовые данные есть.

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


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

Так в User Manual есть раздел baud rate calculation, там блоксхема есть как считать.

Ну и для стандартных частот готовые данные есть.

Ага, в некоторых проектах вообще стал задавать частоту константой, а от неё по формулам считать модулям их частоты. Очень удобно. Без препроцессора)

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


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

Ага, в некоторых проектах вообще стал задавать частоту константой, а от неё по формулам считать модулям их частоты. Очень удобно. Без препроцессора)

Ну вообще-то только так и надо делать. В моих проектах все частоты (UART, SPI и т.п.) задаются дефайнами, от которых макросами рассчитываются необходимые делители, прескалеры, делители PCLK и пр.

Если данную частоту невозможно обеспечить физически, принимается ближайшая большая/меньшая или выводится #error компиляции (по ситуации).

Для смены частоты тогда достаточно изменить одно число.

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


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

задаются дефайнами, от которых макросами рассчитываются необходимые делители, прескалеры, делители

А Вы можете привести пример такого макроса для дробного делителя LPC UART?

 

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


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

Макросом дробный делитель сложновато считать. У меня кодом считается при необходимости:

 

#ifdef USE_CALC_FRACTIONAL_DIVIDER

//расчёт дробного делителя UART для минимизации процента ошибок.
//19200 и 115200 позволяет использовать с 0 ошибкой для кварца 11,0592.
static void uart_calc_divisors(uint_fast32_t baudrate, int *pDiv, int *pAddDiv, int *pMul, int *error)
{
uint_fast32_t uClk;
uint_fast32_t calcBaudrate = 0;
uint_fast32_t temp = 0;

int mulFracDiv, dividerAddFracDiv;
int diviser = 0;
int mulFracDivOptimal = 1;
int dividerAddOptimal = 0;
int diviserOptimal = 0;

int relativeError = 0;
int relativeOptimalError = 10000;

uClk = CPU_PERIPH_CLOCK >> 4; // div by 16
// In the Uart IP block, baud rate is calculated using FDR and DLL-DLM registers
// The formula is :
// BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL)
// It involves floating point calculations. That's the reason the formulae are adjusted with
// Multiply and divide method.
// The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions:
// 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15
for (mulFracDiv = 1; mulFracDiv <= 15;mulFracDiv++)
{
for (dividerAddFracDiv = 0; dividerAddFracDiv <= 15;dividerAddFracDiv++)
{
  temp = (mulFracDiv * uClk) / ((mulFracDiv + dividerAddFracDiv));

  diviser = temp / baudrate;
  if ((temp % baudrate) > (baudrate / 2))
	diviser++;

  if ((diviser > 2) && (diviser < 65536))
  {
	calcBaudrate = temp / diviser;

	if (calcBaudrate <= baudrate)
	  relativeError = baudrate - calcBaudrate;
	else
	  relativeError = calcBaudrate - baudrate;

	if ((relativeError < relativeOptimalError))
	{
	  mulFracDivOptimal = mulFracDiv;
	  dividerAddOptimal = dividerAddFracDiv;
	  diviserOptimal = diviser;
	  relativeOptimalError = relativeError;
	  if (relativeError == 0)
		break;
	}
  }
}
if (relativeError == 0)
  break;
}

	*pDiv = diviserOptimal;
	*pAddDiv = dividerAddOptimal;
	*pMul = mulFracDivOptimal;
	*error = relativeOptimalError;
}
#else   //!USE_CALC_FRACTIONAL_DIVIDER

 //UART baudrate formula : PCLK / (16 * UART1_MAIN_DIV * (1 + (FRACTIONAL_UART1_DIV / FRACTIONAL_UART1_MUL)))

 //For 11.0592 MHz , CCLK = 99532800, PCLK = 24883200

 //Baudrate = 115200
 #if (UART1_BAUDRATE == 115200)
#define FRACTIONAL_UART1_DIV	  1
#define FRACTIONAL_UART1_MUL	  2
#define UART1_MAIN_DIV			9
 #endif

 //Baudrate = 19200
 #if (UART1_BAUDRATE == 19200)
#define FRACTIONAL_UART1_DIV	  0
#define FRACTIONAL_UART1_MUL	  1
#define UART1_MAIN_DIV			81
 #endif

 //wrong baudrate
 #if ((UART1_BAUDRATE != 115200) && (UART1_BAUDRATE != 19200))
#error  "Wrong UART1 baudrate"
 #endif

#endif  //USE_CALC_FRACTIONAL_DIVIDER

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

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


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

Макросом дробный делитель сложновато считать. У меня кодом считается при необходимости:

С кодом то понятно, просто jcxz утверждает, что ВСЕ прескалеры макросами получаются.

Может есть какой то "красивый" способ.

 

В моих проектах все частоты (UART, SPI и т.п.) задаются дефайнами, от которых макросами рассчитываются необходимые делители, прескалеры, делители PCLK и пр.

Если данную частоту невозможно обеспечить физически, принимается ближайшая большая/меньшая или выводится #error компиляции (по ситуации).

 

вот и интересен пример такого макроса для этого вида UART

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


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

С кодом то понятно, просто jcxz утверждает, что ВСЕ прескалеры макросами получаются.

Может есть какой то "красивый" способ.

Нет. Сейчас глянул - освежил в памяти - для UART я макросом не стал делать, сделал обычной функцией в рантайм - действительно слишком сложно. Оостальные - SPI, I2C и т.п. макросами

B)

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


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

Ну вообще-то только так и надо делать. В моих проектах все частоты (UART, SPI и т.п.) задаются дефайнами, от которых макросами рассчитываются необходимые делители, прескалеры, делители PCLK и пр.

Нет, Вы меня не правильно поняли :rolleyes: Когда я написал формулами и без препроцессора, я подразумевал, что всё считается в коде, как показал andrewlekar Места в нынешних контроллерах до фига, смысла экономить на спичках нет :rolleyes:

 

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


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

Спасибо за ответы.

Не обязательно что калькуляторы ошибочные.

Был сайт с калькулятором где можно было задать частоту и необходимую скорость обмена все работало.

Сейчас не могу вспомнить где он был.

Взял программу по расчету скорости UART. Настроил UART до скорости 480600 частота 24МГц.

Но 921600 никак не хочет синхронизироваться.

 

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


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

А Вы умножьте 921600*16 сравните результат с 24МГц, посмотрите ещё на частоту PCLK для данного UART и подумайте почему.

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


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

Умножение 16 * 921600 = 14 745 600 что меньше 24 000 000.

Но очень близко и очень плохо делится. Попробуйте увеличить частоту процессора и проверить. Если заведётся - проблема в этом.

У меня при 100МГц CPU прекрасно работает 921600

И какая у Вас PCLK?

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


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

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...