Задать вопрос
@Kopranych

STM32F4 discovery как заставить работать прерывания по шине I2C?

Работая по шине i2c в режиме ожидания флагов контроллер получает данные. Решил сделать работу на прерываниях но после генерации условия START прерывания не происходит программа выполняется дальше. Может неправильная инициализация? Подскажите кто знает.
Код:
void I2C_init(void)
{
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//тактируем пины для i2c
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);//тактируем сам i2c
   //--------------------------------------------
   GPIO_InitTypeDef busi2c;//создаем структуры 
   I2C_InitTypeDef i2c;//для инициализации
   //------------------------------------
   i2c.I2C_ClockSpeed = 100000;//100kHz
   i2c.I2C_Mode = I2C_Mode_I2C;
  i2c.I2C_DutyCycle = I2C_DutyCycle_2;
  i2c.I2C_OwnAddress1 = OWNADRESS;
  i2c.I2C_Ack = I2C_Ack_Enable;
  i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_Init(I2C1, &i2c);
   //---------------------------------------
   busi2c.GPIO_Pin = BUS_SCL|BUS_SDA;
   busi2c.GPIO_Mode = GPIO_Mode_AF;
   busi2c.GPIO_Speed = GPIO_Speed_2MHz;
   busi2c.GPIO_OType = GPIO_OType_OD;
   busi2c.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_Init(GPIOB, &busi2c);
   //---------------------------------------------
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);//включаем альтернативные 
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);//функции ножек
   //----------------------------------------------
   I2C_Cmd(I2C1, ENABLE);//включаем модуль i2c
   
}

void init_IT_i2c(void)
{

   NVIC_InitTypeDef IT_i2c;
   
   IT_i2c.NVIC_IRQChannel = I2C1_EV_IRQn;//прерывания по событию
   IT_i2c.NVIC_IRQChannelPreemptionPriority = 0;//приоритет прерывания чем ниже значение тем выше приоритет
   IT_i2c.NVIC_IRQChannelSubPriority = 0;//Sub приоритет прерывания чем ниже значение тем выше приоритет
   IT_i2c.NVIC_IRQChannelCmd = ENABLE;//включение параметра канала прерывания
   NVIC_Init(&IT_i2c);//инициализируем прерывание

   IT_i2c.NVIC_IRQChannel = I2C1_ER_IRQn;//прерывания по ошибке
   IT_i2c.NVIC_IRQChannelPreemptionPriority = 0;//приоритет прерывания чем ниже значение тем выше приоритет
   IT_i2c.NVIC_IRQChannelSubPriority = 0;//Sub приоритет прерывания чем ниже значение тем выше приоритет
   IT_i2c.NVIC_IRQChannelCmd = ENABLE;//включение параметра канала прерывания
   NVIC_Init(&IT_i2c);

   
   I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);//включили прерывания по событию
   I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);//включили прерывания по ошибке

}

void I2C_start_IT(void)
{
   // ждем освобождения шины
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
   I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);//включаем прерывания для буфера приема и передачи
   I2C_GenerateSTART(I2C1, ENABLE);//генерируем старт
}

После генерации START зажигается флаг SB но прерывания не срабатывают
  • Вопрос задан
  • 1514 просмотров
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
Roon_Boh
@Roon_Boh
Сломав зубы о гранит, продолжаю его рассасывать
Ебани перемычку на любую ногу, и по этой ноге ебани прерывание по изменению состояния, но не забывай вырубать прерывание при приёме передаче данных, а то оно у тебя как бы срабатывать не будет, на самом деле при поступлении нового бита будит занаво срабатывать.
Ответ написан
Комментировать
@itxs
Инженер-электронщик
1) В прерывании нужно очищать флаг происхождения прерывания, иначе после одного срабатывания при включении больше срабатывать не будет.
2) NVIC попроще инитьте: NVIC_EnableIRQ(I2C1_EV_IRQn); NVIC_EnableIRQ(I2C1_ER_IRQn);
3) Имена функций прерываний нужно брать из .s файла в проекте, где они прилинкованы в область векторов прерываний. I2C_start_IT(void) здесь размещается совсем не в области векторов вот и не работает.
4) Прерывания самой периферии (I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE); и т.д.) нужно включать в коде инициализации этой периферии.
Ответ написан
@Kopranych Автор вопроса
Теперь датчик совсем не хочет отвечать код виснет в режиме подтверждения адреса и все тут:
[CODE]while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));[/CODE]
Хотя я что то кардинальное в коде не менял. Может датчик сдох, потому что не отвечает даже на рабочей версии кода когда все без прерываний? Как проверить датчик у меня MPU6050 гироскоп?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы