Question
USART2 - I2C1 problem in STM32F1
Posted on March 14, 2014 at 14:28
When I send data to the USART2 it's well received BUT after that the last data character keeps being received until filling up my reception buffer. Note that in the same application I'm also using I2C1 to transmit other data.
After some debugging, I went through the STM32F103RGproduct manual , page 272, figure 50 - DMA1 Request Mapping picture states that the USART2 and I2C1 share the DMA1 channels. I kept doing some testing, concluding that this happens whenusing: - USART2 with DMA RX enabled, and - I2C1 in master mode using the IRQ Handlers as in ''OptimizedI2Cexamples'', EVENwith DMA disabled.
I can avoid this problem making 2 tricks: 1) Or disabling the USART2 DMA. 2) Orwritinginto the I2C1 usingthe ''I2C_CheckEventfunction''way,
instead of using the I2C1 IRQ Handlers way as in''OptimizedI2Cexamples''.
Well, I don't know exactly why this problem occurs. Is there any kind of incompatibility between the USART2 with DMA mode and the I2C1 with IRQ Handlers? This is my USART2 configuration:RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
USART_DeInit(USART2);
USART_StructInit(&USART_InitStruct);
USART_InitStruct.USART_BaudRate = 57600;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_Mode = (USART_Mode_Rx | USART_Mode_Tx);
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2, &USART_InitStruct);
USART_ClearFlag(USART2, USART_FLAG_RXNE | USART_FLAG_TC);
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
This is the DMA configuration:
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel6);
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_PeripheralBaseAddr = USART2->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = rx_buf;
DMA_InitStructure.DMA_BufferSize = rx_buf_sz;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
And the I2C configuration:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_DeInit(I2C1 );
I2C_ClearFlag(I2C1, I2C_FLAG_SMBALERT | I2C_FLAG_TIMEOUT | I2C_FLAG_PECERR | I2C_FLAG_OVR | I2C_FLAG_AF | I2C_FLAG_ARLO | I2C_FLAG_BERR);
I2C_ClearITPendingBit(I2C1, I2C_IT_SMBALERT | I2C_FLAG_TIMEOUT | I2C_IT_PECERR | I2C_IT_OVR | I2C_IT_AF | I2C_IT_ARLO | I2C_IT_BERR);
I2C_ITConfig(I2C1,I2C_IT_EVT,ENABLE);
I2C_ITConfig(I2C1,I2C_IT_ERR,ENABLE);
I2C_ITConfig(I2C1,I2C_IT_BUF,ENABLE);
I really hope to hear from you :p
#uart-dma-i2c-stm32f1