Nano Hash - криптовалюты, майнинг, программирование

Включение прерывания 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);

}
01.07.2017

  • Я также пробовал использовать NVIC_GetPriority и NVIC_SetPriority, чтобы сделать все прерывания SPIx_TWIx_IRQn как выше, так и ниже, чем приоритет всех приоритетов TIMERx_IRQn. NVIC_GetPriority подтверждает, что приоритеты были установлены, но все равно без радости 01.07.2017

Ответы:


1

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

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

02.07.2017
  • Спасибо, я предположил, что это так, и я попытался установить все приоритеты таймера на 2 и все прерывания SPIx_TWIx на 1, а затем в отдельном тесте на 3. Я проверил, что это было установлено с помощью NVIC_GetEnableIRQ, и они, похоже, были сообщая их правильные значения, но мой вызов I2C все еще вызывает зависание моей программы, если я использую его в таймере ISR 03.07.2017
  • @Steve Я вижу, что вы включили свой скетч, однако я заметил, что ISR для контроллеров I2C отсутствует, по умолчанию я не думаю, что ядро ​​Arduino использует прерывание для обработки I2C, поэтому, когда вы включаете прерывание, оно переходит к обработчику по умолчанию , который представляет собой бесконечный цикл. Вероятно, это объясняет зависание. 03.07.2017
  • Кроме того, я заметил, что вы используете объект Ticker в качестве своего таймера, однако имейте в виду, что они обычно реализуются с использованием таймера SysTick, доступного на каждом Cortex-M, и его приоритет прерывания отделен от обычных таймеров, доступных на NRF52. 03.07.2017
  • Спасибо за ваши комментарии. Я не очень понимаю причину зависания. Вызов I2C отлично работает вне таймера ISR, но не внутри него. Не могли бы вы подсказать, как я могу заставить вызов I2C работать в этой (или другой) ISR на основе таймера? 03.07.2017
  • Вы пробовали просто вызвать функцию I2C, не разрешая прерывание для I2C? Как я уже упоминал, код Arduino I2C не использует прерывания. 03.07.2017
  • спасибо за ваши предложения. Мы перешли к использованию таймера, а не тикера, и смогли заставить все работать. Если вы хотите написать свой комментарий в качестве ответа, я с радостью его приму. Спасибо! 25.07.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..