2011-06-23 02:58 PM
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 #stm322011-06-23 11:24 PM
2011-06-24 07:19 AM
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).2011-06-24 09:54 AM
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?2011-06-24 10:36 AM
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.2011-06-24 05:08 PM
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' }
2013-03-29 06:15 AM
Hello
I would like very much to see the complete project (with the macros) of your dmx transmitter, if you still are around.Regards,2013-03-29 02:22 PM
questions
1) are you missing LSB or MSB 2) what do you see if you specify 1 stop bit Erik2013-03-30 04:23 AM
Note that the last post from the OP was in June
2011
- so it seems rather unlikely that he is still monitoring this thread...2013-03-31 12:55 PM
Never mind, found it at