Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: baud rate uart LPC2148
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Ave
Кто может подсказать калькулятор расчета скорости UART для LPC2148.
Ни как не могу найти сайт.
kovigor
Цитата(Ave @ Jun 19 2013, 17:07) *
Кто может подсказать калькулятор расчета скорости UART для LPC2148.

От калькулятора вреда больше, чем пользы. Скорость там задается довольно просто. Разобраться с этим необходимо лично, иначе вы не сможете разобраться с самим UART ...
KRS
Так в User Manual есть раздел baud rate calculation, там блоксхема есть как считать.
Ну и для стандартных частот готовые данные есть.
haker_fox
QUOTE (KRS @ Jun 20 2013, 02:43) *
Так в User Manual есть раздел baud rate calculation, там блоксхема есть как считать.
Ну и для стандартных частот готовые данные есть.
Ага, в некоторых проектах вообще стал задавать частоту константой, а от неё по формулам считать модулям их частоты. Очень удобно. Без препроцессора)
jcxz
Цитата(haker_fox @ Jun 20 2013, 13:16) *
Ага, в некоторых проектах вообще стал задавать частоту константой, а от неё по формулам считать модулям их частоты. Очень удобно. Без препроцессора)

Ну вообще-то только так и надо делать. В моих проектах все частоты (UART, SPI и т.п.) задаются дефайнами, от которых макросами рассчитываются необходимые делители, прескалеры, делители PCLK и пр.
Если данную частоту невозможно обеспечить физически, принимается ближайшая большая/меньшая или выводится #error компиляции (по ситуации).
Для смены частоты тогда достаточно изменить одно число.
KRS
Цитата(jcxz @ Jun 20 2013, 11:40) *
задаются дефайнами, от которых макросами рассчитываются необходимые делители, прескалеры, делители

А Вы можете привести пример такого макроса для дробного делителя LPC UART?
andrewlekar
Макросом дробный делитель сложновато считать. У меня кодом считается при необходимости:

CODE
#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
KRS
Цитата(andrewlekar @ Jun 20 2013, 12:33) *
Макросом дробный делитель сложновато считать. У меня кодом считается при необходимости:

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

Цитата(jcxz @ Jun 20 2013, 11:40) *
В моих проектах все частоты (UART, SPI и т.п.) задаются дефайнами, от которых макросами рассчитываются необходимые делители, прескалеры, делители PCLK и пр.
Если данную частоту невозможно обеспечить физически, принимается ближайшая большая/меньшая или выводится #error компиляции (по ситуации).


вот и интересен пример такого макроса для этого вида UART
jcxz
Цитата(KRS @ Jun 20 2013, 15:54) *
С кодом то понятно, просто jcxz утверждает, что ВСЕ прескалеры макросами получаются.
Может есть какой то "красивый" способ.

Нет. Сейчас глянул - освежил в памяти - для UART я макросом не стал делать, сделал обычной функцией в рантайм - действительно слишком сложно. Оостальные - SPI, I2C и т.п. макросами
cool.gif
haker_fox
QUOTE (jcxz @ Jun 20 2013, 16:40) *
Ну вообще-то только так и надо делать. В моих проектах все частоты (UART, SPI и т.п.) задаются дефайнами, от которых макросами рассчитываются необходимые делители, прескалеры, делители PCLK и пр.

Нет, Вы меня не правильно поняли rolleyes.gif Когда я написал формулами и без препроцессора, я подразумевал, что всё считается в коде, как показал andrewlekar Места в нынешних контроллерах до фига, смысла экономить на спичках нет rolleyes.gif
Ave
Спасибо за ответы.
Не обязательно что калькуляторы ошибочные.
Был сайт с калькулятором где можно было задать частоту и необходимую скорость обмена все работало.
Сейчас не могу вспомнить где он был.
Взял программу по расчету скорости UART. Настроил UART до скорости 480600 частота 24МГц.
Но 921600 никак не хочет синхронизироваться.
jcxz
А Вы умножьте 921600*16 сравните результат с 24МГц, посмотрите ещё на частоту PCLK для данного UART и подумайте почему.
Ave
Умножение 16 * 921600 = 14 745 600 что меньше 24 000 000.
jcxz
Цитата(Ave @ Jun 21 2013, 12:40) *
Умножение 16 * 921600 = 14 745 600 что меньше 24 000 000.

Но очень близко и очень плохо делится. Попробуйте увеличить частоту процессора и проверить. Если заведётся - проблема в этом.
У меня при 100МГц CPU прекрасно работает 921600
И какая у Вас PCLK?
Ave
Частота кварца 12 000 000
Частота процессора 48 000 000
Частота переферии 24 000 000

toweroff
Цитата(jcxz @ Jun 21 2013, 14:56) *
У меня при 100МГц CPU

у этой каменюки 60МГц максимум
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.