0

我正在使用 Redbear Arduino Library 为基于 nRF52 的板编写程序。有效地将我的电路板视为 BLE Nano 2。

我有一个计时器,每 x 毫秒计时一次,例如 50 毫秒。

在该计时器内,我想从 I2C 传感器读取数据并将读数添加到缓冲区。

我知道默认情况下,当在定时器 ISR 内时,中断被禁用。我想知道如何短暂地重新启用 I2C 中断,并获取传感器读数,然后再次禁用中断。

传感器读数之间的间隔很关键,我不只是想在计时器 ISR 中设置一个标志,因为我不知道在检查该标志之前需要多长时间。

请有人指导我如何从定时器 ISR 中简要启用 I2C 中断?

我已经尝试过:

__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);

}
4

1 回答 1

0

默认情况下,Cortex-M 上的 ISR 中不会禁用中断,而是根据 NVIC 中设置的优先级抢占中断(因此是 NVIC 的“嵌套”部分)。这意味着您应该像往常一样简单地启用 I2C 中断,然后使用NVIC_SetPriority(IRQn, priority).

但是请注意,优先级编号是按相反顺序排列的,因此优先级 0 会抢占优先级 6。在这种情况下,您可以将定时器中断优先级设置为 1,将 I2C 中断设置为 0。

于 2017-07-02T23:14:38.697 回答