cancel
Showing results for 
Search instead for 
Did you mean: 

USART1 IRQ Handler Problem

WPong.1
Associate II

Hello everyone, I use STM32F103C8 and try to receive data via USART1 using DMA and IDLE. When I receive 1 character and IDLE occur then USART1 interrupt was generated and call "USART1_IRQHandler" function like this.

void USART1_IRQHandler(void)
{
	count = count + 1;
}

But count not increse by 1. Its value is big increse.

main.c

int count=0;
 
int main()
{
	system_clock_config();
	uart1_rx_Init();
	NVIC_EnableIRQ(USART1_IRQn);
	DMA1_channel5_init((uint32_t) RES_CMD, (uint32_t) &USART1->DR, 4);
	while(1)
	{
	
	}
}

uart1_rx_Init

void uart1_rx_Init(void)
{
	
	/*Enable IO Port A*/
	RCC->APB2ENR	|=	(1U<<2);
	
	/*Enable UART1*/
	RCC->APB2ENR |= 	(1U<<14);
	
	/*Set Port A Pin10 As Input Pull-up Pull-down*/
	GPIOA->CRH		|=	(1U<<10);
	
	/*Set Buad Rate 9600*/
	USART1->BRR		|=	0x1D4C;
	
	/*Enable IDLE Line*/
	USART1->CR1	|=	(1U<<4);
	
	/*Enable Receiver*/
	USART1->CR1		|=	(1U<<2);
	
	/*Enable UART*/
	USART1->CR1		|=	(1U<<13);
	
}

DMA1_channel5_init

void DMA1_channel5_init(uint32_t src, uint32_t dst, uint32_t len)
{
	/*Enable Clock Access To DMA*/
	RCC->AHBENR		|=	(1U<<0);
	
	/*Disable DMA1 Channel5*/
	DMA1_Channel5->CCR	&= ~(1U<<0);
	
	/*Wait For DMA1 Channel5 is Disable*/
	while(DMA1_Channel5->CCR & (1U<<0)){}
		
	/*Clear All Interrupt Flags of Channel5*/
	DMA1->IFCR	|=	(1U<<16);
	DMA1->IFCR	|=	(1U<<17);
	DMA1->IFCR	|=	(1U<<18);
	DMA1->IFCR	|=	(1U<<19);
	
	/*Set the Destination Buffer*/
	DMA1_Channel5->CPAR		=	dst;
	
	/*Set the Source Buffer*/
	DMA1_Channel5->CMAR		=	src;
	
	/*Set Length*/
	DMA1_Channel5->CNDTR	=	len;
	
	/*Enable Memory Increment*/
	DMA1_Channel5->CCR	|=	(1U<<7);
	
	/*Enable Circular Mode*/
	DMA1_Channel5->CCR	&=	~(1U<<5);
	
	/*Configure Transfer Direction*/
	DMA1_Channel5->CCR	&=	~(1U<<4);
	
	/*Enable DMA Transfer Complete Interrupt*/
	//DMA1_Channel5->CCR	|=	(1U<<1);
	
	/*Enable DMA1 Channel5*/
	DMA1_Channel5->CCR	|=	(1U<<0);
	
	/*Enable UART1 Transmitter DMA*/
	USART1->CR3	|=	(1U<<6);
	
}

1 ACCEPTED SOLUTION

Accepted Solutions
KnarfB
Principal III

A peripheral IRQ handler will typically first analyze why exactly it was called by inspecting the correspondig bits in the peripheral registers, and finally clear the bit/flag/irq condition before leaving the handler. If you don't clear the right bit(s) the handler will be called again and again...

For some code see https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx/tree/main/projects/usart_rx_idle_line_irq_F1

hth

KnarfB

View solution in original post

1 REPLY 1
KnarfB
Principal III

A peripheral IRQ handler will typically first analyze why exactly it was called by inspecting the correspondig bits in the peripheral registers, and finally clear the bit/flag/irq condition before leaving the handler. If you don't clear the right bit(s) the handler will be called again and again...

For some code see https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx/tree/main/projects/usart_rx_idle_line_irq_F1

hth

KnarfB