首页 文章

在nRF52 Arduino上的定时器中断内启用I2C中断

提问于
浏览
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);

}

1 回答

  • 0

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

    但请注意,优先级编号是反向排序的,因此优先级为0将优先于6的优先级 . 在这种情况下,您可以将定时器中断优先级设置为1,将I2C中断设置为0 .

相关问题