cancel
Showing results for 
Search instead for 
Did you mean: 

USART/RS232 Int Problem...

mwp
Senior
Posted on April 11, 2013 at 19:16

Hi all,

I have the following code:

void
RS232_UART_Interrupt(
void
)
{
if
(USART_GetFlagStatus(USART3, USART_FLAG_TXE) != RESET)
{
//last byte has been transmitted, send another
if
(FIFO_Count(RS232_OutFIFO))
{
//have data to send
FIFO_Pop(RS232_OutFIFO, &Data);
USART_SendData(USART3, Data);
}
else
//no data, ready to restart with new data
USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
}
}

Im having the problem where if i try to transmit a lot of data quickly, the FIFO buffer will empty out, the function will stop sending data, but the int keeps being called with

USART_FLAG_TXE set.

As soon as the int returns, it is immediately called again hanging my program. Any ideas what the issue could be here? Thanks in advance!!
2 REPLIES 2
Posted on April 11, 2013 at 19:26

Any ideas what the issue could be here?

What other interrupts do you have enabled, or are signalling when it enters?

Disabling stops the NVIC being signalled, it does stop the bit showing up in the register.

Send Data clears the interrupt, you should perhaps disable the interrupt when you send the last byte, not when you realize there is no more data. But if you have no data to service the TXE, you'd better clear the interrupt, as you are not writing to USART3->DR to clear it that way.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mwp
Senior
Posted on April 16, 2013 at 09:50

Hi clive1,

Im still struggling to work out what the problem/cause is here. Im finding that when i send a largeish (~1KB) of data to the STM32's USART3 from a host PC, the USART3 int starts getting triggered with TXE (not RXNE), when the code has never sent any data. I cant see any reason why this should happen. Other ints in use are TIM3, UART4, USBVCom. Here is the updated complete setup/int code:

///////////////////////////////////////////////////////////////////////////////////////////
void
RS232_Init(
void
)
{
//init USART3 for coms with RS232
//PB10=TX, PB11=RX
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//init FIFO buffers
RS232_InFIFO = FIFO_Init(RS232_QUEUE_LEN);
RS232_OutFIFO = FIFO_Init(RS232_QUEUE_LEN);
//init pins
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
//TX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; 
//RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//init clocks
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
//setup nvic
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//set baud rate & init
RS232_SetBaud(Settings.RS232_BaudRate);
}
///////////////////////////////////////////////////////////////////////////////////////////
void
RS232_SetBaud(lDWORD BaudRate)
{
//set new baud rate
USART_InitTypeDef USART_InitStructure;
//disable
USART_DeInit(USART3);
//wait a while
GPIO_Delay(50);
//init uart (115200,8N1)
USART_InitStructure.USART_BaudRate = BaudRate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
//init interrupts
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); 
//int triggered on incoming data
USART_ITConfig(USART3, USART_IT_TXE, DISABLE); 
//disabled to begin with
//enable again
USART_Cmd(USART3, ENABLE);
//wait for tx ready
while
(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
}
///////////////////////////////////////////////////////////////////////////////////////////
void
RS232_UART_Interrupt(
void
)
{
//USART interrupt
lBYTE Data;
/*if(USART_GetFlagStatus(USART1,USART_FLAG_ORE))
USART_ClearFlag(USART1,USART_FLAG_ORE);
if(USART_GetFlagStatus(USART1,USART_FLAG_FE))
USART_ClearFlag(USART1,USART_FLAG_FE);
if(USART_GetFlagStatus(USART1,USART_FLAG_NE))
USART_ClearFlag(USART1,USART_FLAG_NE);
if(USART_GetFlagStatus(USART1,USART_FLAG_PE))
USART_ClearFlag(USART1,USART_FLAG_PE);*/
if
(USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == SET)
{
//have incoming byte
Data = USART_ReceiveData(USART3);
FIFO_Push(RS232_InFIFO, Data);
return
;
}
if
(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == SET)
{
//last byte has been transmitted, send another
USART_ClearITPendingBit(USART3, USART_IT_TXE);
if
(FIFO_Pop(RS232_OutFIFO, &Data))
//have data to send
USART_SendData(USART3, Data);
else
//no data, clear & disable until we have new data
USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
lBOOL RS232_Send(
void
*Buffer, lWORD Size)
{
//send data
if
(!Size)
//no data
return
lFALSE;
//queue up the data
for
(;Size != 0; --Size)
FIFO_Push(RS232_OutFIFO, *((lBYTE*)Buffer++));
//start transmit
USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
return
lTRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////

Continuing help is much appreciated! Thanks.