Включение прерывания I2C при прерывании по таймеру на nRF52 Arduino

Я пишу программу для платы на базе nRF52 с использованием библиотеки Redbear Arduino. Эффективно трактую мою доску как BLE Nano 2.

У меня есть таймер, который тикает каждые x миллисекунд, например, 50 мс.

В этом таймере я хотел бы прочитать данные с датчика I2C и добавить показания в буфер.

Мне известно, что по умолчанию, когда внутри таймера ISR прерывания отключены. Я хотел бы знать, как кратковременно повторно включить прерывание I2C и получить показания датчика, а затем снова отключить прерывания.

Интервал между показаниями датчика является критическим, и я не просто хочу установить флаг в ISR таймера, поскольку я не знаю, сколько времени пройдет до того, как этот флаг будет проверен.

Кто-нибудь может подсказать, как кратко включить прерывания I2C из таймера ISR?

Я экспериментировал с:

__disable_irq();

__enable_irq();

NVIC_EnableIRQ(SPI0_TWI0_IRQn);

NRF_TWI0->INTENSET = 1;

Я не рад ни с одним из них, я понимаю, что некоторые из них работают только в определенных местах программного обеспечения, поэтому не работали правильно в ISR.

void setup() {
  // put your setup code here, to run once
  NVIC_SetPriority (TIMER0_IRQn, 2);
  NVIC_SetPriority (TIMER1_IRQn, 2);
  NVIC_SetPriority (TIMER2_IRQn, 2);
  NVIC_SetPriority (SPI0_TWI0_IRQn, 3);
  NVIC_SetPriority (SPI1_TWI1_IRQn, 3);
  Serial.begin(9600);
  Serial.println("Start ");
  Serial.print("Priority of TWI0: ");
  Serial.println(NVIC_GetPriority (SPI0_TWI0_IRQn));
  Serial.println(NVIC_GetPriority (SPI1_TWI1_IRQn));
  Serial.print("Priority of Ticker: ");
  Serial.println(NVIC_GetPriority (TIMER0_IRQn));
  Serial.println(NVIC_GetPriority (TIMER1_IRQn));
  Serial.println(NVIC_GetPriority (TIMER2_IRQn));


  Wire.begin();
  __disable_irq();
  __enable_irq();
  ticker1s.attach(task_handle, 1);
  Wire.requestFrom(0x02,6);

}

void task_handle(void) {
  __enable_irq();
  Serial.println("Task handle ");
  Serial.println("-IRQ enable status: ");
  Serial.println(NVIC_GetEnableIRQ(SPI0_TWI0_IRQn));
  Serial.println(NVIC_GetEnableIRQ(SPI1_TWI1_IRQn));
  NVIC_EnableIRQ(SPI0_TWI0_IRQn);
  NRF_TWI0->INTENSET = 1;

  NVIC_EnableIRQ(SPI1_TWI1_IRQn);
  NRF_TWI1->INTENSET = 1;
  Serial.println("-IRQ enable status: ");
  Serial.println(NVIC_GetEnableIRQ (SPI0_TWI0_IRQn));
  Serial.println(NVIC_GetEnableIRQ (SPI1_TWI1_IRQn));
  delay(1000);
  Wire.requestFrom(0x02,6);

}

1 ответ

По умолчанию прерывания не отключаются в ISR на Cortex-M, а прерывания прерываются на основе приоритетов, установленных в NVIC (отсюда и "вложенная" часть NVIC). Это означает, что вы должны просто включить прерывание I2C, как обычно, и затем установить приоритет, используя NVIC_SetPriority(IRQn, priority),

Тем не менее, обратите внимание, что номера приоритетов упорядочены в обратном порядке, поэтому приоритет 0 будет означать приоритет, скажем, 6. В этом случае вы должны установить приоритеты прерываний от таймера, скажем, 1, а прерывание I2C - 0.

Другие вопросы по тегам