cancel
Showing results for 
Search instead for 
Did you mean: 

USART and stop bits

slandrum
Associate II
Posted on June 23, 2011 at 23:58

In playing around with USART3, I'm attempting to configure it for DMX (250000 baud, 8 data bits, 2 stop bits).  In fact, when configured this way, what actually seems to happen is that any data I attempt to send is actually sent as 7 bits (the MSB is dropped).  The stop bits are there, but the last data bit was stolen.

I can get what I want by configuring for 9 data bits and two stop bits, what comes out is actually 8 data bits and two stop bits.

This behavior doesn't match what I would expect from the reference manual, but since I can do what I need to do I'll proceed.

I haven't tested to see if this behavior is the same on the other USARTs/UARTs, but I would expect that it would be identical.

#usart #stop-bits #stm32
9 REPLIES 9
ezyreach
Associate II
Posted on June 24, 2011 at 08:24

Check whether the USARTx data register is AND with 0x7F.

When no parity is there this AND operation not to be done.

usart_wordlength_8b = 7 databits + 1 parity bit.

when no parity, the above actually acts as 8 data bits.

If parity is even or odd, upon reading the USARTx data register AND operation with 0x7F needed to performed.

usart_wordlength_9b = 8 databits + 1 parity bit

When no parity is declared, then it is 9 data bits.

slandrum
Associate II
Posted on June 24, 2011 at 16:19

This is not a parity issue.  I'm not requesting parity - I'm requesting stop bits.

If I configure the USART for 8 data bits and 2 stop bits at 250000 baud, each bit takes 4 usec, and each byte should be 11 bits for 44 usec.  Instead, I get 10 bits for each byte.  The first stop bit is replacing the last data bit, so instead of what I requested, I get 7 data bits and 2 stop bits.

If I configure the USART for 9 data bits and two stop bits, then I get 8 data bits and two stop bits.

This is verified by monitoring the output with an oscilloscope.  There is no ANDing going on, in fact stop bits are high level (read as 1).

ColdWeather
Senior
Posted on June 24, 2011 at 18:54

1). Prove again, how you handle the USART TXE bit. Maybe you write to the DR before TXE is set?

2). Try to make the ''synchronous'' transmission by polling TXE or TC bits. As far as I unterstood, you've got an oscilloscope. Make debug pulses on some GPIOs to reflect TXE and TC bits.

3). How do you generate the DMX break condition? If you change the baud rate, check your code: maybe you set it >every time< before sending a byte that causes the last bit get lost?

slandrum
Associate II
Posted on June 24, 2011 at 19:36

I send bytes based on an interrupt, which is triggered by TXE.  In any case, if I were writing too soon, I would not see the data truncated in this way with the stop bits coming too soon - I would expect that I might see the stop bits truncated if anything.

I will be implementing the break with baud rate changes, using TC to know that it's safe to change the baud rate.  But for now I am not doing any baud rate changes.  This test is using a simple interrupt handler tiggered by TXE that sends bytes until the buffer is depleted, then disables the TXE interrupt.  The code that writes the buffer enables the TXE interrupt to start the transmission process.

If I set the number of stop bits to 1, I get exactly what I expect.  8 data bits with a single stop bit comes out correctly with the correct timing and bit pattern.  9 data bits with a single stop bit also comes out correctly with the correct timing and bit pattern.

It fails to operate in the expected manner when I set the number of stop bits to 2.  The data is shortened by a bit and two stop bits are generated.  It's like the 2nd stop bit is handled the same way that the parity bit is handled, it replaces the last data bit.  I have not done tests to see if parity affects the behavior of the stop bits, since in my application I won't be using parity.

This also occurs if I send a single character in isolation so that there can be no issue of truncating the character by sending a subsequent one too early.  In this case it cannot easily be determined how many stop bits there are as the idle state of the line is the mark state, but it is clear that the data being sent is being truncated if two stop bits are requested.

Have you attempted to use two stop bits in transmission from this processor family and seen it work?

