cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 using two usart interrups simultaneously

persianpatient
Associate II
Posted on November 07, 2016 at 09:59

The original post was too long to process during our migration. Please click on the attachment to read the original post.
7 REPLIES 7
AvaTar
Lead
Posted on November 07, 2016 at 10:46

> void USART1_IRQHandler(void)

 

> {

 

>    ...

 

>                    b1 = checksumUnion.bytes[0];

 

>                    b2 = checksumUnion.bytes[1];

 

>                   

USART3_Send_Byte

(':');

 

>     ...

Is the

USARTx_SendByte()

function blocking ?  Most probably.

It will keep you in the receive interrupt context until sending is finished. Assuming equal priorities for your UART interrupts, received characters get lost.

Never do this.

Tuttle.Darrell
Associate II
Posted on November 07, 2016 at 15:29

You are spending WAY too much time in your ISRs. Lose the delay_ms() calls, process a single byte at a time and avoid calling blocking functions. Try receiving a single byte and storing it in a buffer and exiting the ISR (no delays). Process received data from the buffer in main(). 

Posted on November 07, 2016 at 18:36

The code looks logically broken, beyond the blocking.

But as others have indicated you need to get past this mind-set that you can spin around in loops, either waiting for characters to be sent, or delays. There are not multiple threads of execution. You aren't going to be able to solve this with preemption, you need to physically separate the functionality into steps.

You need to buffer the output, and send it one byte at a time elsewhere in the IRQ handler. It is critical you do everything you can in less than one byte time and leave. 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
persianpatient
Associate II
Posted on November 08, 2016 at 08:42

Hi ,

Thanks for replies , regarding to your explanation I will update my code and report my progress.

Sincerely Yours

Amir .

persianpatient
Associate II
Posted on November 08, 2016 at 18:22

Hi,

I have changed RX interrupts :

void USART2_IRQHandler(void)

{

    if( USART_GetITStatus(USART2, USART_IT_RXNE) )

    {

        char s = USART2->DR;

        {

            if ((s != ':') && (bSent == 1))

            {

                for (q=1; q<cnt; q++)

                {

                    received_string[q] = '\0';

                }

            }

            if (s != ';')

            {

                cnt++;

                received_string[cnt] = s;

            }

            if (s == ';')

            {

                cnt++;

                received_string[cnt] = ';';

                bUpdated = 1;

            }

        }

    }

}

void USART1_IRQHandler(void)

{

    if( USART_GetITStatus(USART1, USART_IT_RXNE) )

    {

//        if (canSend == 1)

        {

            char t = USART1->DR;

//            USART3_Send_Byte(t);

            if ((t != ':') && (aSent == 1))

            {

                for (q=1; q<cnt2; q++)

                {

                    received_string2[q] = '\0';

                }

            }

            if (t != ';')

            {

                cnt2++;

                received_string2[cnt2] = t;

            }

            if (t == ';')

            {

                aUpdated = 1;

//                cnt2 = -1;

            }

        }

    }

}

transmit data in main loop :

    while(1)

    {

        aSent = 0;

        if ((aUpdated == 1) && (bUpdated == 0))

        {

            checksum = 0;

            checksum = received_string2[1] + received_string2[2] + received_string2[3] + received_string2[4] + received_string2[5] + received_string2[6] + received_string2[7];

            checksumUnion.checks = checksum;

            b1 = checksumUnion.bytes[0];

            b2 = checksumUnion.bytes[1];

            for (q=0; q<8; q++)

            {

                USART3_Send_Byte(received_string2[q]);

                received_string2[q] = '\0';

            }

            USART3_Send_Byte(b1);

            USART3_Send_Byte(b2);

            USART3_Send_Byte(';');

            aUpdated = 0;

            cnt2 = -1;

            aSent = 1;

        }

        //

        bSent = 0;

        if (bUpdated == 1)

        {

            for (q=0; q<cnt; q++)

            {

                USART3_Send_Byte(received_string[q]);

                received_string[q] = '\0';

            }

            USART3_Send_Byte(';');

            cnt = -1;

            aUpdated = 0;

            bUpdated = 0;

            bSent = 1;

        }

it's now working better , but I still have checksum errors .

do you have any advice ?

Best Regards,

Amir .

 

Posted on November 08, 2016 at 18:43

it's now working better, but I still have checksum errors. do you have any advice ?

Present sufficiently complete code.

Present example input data, and output from the presented code, both for successful and failing cases.

Make sure you properly scope the buffers, so you don't overflow them, and you can recover/resync the data if you drop bytes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 08, 2016 at 18:46

You shouldn't act on buffers you are changing in the background. Not sure of the value of zeroing the entire buffers. For string functions you need to ensure NUL termination.

Show the buffer sizes and variable definitions, the code lacks context without these.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..