cancel
Showing results for 
Search instead for 
Did you mean: 

STM34F411-Nucleo USART stop TX interrupt advice

dman
Associate II
Posted on February 10, 2016 at 10:11

Hi,

I'm trying to get comms between USART1 and USART6 working. I can send from USART1 to USART6 using interrupts and it works. What I am trying to do now is control the sending interrupt, but I think I am missing something. So the IRQ1handler just goes through a send buffer and send data, great no problem, but I cannot seem to stop it. This is my IRQ1Handler

void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) // Transmit the string in a loop
{
USART_SendData(USART1, StringLoop[tx_index++]);
if (tx_index >= BUFFER_SIZE)
{
tx_index = 0;
USART_ITConfig(USART1,USART_IT_TXE,DISABLE); //When all data received, stop interrupt for TXE flags
}
}
}

and this is my main

int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_USART1_Configuration();
NVIC_USART6_Configuration();
USART1_Configuration();
USART6_Configuration();
while (1)
{
Delay(2000);
USART_ITConfig(USART1,USART_IT_TXE,ENABLE);
}
}

So basically I am trying to enable the transmission every 2 seconds, not continuously send it. Any advice would be appreciated. Thanks
12 REPLIES 12
dman
Associate II
Posted on February 11, 2016 at 00:17

Dembek, thank you for encouragement (virtual kick in the a*s) - it worked.

Got my main sorted

int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_USART1_Configuration();
NVIC_USART6_Configuration();
USART1_Configuration();
USART2_Configuration();
USART6_Configuration();
while (1)
{
USART_ITConfig(USART1,USART_IT_TXE,ENABLE);
Delay(0xFFFFF);
Delay(0xFFFFF);
Delay(0xFFFFF);
Delay(0xFFFFF);
}
}

The TX IRQ really hasn't changed. By adding these delays in the main I can see in debug a much longer delay until the RX buffer fills up (I am not losing any data). I guess my next step will be to implement some sort of more sensible control when i want data to be sent and when not. What would be a typical pattern in implementing interrupt driven TX? Circular buffer? Thanks
Radosław
Senior II
Posted on February 11, 2016 at 10:16

OK. Specially for You.

#define buffer_size 256                         //!< Buffer size for USART1 (must be power of 2)

#define buffer_mask (buffer_size - 1)           //!< Mask for buffer indexes for USART1.

volatile char RXD1_buffer[buffer_size];         //!< Input buffer for USART1.

volatile char TXD1_buffer[buffer_size];         //!< Output buffer for USART1.

volatile uint32_t RXD1_head;                    //!< Head of input buffer for USART1.

volatile uint32_t TXD1_head;                    //!< Head of output buffer for USART1.

volatile uint32_t RXD1_tail;                    //!< Tail of input buffer for USART1.

volatile uint32_t TXD1_tail;                    //!< Tail of output buffer for USART1.

void USART1_IRQHandler(void)

{

    uint32_t tmp;

    if (USART1_SR_RXNE_bb)

    {

        tmp = RXD1_head;

        RXD1_buffer[tmp] = USART1->DR;

        RXD1_head = (tmp + 1) & buffer_mask;

        if (RXD1_head == RXD1_tail)

        {

            // buffer overflow detection

        }

    }

    if (USART1_CR1_TXEIE_bb && USART1_SR_TXE_bb)

    {

        tmp = TXD1_tail;

        if (TXD1_head != tmp)

        {

            tmp = (tmp + 1) & (buffer_size - 1);

            USART1->DR = TXD1_buffer[tmp];

            TXD1_tail = tmp;

        }

        else

        {

            USART1_CR1_TXEIE_bb = 0;

        }

    }

}

void USART1_SendString(const char *s)

{

    char c;

    uint32_t tmp_head;

    while ((c = *s++))

    {

        tmp_head = (TXD1_head + 1) & buffer_mask;

        while (tmp_head == TXD1_tail);

        TXD1_buffer[tmp_head] = c;

        TXD1_head = tmp_head;

    }

    USART1_CR1_TXEIE_bb = 1;

}

dman
Associate II
Posted on February 11, 2016 at 21:10

Radoslaw,

This is great, I actually understand the logic and can make sens off it. Thank you for this, much appreciated.