Set UART baud rate with UARTCLKDIV 

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Set UART baud rate with UARTCLKDIV 

2,795 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by drvrh on Thu Jul 23 01:25:04 MST 2015
Hello

In
this article is show how set baud rate for UART with UARTCLKDIV. From User manual I can't
set for 57600 baud rate.

What is difference between set baud rate with UARTCLKDIV and DLL DLM.

Labels (1)
0 Kudos
7 Replies

1,976 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Sat Aug 01 11:48:50 MST 2015

Quote: IanB
Whose idea were all these strange baud rates?


It started with 300 baud (at least that is the lowest I encountered in the early eighties, ignoring 1200/75 for BTX), on an acoustic coupler.
Then you start doubling it: 600, 1200, 2400, 4800, 9600, 19200, 38400 were all common baud rates for modems.
The ISDN phone system sends 8K samples of 8 bits per second, so it maxes out at 64Kbit/s, so you can't get 76800 over a phone line.  You can't get 64Kbit/s either on an analog phone because of the digital-to-analog-to-digital conversion. But you can get 57600 = 3 * 19200 if the line is good.
Continue doubling: 115200, ...
0 Kudos

1,976 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by IanB on Mon Jul 27 23:59:58 MST 2015
Yes, I should have included the +0.5 - I think the assembler works out the constants using floating point, so
SystemCoreClock/(16*baudrate) + 0.5 would have done the trick as well, but once the baud rate gets low enough and the divisor gets big enough the error is vanishingly small.
But watch out for those divisors which add an extra 1 (I think the A/D clock does that)

So everything also divides down from 48MHz pretty well (115200 is a divide by 26 with the same error), and all the other common values are factors of 115200 (9600 = 115200/12), so all have the same % error.


Whose idea were all these strange baud rates?
I remember the days of the 6850 UART when we had to buy a 4.915MHz crystal to generate the baud rates, and that crystal had no other use.
Now I mainly deal with MIDI (31250 baud) and DMX (250kbaud) both of which (sensibly) divide down exactly from both 12MHz and 16MHz
0 Kudos

1,976 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Mon Jul 27 03:10:51 MST 2015

Quote: drvrh
((SystemCoreClock)/ (16* baudrate))


This will always round down. It is better to round to the nearest integer, because that halves the maximal error:
((SystemCoreClock + 8 * baudrate) / (16 * baudrate))


BTW, 24MHz is a very nice clock frequency to get 115200 baud. The error is about 1/625 or 0.16%, because 25 * 25 = 26 * 24 + 1.  24000000 = 2^9 * 3 * 5^6 ~ 2^13 * 3^2 * 5^2 * 13 and 16 * 115200 = 2^13 * 3^2 * 5^2, so if you divide the 24MHz by 13 you get almost exactly the right UART sample frequency.

Isn't math fun?

Jürgen
0 Kudos

1,976 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by IanB on Sun Jul 26 23:41:54 MST 2015
The UART has another trap for the unwary. You can switch the FIFOs on or off.
If you switch them off, the UART doesn't work.

. . .  so why the option to switch them on and off?
0 Kudos

1,975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by drvrh on Sun Jul 26 22:45:49 MST 2015
Hello,
Now I'am using DLM and DLL..

void SerialInit(uint32_t baudrate){
//uint32_t DL;

LPC_IOCON->PIO1_7 &= ~0x07;
LPC_IOCON->PIO1_7 |= 0x01;                           /* UART TXD */
LPC_SYSCON -> SYSAHBCLKCTRL|= (1 << 12);
LPC_SYSCON -> UARTCLKDIV= 0x01;//
//DL = (SystemCoreClock * LPC_SYSCON -> SYSAHBCLKDIV)/(16 * baudrate * LPC_SYSCON -> UARTCLKDIV);
LPC_UART->LCR = 0x83;  //  8-bit character length, DLAB enable ( DLAB = 1)
LPC_UART->DLM = (((SystemCoreClock)/ (16* baudrate)) / (256));    //  Determines the baud rate of the UART (MSB Register)     (Access DLAB = 1)
LPC_UART->DLL = (((SystemCoreClock)/ (16* baudrate)) % (256));    //  Determines the baud rate of the UART (LSB Register)     (Access DLAB = 1)
LPC_UART->LCR = 0x03;  //  8-bit character length , DLAB disable ( DLAB = 0)
LPC_UART->FCR = 0x07;
}
//***************end function SerialInit *******************************************
0 Kudos

1,975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by IanB on Sun Jul 26 10:50:07 MST 2015
R3 contains LPC_UART_BASE, (0x40008000) but you'd already figured that out, hadn't you?
0 Kudos

1,975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by IanB on Sun Jul 26 10:48:13 MST 2015
It seems best to set UARTCLKDIV to 1.

Then this will set DLL and DLM
                LDR R2,=clockspeed/(baudrate*16)
                STRB R2,[R3,DLL]
                LSRS R2,R2,#8
                STR R2,[R3,DLM]

Assuming you have the clock via the PLL running at 48MHz then  for 57600 baud it gives DLL=52, DLM=0 and a real baud rate of 57692 baud. Because the UART resynchronises every start bit, anything that's less than half a bit out in 10 bits will work!

10 bits at 57600 baud = 173.6µs
10 bits at 57692 baud = 173.3µs

300ns out on a bit time of 17.3µs is not going to be a problem.

However, if you want to use a lower clock speed, things might get trickier and you might have to use the fractional divider.
0 Kudos