2022-04-19 02:49 AM
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);
}
Solved! Go to Solution.
2022-04-19 03:38 AM
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
2022-04-19 03:38 AM
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