Lpc43xx uart baudrate calculation

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Lpc43xx uart baudrate calculation

1,150件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by JoeM on Thu Apr 23 00:03:08 MST 2015
Using an NGX Xplorer with Lpc4330 and driving Uart0 at 1 MBaud for some debug output.
Currently using Lpcopen 2.12 and Lpcxpresso.

Configuring Uart0 to 1 MBaud won't work because of a rounding error within the baudrate calculation in Chip_UART_SetBaud().

Originally Chip_UART_SetBaud() code:

uint32_t Chip_UART_SetBaud(LPC_USART_T* pUART, uint32_t baudrate) {
    uint32_t div, divh, divl, clkin;

    /* Determine UART clock in rate without FDR */
    clkin = Chip_Clock_GetRate(UART_BClock[Chip_UART_GetIndex(pUART)]);
    div = clkin / (baudrate * 16);

    /* High and low halves of the divider */
    divh = div / 256;
    divl = div - (divh * 256);

    Chip_UART_EnableDivisorAccess(pUART);
    Chip_UART_SetDivisorLatches(pUART, divl, divh);
    Chip_UART_DisableDivisorAccess(pUART);

    /* Fractional FDR alreadt setup for 1 in UART init */
    return clkin / div;
}


IMHO, the errornous part resists in the statement
    div = clkin / (baudrate * 16);

and changing that to something like this:
    tmp = baudrate * 16;
    div = (clkin + tmp/2) / tmp;

make it work for e.g. 921,6 kBaud and 1 MBaud.

But now, another colleague says that it better has to be changed to:
    tmp = baudrate * 16;
    div = (clkin + (tmp - 1)) / tmp;

What is the best / most correct way for calculating the Uart baudrate?

BTW: The errornous calculation can be found both in Lpcopen 2.12 and 2.16.
ラベル(1)
0 件の賞賛
返信
1 返信

887件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Thu Apr 23 00:47:47 MST 2015
These are just different ways of rounding the result of the division:
    tmp = baudrate * 16;
    div = (clkin + 0) / tmp;
always rounds down.
    tmp = baudrate * 16;
    div = (clkin + tmp/2) / tmp;
rounds to the nearest integer (IMHO best for your purpose).
    tmp = baudrate * 16;
    div = (clkin + tmp - 1) / tmp;
rounds up.
Rounding up or down may be useful if you need upper or lower bounds instead of a close approximation.

But you should do the math how much deviation from the true value you get and check whether that is precise enough for your application.
0 件の賞賛
返信