In any case, as I said, I can get what I need out of the device.  I just want others to know that it does not behave as one would expect.

ColdWeather
Senior
Posted on June 25, 2011 at 02:08

Hello!

Have you attempted to use two stop bits in transmission from this processor family and seen it work?

 

Yes, I took a look at my test project and saw, I was also using USART3 on STM32F103RC for DMX packet sending in DMA mode.

My USART init structure is (to use with the ST peripheral library):

static const USART_InitTypeDef

    USART_InitStructure = {

        DMX_BAUD_RATE,   

        USART_WordLength_8b,

        USART_StopBits_2,

        USART_Parity_No,

        USART_Mode_Tx,

        USART_HardwareFlowControl_None

    };

The USART3 ISR processes the first interrupt on TC flag after BREAK has been sent (I use a lot of macros to access registers but they have self explaining names):

/******************************************************************************/

//

//    DMX SENDER UART IRQ Handler: on TC only!

//  If entered while low baud rate, BREAK complete, - start DMA

//  else the last byte sent, - restart packet.

//

/******************************************************************************/

void DMX_USART_IRQHandler(void)

{

    USART_TCIE_CLEAR(DMX_USART);            // disable USART TC interrupt

    if (DMX_USART->BRR != _BRR) {           // low speed: BREAK gone

        _SetBaud(1);                           // set full baud rate

                                               

        // see Fig.295, page 787, RM0008, Doc ID 13902 Rev 12,

        // for multibyte communication with DMA:

        USART_TC_CLEAR(DMX_USART);            // clear USART TC flag

        DMA_IF_CLEAR_BITS(DMX_USART_DMA,

                          DMX_DMA_IT_TCx);  // clear DMA TC flag

        DMA_TCIE_SET(DMX_USART_DMA_C);      // enable DMA TC interrupt

        DMA_ENABLE  (DMX_USART_DMA_C);      // transmit bytes via DMA

    } else {                                // ALL BYTES sent, start again

        NVIC_SetPriority(DMX_USART_IRQn, LOWEST_IT_Priority);

        DMX_Sender_Start();                     

    }

}

The DMA ISR looks like:

/******************************************************************************/

//

//  DMA Channel IRQ handler

//

//  Occures as soon as the last byte moved into USART->DR.

//  At this point TXE is still reset, the byte is being transmitted,

//  USART TC bit would occure after the STOP bit.

//

//  ATTENTION: occures two bytes before! See multibyte communication with DMA

//

/******************************************************************************/

void DMX_DMA_HANDLER(void)  // DMX_USART_DMA_C is responsible for USART TX

{

    DMA_TCIE_CLEAR(DMX_USART_DMA_C);    // disable DMA TC interrupt

    DMX_USART_TCIE_ON;                    // reenable USART TC interrupt

}

The whole process is started by:

void DMX_Sender_Start(void)

{

    DMX_SendBuffer[1] += 50;    // DEBUG SHOW!!!

    DMA_DISABLE(DMX_USART_DMA_C);                 // disable DMA channel

    DMA_RELOAD (DMX_USART_DMA_C, (DMX_BUFSIZE+1));// reload DMA channel counter  

    _SetBaud(2);                  // set half baud

    DMX_USART_TCIE_INIT;        // clear USART TC flag, enable its interrupt

    USART_PUT_DR(DMX_USART, 0); // send '0'

}

fradav
Associate
Posted on March 29, 2013 at 14:15

Hello 

I would like very much to see the complete project (with the macros) of your dmx transmitter, if you still are around.

Regards,

emalund
Associate III
Posted on March 29, 2013 at 22:22

questions

1) are you missing LSB or MSB

2) what do you see if you specify 1 stop bit

Erik
Andrew Neil
Chief II
Posted on March 30, 2013 at 12:23

Note that the last post from the OP was in June

2011

- so it seems rather unlikely that he is still monitoring this thread...
fradav
Associate
Posted on March 31, 2013 at 21:55

Never mind, found it at 

https://code.google.com/p/stm32-dmx512/