2013-09-02 01:37 AM
Hi,
I'm using Usart1 on STM32F100. I need to wait until the last byte is completed sended to make the DE signal go low on a Modbus Slave application. This seems to be a simple task for a each programmer, but I have spend one day on that, and sometimes this flag is been set, other times it doesn't. I read the reference manual and there is nothing that says that it is required any configuration to make this flag be asserted. I have used the pool version, and the interrupt version, and the problem is always the same. Sometimes it is asserted and the communication is works well, other times it is blocked, waiting for this flag, to make sure that the last byte has been sended. Can someone help me, giving me reasons, why this occurs? Thank you very much in advance, Best regards, Almerindo Paiva2013-09-02 02:37 AM
The TC bit is cleared by the following software sequence:
1. A read from the USART_SR register 2. A write to the USART_DR register Note: The TC bit can also be cleared by writing a ‘0’ to it. This clearing sequence is recommended only for Multibuffer communication. If you are not doing any of the above, are you using a debugger and monitoring USART_SR? the debugger will clear TC when it reads SR.2013-09-02 03:15 AM
Yes, I was monitoring all registers on that peripheral!!! Inclunding USART_SR of course. I don't know if my IDE is able to select this register from the selected peripheral.
I believe you are right, because this explains why sometimes it works and others times it blocks. It depends if the Usart_handler was quicker rather than the debbuger to read find th TC flag. I'm using freemodbus. there are being using two instructions: - __disable_irq() and - __enable_irq(). What make it at all? Can this make interferance with the USART interrupt handler? Can I lost events with this functions, like a TC interrupt? Another question, in my Usart handler I use the following code to check it the interrupt request was done by the TC flag. ... if ( USART_GetITStatus( RS485_COM1, USART_IT_TC ) != RESET) { .... } ... in the freemodbus I use this same code to know if I have transmitted all bytes. When it is running, the CPU calls the Usart handler and make the instrunctions below the checking of the TC flag. But then it doesn't enters in the freemodbus, and the transmit state machine is blocked because the TC flag isn't asserted. What is happening if I read the ISR register, will it clear the TC flag??? Thank you for the above information. Regards, Almerindo Paiva2013-09-02 03:21 AM
Hi Mr. John,
It is solved! It was making a great mistake in my usart interrupt handler code: if ( USART_GetITStatus( RS485_COM1, USART_IT_TC ) != RESET ) { //USART_ClearITPendingBit( RS485_COM1, USART_IT_TC ); ... } I was clearing the bit, so it would be always deasserted in the freemodbus transmit state machine :) Could you explain the influence of the __disable_irq() and __enable_irq() functions, in the lost of events??? Thanks for your help, Regards, Almerindo Paiva2013-09-02 05:28 AM
The enable/disable should just defer the service, these act at the processor level, the interrupt should be held by the NVIC, and the peripheral asserting.
2013-09-02 06:45 AM
Hi Mr. Clive,
Thanks for the information. Best regards, Almerindo Paiva