cancel
Showing results for 
Search instead for 
Did you mean: 

USART IDLE interrupt with DMA problem

parisa
Senior
Posted on September 11, 2016 at 06:59

Hello

I have tried to use USART IDLE interrupt to align my buffer position in right address.

#include <
stm32f10x_gpio.h
>
#include <
stm32f10x_rcc.h
>
#include <
stm32f10x_usart.h
>
#include <
stm32f10x_usart.h
>
#include <
stdio.h
>
#include <
stm32f10x_dma.h
>
struct __FILE { int handle;} ;
FILE __stdout;
FILE __stdin;
FILE __stderr;
char buffer[10];
int x;
DMA_InitTypeDef DMAStruc;
int fputc(int ch, FILE *f) 
{
while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE)); 
USART_SendData(USART1,ch); 
return ch; 
}
void dmas(void){
DMA_DeInit(DMA1_Channel5);
DMAStruc.DMA_PeripheralBaseAddr=(uint32_t) &USART1->DR;
DMAStruc.DMA_MemoryBaseAddr=(uint32_t) buffer; 
DMAStruc.DMA_DIR=DMA_DIR_PeripheralSRC;
DMAStruc.DMA_BufferSize=sizeof(buffer)-1;
DMAStruc.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
DMAStruc.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMAStruc.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
DMAStruc.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
DMAStruc.DMA_Mode=DMA_Mode_Circular;
DMAStruc.DMA_Priority=DMA_Priority_High;
DMAStruc.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5,&DMAStruc);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC | DMA_IT_TE, ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
}
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)
{
DMA_Cmd(DMA1_Channel5, DISABLE);
USART_ClearITPendingBit(USART1, USART_IT_IDLE);
dmas();
}
} 
void delay()
{
int i,j;
for(i=0;i<
10000
;i++)
for(
j
=
0
;j<250;j++);
}
void config(void){
GPIO_InitTypeDef GPIOStruc;
USART_InitTypeDef USAR;
x
=
0
;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//PD5
GPIOStruc.GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIOStruc.GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIOStruc.GPIO_Pin
=
GPIO_Pin_6
;
GPIO_Init(GPIOB,&GPIOStruc);
//PD6
GPIOStruc.GPIO_Mode
=
GPIO_Mode_IN_FLOATING
;
//
GPIOStruc.GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIOStruc.GPIO_Pin
=
GPIO_Pin_7
;
GPIO_Init(GPIOB,&GPIOStruc);
USAR.USART_BaudRate
=
9600
;
USAR.USART_StopBits
=
USART_StopBits_1
;
USAR.USART_WordLength
=
USART_WordLength_8b
;
USAR.USART_Parity
=
USART_Parity_No
;
//
USAR.USART_Parity
=
USART_Parity_Even
;
USAR.USART_HardwareFlowControl
=
USART_HardwareFlowControl_None
;
USAR.USART_Mode
=
USART_Mode_Rx
| USART_Mode_Tx;
USART_Init(USART1,&USAR);
USART_Cmd(USART1,ENABLE);
USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
NVIC_EnableIRQ(USART1_IRQn);
GPIOC->CRL=(2<< 
8
);
GPIOC->BSRR=(1<<
2
);
}
void DMA1_Channel5_IRQHandler(void) 
{
if (DMA_GetITStatus(DMA1_IT_TC5))
{
x
=x+1;
DMA_ClearITPendingBit(DMA1_IT_TC5 | DMA1_IT_GL5);
GPIOC->BSRR=(1<<
18
);
printf(''%s'',buffer); 
}
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel
= 
DMA1_Channel5_IRQn
;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
= 
0
;
NVIC_InitStructure.NVIC_IRQChannelSubPriority
= 
0
;
NVIC_InitStructure.NVIC_IRQChannelCmd
= 
ENABLE
;
NVIC_Init(&NVIC_InitStructure);
}
int main(){
config();
NVIC_Configuration();
dmas();
while(1)
{
// GPIOC->BSRR=(1<<2);
printf(''Hello the(%d) world\n\r'',x);
delay();
//delay();
}
}

But unfortunately it doesn't work properly. when I send ''123456789'' my device print 123456789 immediately(as you can see in dma interrupt) and it repeat usart idle interrupt again and again and it doesn't print ''Hello ... world'' until I send a char. what is my mistake?
0 REPLIES 0