oPossum 1,083 Posted March 26, 2012 Share Posted March 26, 2012 The MSP430x2xx Family User's Guide has several forumulas and tables for UART bit rate calculation. Makes it look more complicated than it is. Here is simple code to setup the bit rate divisor and modulator (for oversampling mode). First you need to know the SMCLK frequency and the desired bit rate. const unsigned long smclk_freq = 16000000; // SMCLK frequency in hertz const unsigned long bps = 19200; // Async serial bit rate Then a 20 bit divisor value can be calculated. const unsigned long brd = (smclk_freq + (bps >> 1)) / bps; // Bit rate divisor Shift and mask to setup the registers. UCA0BR1 = (brd >> 12) & 0xFF; // High byte of whole divisor UCA0BR0 = (brd >> 4) & 0xFF; // Low byte of whole divisor UCA0MCTL = ((brd << 4) & 0xF0) | UCOS16; // Fractional divisor, oversampling mode That's it! A function for UART setup at a specified bit rate... const unsigned long smclk_freq = 16000000; // SMCLK frequency in hertz void setup_UART(const unsigned long bps) // Async serial bit rate { const unsigned long brd = (smclk_freq + (bps >> 1)) / bps; // Bit rate divisor UCA0CTL1 = UCSWRST; // Hold USCI in reset to allow configuration UCA0CTL0 = 0; // No parity, LSB first, 8 bits, one stop bit, UART (async) UCA0BR1 = (brd >> 12) & 0xFF; // High byte of whole divisor UCA0BR0 = (brd >> 4) & 0xFF; // Low byte of whole divisor UCA0MCTL = ((brd << 4) & 0xF0) | UCOS16; // Fractional divisor, oversampling mode UCA0CTL1 = UCSSEL_2; // Use SMCLK for bit rate generator, release reset } timotet, stirlingboy, bluehash and 7 others 10 Quote Link to post Share on other sites
RobG 1,892 Posted March 27, 2012 Share Posted March 27, 2012 Another option is an online calculator. Quote Link to post Share on other sites
oPossum 1,083 Posted March 27, 2012 Author Share Posted March 27, 2012 I don't think that calculator is for F2000/G2000 series MSP430. The modulator value is wrong and the javascript source code doesn't use the method described in the MSP430x2xx family user's guide (slau144). It uses a discreet modulation pattern instead of modulation table indices (table 15-2 and 15-3 in slau144i). Quote Link to post Share on other sites
RobG 1,892 Posted March 27, 2012 Share Posted March 27, 2012 I have used it for G series and didn't have any issues, maybe it's just a combination of clock and bit rate that made it work. Here's an idea, create 43oh hosted Javascript calculator page based on your code. Quote Link to post Share on other sites
oPossum 1,083 Posted March 27, 2012 Author Share Posted March 27, 2012 This is the Javascript code from the calculator web page that calculates the modulator value (UxMCTL). It tests a modulus of N and N+1 to assess which has the least error and creates a bit pattern for modulation. for(i=0;i<8;i++) { er0= (Baud/F*((i+1)*N+msum) -(i+1))*100; er1= (Baud/F*((i+1)*N+msum+1) -(i+1))*100; if(abs(er1) msum++; UxMCTL|= s; txer[i]= er1; } else { txer[i]= er0; } s<<=1; } This is compatible with 1 series, 3 series and 4 series. It is not compatible with 2 series, value line, 5 series and 6 series. These parts have dual mode prescalers that can operate in 'low bit rate' mode (typically with 32 kHz ACLK) or 'oversampling mode' (typically with DCO). The code I posted uses oversampling mode and does not make use of the BITCLK modulator (UCBRSx), only the BITCLK16 modulator (UCBRFx). Careful coding will allow the derivation of the register values to be shown in the code without generating any excess runtime code - just loading constants in to registers. This makes it easy to change the bit rate or clock frequency and makes it clear what the actual metrics are. { // Use of 'const' to allow compile time calculation of register values const unsigned long smclk_freq = 16000000; // SMCLK frequency in hertz const unsigned long bps = 19200; // Async serial bit rate const unsigned long brd = (smclk_freq + (bps >> 1)) / bps; // Bit rate divisor UCA0BR1 = (brd >> 12) & 0xFF; // High byte of whole divisor UCA0BR0 = (brd >> 4) & 0xFF; // Low byte of whole divisor UCA0MCTL = ((brd << 4) & 0xF0) | UCOS16; // Fractional divisor, oversampling mode } bluehash, SugarAddict and yyrkoon 3 Quote Link to post Share on other sites
RobG 1,892 Posted March 28, 2012 Share Posted March 28, 2012 Well, BR0 and BR1 are calculated correctly. In situations where clock is divisible by baud rate, modulation pattern is 0 so it doesn't matter. For example MIDI's 31250 Baud rate and clock speeds 16MHz, 8MHz, 1MHz, etc. In other situations, you can match UxMCTL results to table 15-2 and choose the closest match (worked for me with 16MHz and 115200 Baud rate.) The Javascript can be updated to produce 8 values only and the second one can be written for use with oversampling. As I wrote already, UART calculator would be a nice tool to have on 43oh. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.