5
\$\begingroup\$

I using MSP430FR6989 microcontroller (development board MSP-EXP430FR6989) to try and send a UART signal via it's TX pin

The configuration of the MSP430:

  • Clock System 32.768 Khz
  • Baud Rate 9600
  • 8 bits, No Parity, LSB first, One Stop bit
  • Using eUSCI_A0 module (Enhanced Universal Serial Communication Interface A0 module), and using P4.2 UCA0TXD pin

The premise of the mini-project is, when I press a button, a digital input isr is serviced, and an 'A' is transmitted via the UART module.

'A' = 0x41 = 0b 0100 0001

so if LSB bit is sent first it will be 1000 0010

following the character format of the UART Start D0 D1 D2 D3 D4 D5 D6 D7 Stop 0 1000 0010 1

enter image description here Section 30.3.2 of the MSP430 user guide

I expected the signal to look like this in the oscilloscope

enter image description here


However, when I debugged the UART TX pin using an oscilloscope, this is the signal that I got:

enter image description here

the char that I received is (from MSB to LSB): 0b 1010 0001 = 0xA1

I changed the code so that when I press a button a 0 would be written on the Transmit Buffer, but this is the signal I got from the oscilloscope:

enter image description here

I sent a 0 yet I received a 1000 0000

Note: I am not sure if this is relevant or not, but I pressumed time in the oscilloscope goes from left to right, however, the time cursor E is at 0.00 us and S is at -105us, which suggest that time goes from right to left.


That is part of my code that I think is relevant to the post FYI

Clock_Initialization.h

#ifndef CLOCK_INITIALIZATION_H_
#define CLOCK_INITIALIZATION_H_

void clock_initialization (void);

#endif /* UART_CLOCK_INITIALIZATION_H_ */

Clock_Initialization.c

#include <msp430.h>
#include "Clock_Initialization.h"

void clock_initialization (void)
{
    //smclk and mclk = 8Mhz DCO
    //is it possible to disable ACLK

    CSCTL0 = CSKEY;//password in order to modify clock signal
    CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
    //ACLK -> LFXTCLK (32.768KHz) SMCLK & MCLK -> DCOCLK

    //enable the LFXIN and LFXOUT pins PJ.4 and PJ.5 P84 and P85
    PJSEL0 |= BIT4;//PJSEL0.4 = 1
    PJSEL1 &= ~BIT4;//PJSEL1.4 = 0
}

Baud_Rate.h

#ifndef BAUD_RATE_H_
#define BAUD_RATE_H_

void baud_rate_setup (void);

#endif /* UART_BAUD_RATE_H_ */

Baud_Rate.c

#include <msp430.h>
#include "Baud_Rate.h"

void baud_rate_setup (void)
{
    //baud rate 9600 clock signal 32.768 KHz
    UCA0CTLW0 |= UCSWRST;
    UCA0BRW = 3;
    UCA0MCTLW = 0x9200;
}

UART.h

#ifndef UART_H_
#define UART_H_

#define UART_TX_BUF UCA0TXBUF

#include "Digital_Input_Output/Debounce.h"
//includes the enum Button datatype
/*
   enum Button
   {
        Button0 = 0,
        Button1 = 1,
        Button2 = 2
   }
 */
void init_UART (void);

void sendChar (enum Button x);


#endif /* UART_UART_H_ */

UART.c

#include <msp430.h>
#include "UART.h"
#include "Digital_Input_Output/Debounce.h"
//includes the enum Button datatype

void init_UART (void)
{
    UCA0CTLW0 &= ~ (UCPEN | UCMSB | UC7BIT | UCSPB | UCSYNC);
    //No Parity, LSB first, 8 bits, One Stop Bit, Ascyc.
    UCA0CTLW0 |= UCSSEL__ACLK;//CS 32.768 KHz
    UCA0CTLW0 &= ~UCSWRST;

    P4SEL0 |= (BIT2 | BIT3);
    P4SEL1 &= ~(BIT2 | BIT3);
}

void sendChar (enum Button x)
{
    switch(x)
    {
    case Button0:
        UART_TX_BUF = 'A';//0;//'A';
        break;
    //...rest of the code
}

in main.c

#include <msp430.h> 
#include "Digital_Input_Output/Debounce.h"//have enum Button datatype
#include "UART/Clock_Initialization.h"
#include "UART/Baud_Rate.h"
#include "UART/UART.h"

//code

int main(void)
{
    //code

    clock_initialization ();
    baud_rate_setup ();
    init_UART ();

    _BIS_SR (GIE);//enable global interrupt

    while(1);

    return 0;
}

#pragma vector = PORT1_VECTOR
__interrupt void Port1_ISR (void)
{
    switch(P1IV)
    {
         //code
         sendChar(Button0);
         //rest of the code
}

Kindly help me with my issue.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Try sending a "U" (0x55) - that will give you alternating 1 and 0 bits. From your scope pictures, I think your bits are a bit narrower than you expect. \$\endgroup\$ – Peter Bennett Jul 2 '20 at 0:44
8
\$\begingroup\$

If you try to use 9600 bps rate with 32768 Hz clock, it is not possible, the actual baud rate will be faster, 10923 bps.

That is 13% faster than requested 9600 bps, and thus out of tolerance requirement for receiver operating at 9600 bps rate.

\$\endgroup\$
2
  • \$\begingroup\$ I am not an expert on Baud Rate calculations, tried measuring the signal with the new baud rate that you gave me, I reduced the time cursor in the oscilloscope to 1/10923 = 92us and and I got the right results. However, I don't understand why I got the wrong baud rate as I used to the recommendation from the User Guide (pg 782). for brclk = 32768 Hz, Baud Rate = 9600 and UCOS16 = 0 they recommended UCBR = 3 and UCBRS = 0x92 \$\endgroup\$ – Forat Jul 2 '20 at 3:12
  • 4
    \$\begingroup\$ @Forat that's the closest option, it's just that there is no good option with that master clock. \$\endgroup\$ – hobbs Jul 2 '20 at 4:18
1
\$\begingroup\$

You need less than ±5% timing error on 10 bits:

±5% x 10 bits = ±50% bit, i.e a full bit of error

In reality that is unreasonable, as you want to avoid sampling near the possibly noisy edges (from transitions) of the bits.

Most UART receivers do 16x oversampling, so you can push it to ±7 / 16 / 10 = ±4.375% timing error.

Then you have to account for the oscillator error. With a local RC oscillator driving the UART, error is typically 3% to 5% depending on temperature. With a ceramic resonator or quartz crystal driving the UART, the error and drift typically isn't an issue.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You might want to suggest to canonical test of sending 0x55 or 0xAA to check it is a timing error, rather than a misconfigured U[S]ART \$\endgroup\$ – james Jul 3 '20 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.