Picking the right baud rate timing

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

I have recently switched to a new PCB design for my Xmega project.  It has a RN-42 bluetooth "modem" which the Xmega talks to via RS232.

 

I noticed I was getting mostly garbage characters out over bluetooth.

With a 32mhz CPU and 9600 baud, I tried tweaking my baud rate as follows and

found a good clean connection:

 

    USART_data_BT.usart->BAUDCTRLA=209;
    USART_data_BT.usart->BAUDCTRLB=0;

 

Unfortunately, on my previous PCB/same CPU, same RN-42 bluetooth device, I had tweaked the value to 207 to get around the same garbage problem in the past.

207 was not working well with this iteration.

 

So... what is the procedure for picking a number which is robust? I just went and tried every timing value from 207 - 235.  The communications is clean from 208 to 230, garbage below 208, and stops abruptly above 230.

 

Calculations say it should be 208.27

Baudrate select = (1/(16*(((I/O clock frequency)/Baudrate)-1)

208 = 1/16 * (( 32M / 9600 ) - 1)

 

So... the spread of 208 to 230 seems a little lopsided!

 

thanks,

Mike in Alaska

 

 

 

 

 

This topic has a solution.
Last Edited: Sat. Dec 19, 2015 - 12:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

You are likely using the internal 32M oscillator without DFLL calibration. It will be quite far off. You didn't say which xmega you use, but e.g. 16D4 runs around 34M at room temperature according to datasheet. That would give about 220, which is in agreement with your testing.

 

You could use 220, but it would be much more reliable to use DFLL from internal 32K and then 208. The latter is accurate enough in all temperatures.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow! Thanks for that. I am using a 128A4U. I will look into the DFLL.

 

OK. I found this for DFLL code and put it in:

OSC.CTRL |= OSC_RC32MEN_bm | OSC_RC32KEN_bm;  /* Enable the internal 32MHz & 32KHz oscillators */
while(!(OSC.STATUS & OSC_RC32KRDY_bm));       /* Wait for 32Khz oscillator to stabilize */
while(!(OSC.STATUS & OSC_RC32MRDY_bm));       /* Wait for 32MHz oscillator to stabilize */
DFLLRC32M.CTRL = DFLL_ENABLE_bm ;             /* Enable DFLL - defaults to calibrate against internal 32Khz clock */
CCP = CCP_IOREG_gc;                           /* Disable register security for clock update */
CLK.CTRL = CLK_SCLKSEL_RC32M_gc;              /* Switch to 32MHz clock */
OSC.CTRL &= ~OSC_RC2MEN_bm;                   /* Disable 2Mhz oscillator */

 

As a result, the functional range for the baud value is now 200-221, much more centered around the 208 computed value than the earlier span.

 

So what if the device is left outside running and the temperature is drifting up and down by 30 degrees F? Does the above procedure need to be run repeatedly to keep the clock correct?

 

Mike

Last Edited: Sat. Dec 19, 2015 - 12:45 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Look at the datasheet. You'll find the answer under Typical Charasteristics/128A4U/Oscillator Charasterictics/32M internal. There you find two set of curves: One without DFLL and and with it. Earlier you had a range of 35.5->31.5 MHz from -40C to +105C and now with DFLL you have 31.7->32.05MHz.

 

For UART about +-2% error is OK to have and still have some margin for the other end. So earlier you set for 34MHz and it would have been OK for 33.3-34.7 MHz and thus about -10 to + 40C, but now with DFLL you can easily cover the whole -40C + 105C range.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Baudrate select = (1/(16*(((I/O clock frequency)/Baudrate)-1)

This is the ATmega way of determining the bitrate.  The Xmega has a fractional bitrate generator that can generate better average bitrates.  Although this will have much less impact than using the DFLL as jmaja1 has suggested, it may help a little.

Greg Muth

Portland, OR, US

Xplained/Pro/Mini Boards mostly

 

Make Xmega Great Again!