2016-02-10 01:11 AM
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 IRQ1Handlervoid 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
2016-02-10 07:01 AM
void USART1_IRQHandler(void)
{ if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) AND IF INTERRYPT TXE IS ENABLED// 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 } } }2016-02-10 07:08 AM
Does it work if you stop re-enabling the interrupt?
If so make sure the delay function does what you expect it too.2016-02-10 08:23 AM
The delay function just loops
/**
* @brief Inserts a delay time.
* @param nCount: specifies the delay time length.
* @retval None
*/
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
The transmission does not work if I remove the re-enabling statement.
2016-02-10 08:31 AM
Thanks for the suggestion.
But it still does seem to produce a continuous transmission.void USART1_IRQHandler(void)
{
if ((USART_GetITStatus(USART1, USART_IT_TXE) != RESET) && USART_GetFlagStatus(USART1, USART_FLAG_TXE) == SET) // Transmit the string in a loop if TXE enabled
{
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
}
USART_ClearITPendingBit(USART1, USART_IT_TXE);
}
}
I guess my delay function would need to disable all interrupts and re-enable them when it is done, but that just sounds too dangerous.
2016-02-10 09:29 AM
delay as yours not neccesarry must work after optimization.
Change optimization to o0 or rewrite delay based on timer.2016-02-10 11:34 AM
Thank you for your suggestions.
I've decided to ditch the TX IRQ as a whole and use a blocking method. I've added function:void USART_Send(uint8_t * data)
{
for(int tx_index = 0; tx_index < BUFFER_SIZE; tx_index++)
{
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) != SET); //wait for TX register to be empty
USART_SendData(USART1, *data++);
}
}
And updated my main:
while (1)
{
USART_Send(StringLoop);
Delay(0x0FFFF);
}
This seems to do what I was aiming for.
Thank you.
2016-02-10 11:43 AM
OMG. ;)
Learn things. back to interrupt mode. Variable deklaration is OK? volatile if needed?2016-02-10 01:39 PM
Unfortunately the selective cut-n-paste makes it hard to know the larger context.
You'd need to enable the interrupt for it to occur in the first passUSART_ITConfig(USART1,USART_IT_TXE,ENABLE);Defining the loop iterator as volatile will stop the optimizer from removing the pointless code in the delay.2016-02-10 01:49 PM
0xFFFF can create to short delay.