Reputation: 276
I'm implementing a simple UART receive-transmit protocol on STM32F103, the library/boilerplate code I'm using here is LL, not HAL (as HAL includes insane amounts of overhead)
My problem is that after successfully entering the interrupt handler "USART1_IRQHandler" it keeps cycling on forever. My code is here:
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
int ii = 0;
for(ii=0; ii<4; ii++){
LL_mDelay(40);
LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);
LL_mDelay(40);
LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);
}
uint8_t cc = LL_USART_ReceiveData8(USART1);
LL_USART_TransmitData8(USART1, cc);
LL_mDelay(130);
//LL_USART_ClearFlag_RXNE(USART1);
//NVIC_ClearPendingIRQ( USART1_IRQn );
/* USER CODE END USART1_IRQn 0 */
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
and in main.c I have:
LL_USART_EnableIT_RXNE(USART1);
while (1)
{
LL_mDelay(300);
LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);
LL_mDelay(300);
LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);
//LL_USART_EnableIT_TC(USART1);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
The GPIO_Toggle commands are just there to blink an led so I know what's going on. Here's waht happens: When I power the MC up, it enters the main loop and blinks slowly. When I send something (~10 bytes) through UART, the led starts blinking fast, indicating that it has entered the interrupt handler. PProblem is that it never stops and keeps spinning around in the interrupt handler.
I've tried using the now commented functions
LL_USART_ClearFlag_RXNE(USART1);
NVIC_ClearPendingIRQ( USART1_IRQn );
either alone or in combination but they have absolutely no effect on anything. What am I doing wrong? How can I exit the handler?
Upvotes: 2
Views: 3832
Reputation: 3618
The system time utilised for controlling delays is updated by a periodic sysTick interrupt. If the RXNE interrupt has a higher priority than the sysTick interrupt it won't be handled while you're inside your RXNE IRQ handler, so the time will never increment and your delay end time will never be reached. Depending on how your delay is implemented, it may just put the CPU in a spinlock that can never exit.
Upvotes: 1
Reputation: 67476
Actually everything in your USART interrupt handler is wrong.
You can't just read and write the data register when you want to. You need to know if you are allowed to
You should also control the error statuses.
Upvotes: 4