Skip to main content
zhausq
Associate III
January 7, 2016
Question

[F103] USART IRQ fucks with I2C operation

  • January 7, 2016
  • 3 replies
  • 720 views
Posted on January 07, 2016 at 16:31

NVIC priority group is 0

USART priority is 15

I2C priority is 0

I2C exchanges data 100 times a second for minutes without any missed data or handups, if i activate USART it starts failing after seconds.

//nvic priority settings

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

//usart priority

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;

NVIC_Init(&NVIC_InitStructure);

//i2c initialisation

void i2c_init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

I2C_InitTypeDef I2C_InitStructure;

i2c_error = 0;

SystemInit();

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);

/*CLOCK OUT GARBAGE*/

//initialize i2c pins as normal gpio

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    //clock out garbage

    for (int i = 0; i < 12; i++) {

           GPIO_ResetBits(GPIOB, GPIO_Pin_10);

           delay_ms(2);

           GPIO_SetBits(GPIOB, GPIO_Pin_10);

           delay_ms(2);

    }

    //generate start&stop

    GPIO_ResetBits(GPIOB, GPIO_Pin_11); //sda low

    delay_ms(2);

    GPIO_ResetBits(GPIOB, GPIO_Pin_10); //scl low

    delay_ms(2);

    GPIO_SetBits(GPIOB, GPIO_Pin_10); //scl high

    delay_ms(2);

    GPIO_SetBits(GPIOB, GPIO_Pin_11); //sda high

/*CLOCK OUT GARBAGE*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = I2C2_ER_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

I2C_DeInit(I2C2);

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

I2C_InitStructure.I2C_ClockSpeed = 100000;

I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

I2C_InitStructure.I2C_OwnAddress1 = 0;

I2C_Init(I2C2, &I2C_InitStructure);

I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE);

I2C_ITConfig(I2C2, I2C_IT_BUF, ENABLE);

I2C_ITConfig(I2C2, I2C_IT_ERR, ENABLE);

I2C_Cmd(I2C2, ENABLE);

}

am i missing something here?

it is my understanding that i2c should be able to interrupt usart and therefore not be bothered by usart, please help!

#stm32-f1-usart-i2c-irq-problem
This topic has been closed for replies.

3 replies

jpeacock
Associate
January 7, 2016
Posted on January 07, 2016 at 19:47

What is the error reported by I2C?  How do you know it isn't the USART that's the problem?  How did you configure the NVIC priority grouping?  Try changing the I2C priority to 1.

  Jack Peacock

zhausq
zhausqAuthor
Associate III
January 8, 2016
Posted on January 08, 2016 at 02:14

Thank you for your fast reply.

Priority grouping is 0, I tried changing I2C to 1 but that didn't help. Removing a while(!(USART1->SR & 0x00000040)); from the USART interrupt did however.

I still don't know how that works as how I understand it I2C should interrupt the USART interrupt but I will figure that out later, at the moment it works and that must do for now.

John F.
Associate III
January 8, 2016
Posted on January 08, 2016 at 12:55

You chose NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

The function documentation clearly states,

''When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.

The pending IRQ priority will be managed only by the subpriority.''