From: da_wils on
Hi,

I'm making a uart that will run at the standard baud rates and have a
bit of a query,
My board has a 50Mhz clk so I've used this to create a 1.8432Mhz clock
then derive all the baud clocks from it,,eg,
-- 50mhz/ 1843200 = 27.1267
-- 13 bit acc = 4096 msb
-- divided by 151
-- 4096/151 = 27.1258 -- close enough
-- gives 1.843262MHz clock

this is fine for TX but when it comes to RX where the accepted sample
clk is 16x the baud rate I hit a few problems. I wanted to sample the
incoming bit period at 4 16x clocks, 8 16x clocks and 12 16x clock and
use the theory that if two samples match then RX bit is good, It's
this generation of a 16x clock that is causing me problems, not easy
to create for all baud rates. At the moment I'm sampling the RX at
50MHz and taking samples at three points, this scheme works but seems
a bit inefficient due to having to have a bank of constants with the
the various count values for different baud rates.

Has anyone come across this problem ?
From: glen herrmannsfeldt on
da_wils(a)hotmail.com wrote:

> I'm making a uart that will run at the standard baud rates and have a
> bit of a query,
> My board has a 50Mhz clk so I've used this to create a 1.8432Mhz clock
> then derive all the baud clocks from it,,eg,
> -- 50mhz/ 1843200 = 27.1267
> -- 13 bit acc = 4096 msb
> -- divided by 151
> -- 4096/151 = 27.1258 -- close enough
> -- gives 1.843262MHz clock

I believe that off by 1% is considered close enough.

The ones that are usually a little off are 110 baud
(for ASR33s) and 134.48 (for IBM 2741s).
As you can see, getting exactly 134.48 isn't easy with
any divider and normal crystal frequency.

I believe tradition is to sample in the middle of the
incoming bit time, but sampling more and combining them
in some way doesn't sound bad.

As well as I remember it, when you see the start bit then
you wait 1/2 bit time (8 cycles of 16x), then check to be
sure the start bit is still there. If not, then it is
just noise. (Currently popular modems probably won't
do that, but FSK modems, like the 103, can easily do that.)

If the start bit is good, then accumulate bits every
16 clock cycles. The 16x clock gives you a 6% tolerance
on where you see the start bit edge. That is the reason
for the 16x clock. (Higher would be better, and I have
known some that will do 64x.)

An important part of asynchronous communication is that
it resynchs on the start bit for each character. If the
clock is a little off, the error accumulates over each
character, but not between characters.

-- glen
From: David Brown on
On 26/03/2010 10:34, da_wils(a)hotmail.com wrote:
> Hi,
>
> I'm making a uart that will run at the standard baud rates and have a
> bit of a query,
> My board has a 50Mhz clk so I've used this to create a 1.8432Mhz clock
> then derive all the baud clocks from it,,eg,
> -- 50mhz/ 1843200 = 27.1267
> -- 13 bit acc = 4096 msb
> -- divided by 151
> -- 4096/151 = 27.1258 -- close enough
> -- gives 1.843262MHz clock
>
> this is fine for TX but when it comes to RX where the accepted sample
> clk is 16x the baud rate I hit a few problems. I wanted to sample the
> incoming bit period at 4 16x clocks, 8 16x clocks and 12 16x clock and

Sample at clocks 7, 8 and 9 and take a majority vote. That's how
(almost) all standard uarts handle receive sampling. Spreading it out
by using clock 4, 8 and 12 gives you no better noise immunity and makes
your uart far more sensitive to baud rate accuracy.

Start bit edges need to be sampled at every 16x clock, of course.

> use the theory that if two samples match then RX bit is good, It's
> this generation of a 16x clock that is causing me problems, not easy
> to create for all baud rates. At the moment I'm sampling the RX at
> 50MHz and taking samples at three points, this scheme works but seems
> a bit inefficient due to having to have a bank of constants with the
> the various count values for different baud rates.
>
> Has anyone come across this problem ?

All standard baud rates are integer fractions of 115200. So when you
have your 1.84 MHz clock, you simply divide it by the baud divisor to
get your 16x clock (i.e., divide by 1 for 16 x 115200, by 6 for 16 x
19200, etc.).

If it's easier for your hardware, use a faster clock that 1.84 MHz as
the base - you can get away with 1% error (theoretically up to 5% total)
in the baud clock.
From: John_H on
On Mar 26, 5:34 am, da_w...(a)hotmail.com wrote:
> Hi,
>
> I'm making a uart that will run at the standard baud rates and have a
> bit of a query,
> My board has a 50Mhz clk so I've used this to create a 1.8432Mhz clock
> then derive all the baud clocks from it,,eg,
> -- 50mhz/ 1843200 = 27.1267
> -- 13 bit acc = 4096 msb
> -- divided by 151
> -- 4096/151 =  27.1258 -- close enough
> -- gives 1.843262MHz clock
>
> this is fine for TX but when it comes to RX where the accepted sample
> clk is 16x the baud rate I hit a few problems. I wanted to sample the
> incoming bit period at 4 16x clocks, 8 16x clocks and 12 16x clock and
> use the theory that if two samples match then RX bit is good, It's
> this generation of a 16x clock that is causing me problems, not easy
> to create for all baud rates. At the moment I'm sampling the RX at
> 50MHz and taking samples at three points, this scheme works but seems
> a bit inefficient due to having to have a bank of constants with the
> the various count values for different baud rates.
>
> Has anyone come across this problem ?

Why not just run everything from the 50MHz clock directly? Using
simple counters you can get as precise as you need for the UART
application whether for your 16x clock at high baud rates or 1x at the
lowest. You could even go for more precision at the cost of 20ns of
clock jitter by using an accumulator as the divider rather than a
counter.
From: dave on
Thanks for all your answers,
I'll generate a16x clock and give it a try otherwise I don't see any
problem oversampling using the 50MHz clock
my 1.84Mhz clock uses the accumulator method with a 20ns jitter, seems
to run ok,

Dave