Быстрее TimerOne с Teensy 4.0 (600 МГц)
У меня есть teensy 4.0, работающая на частоте 600 МГц и обладающая двойным супермасштабированием (т. е. иногда может выполнять две инструкции за такт). Мне нужно, чтобы прерывание происходило быстрее, чем каждую микросекунду. Я подсчитал, что процессор может выполнять мой код на такой скорости с некоторыми разумными накладными расходами. Можно ли настроить TimerOne (или аналогичный) для создания прерываний чаще одного раза в микросекунду?
Заранее спасибо.
@Jachdich, 👍1
Обсуждение2 ответа
Для этого можно использовать TeensyTimerTool. Он предоставляет общий интерфейс для аппаратных таймеров (TMR, GPT, PIT) и 20 программных таймеров. Поскольку соединение периферийных устройств таймера с ядром ARM довольно неэффективно, программные таймеры могут лучше подходить для прерываний менее микросекунды. Если вы предпочитаете аппаратные таймеры, я предлагаю использовать таймер GPT (также поддерживается библиотекой). Вы можете настроить его на использование тактовой частоты 150 МГц вместо стандартной тактовой частоты 24 МГц. Таким образом, что-то вроде частоты прерывания 2 МГц должно быть возможным.
Документацию можно найти здесь: https://github.com/luni64/TeensyTimerTool/wiki
У меня была похожая проблема с Teensy 3.5. Я обнаружил, что использование «Таймера периодического прерывания (PIT)»; позвольте мне генерировать прерывания каждые 300 нс. Я полагаю, что с Teensy 4.0 должна быть возможность генерировать прерывание каждые 100 нс. Вот код, который работает у меня на Teensy 3.5: с комментариями на французском языке и некоторыми ссылками в комментариях. Я проверяю сигнал на осциллографе.
// ex00305_Timer_pit0_isr_rapid.ino
/*
FONCTIONNE TRES BIEN
Le signal n'est pas très stable, mais acceptable.
J'imagine que d'autres routines d'interruption perturbe la précision, comme la routine millis()
L'instruction suivante améliore la stabilité. visiblement.
NVIC_SET_PRIORITY(IRQ_PIT_CH0, 0);
Le but est de tester l'utilisation du Timer1 .c.f
/home/bg/Arduino/Teensy/Teensy_3_5_manual_K64P144M120SF5RM.pdf
Page 1083, Chapter 41 : "Periodic Interrupt Timer (PIT)"
Pour la gestion des timers PIT, c.f.
====================================
https://github.com/loglow/PITimer/blob/master/PITimer.cpp
********************************************************************************** */
#define PINOUT1 34
#define LEDRED 24
#define LEDYELLOW 25
#define LEDGREEN 26
volatile byte bEtat = 0;
void setup() {
//============
pinMode(PINOUT1, OUTPUT);
digitalWriteFast(PINOUT1, HIGH);
pinMode(33, OUTPUT);
pinMode(34, OUTPUT);
pinMode(LEDRED, OUTPUT); digitalWriteFast(LEDRED, LOW);
pinMode(LEDYELLOW, OUTPUT); digitalWriteFast(LEDYELLOW, LOW);
pinMode(LEDGREEN, OUTPUT); digitalWriteFast(LEDGREEN, LOW);
//если (SIM_SCGC6_PIT == 0b100000000000000000000000) digitalWriteFast(LEDYELLOW, HIGH);
SIM_SCGC6 |= SIM_SCGC6_PIT; // См. страницу 317. PIT Clock Gate Control SIM_SCGC6_PIT == 0b100000000000000000000000
// См.: /home/bg/.arduino15/packages/teensy/hardware/avr/1.58.1/cores/teensy3/kinetis.h
// #define NVIC_ENABLE_IRQ(n) (*(( Летучие uint32_t *)0xE000E100 + ((n) >> 5)) = (1 << ((n) & 31)))
// включаем прерывание IRQ
NVIC_SET_PRIORITY(IRQ_PIT_CH0, 0); // Высший приоритет, чтобы не беспокоить другие прерывания. Улучшение заметно!
NVIC_ENABLE_IRQ(IRQ_PIT_CH0);
PIT_TCTRL0 = 3; // 0b011; // разрешаем прерывания Таймера 0; запуск таймера 0 IRQ_PIT_CH0 == 48 Dans #elif определено(__MK64FX512__)
//если (IRQ_PIT_CH0 == 48) digitalWriteFast(LEDGREEN, HIGH);
// Стирание флага таймера, чтобы разрешить другие прерывания, необходимо завершить работу
PIT_TFLG0 = 1;
// Порядок инструкций по важности !
//"""""""""""""""""""""""" """"""""""""""""""""
PIT_MCR = 0; // включаем PIT
//PIT_LDVAL0 = 600-1; // == таймер настройки 10 микросекунд 0 для xxx циклов Fréqu = 60 МГц dt = 16,666 нс
//PIT_LDVAL0 = 120-1; // == 2-секундные микрофоны
//PIT_LDVAL0 = 60-1; // == 1 секундный микрофон
//PIT_LDVAL0 = 30-1; // == 500 нс
//PIT_LDVAL0 = 24-1; // == 400 нс
//PIT_LDVAL0 = 21-1; // == 350 нс
//PIT_LDVAL0 = 20-1; // == 333 нс
//PIT_LDVAL0 = 18-1; // == 300 нс
PIT_LDVAL0 = 120-1;
} // настраивать
void loop() {
//===========
} // петля
void pit0_isr() { // См. mk20dx128.c
//===============
// Надеюсь, что смогу продержаться некоторое время
// Очистим флаг таймера, чтобы разрешить дальнейшие прерывания
// Doit être неправильно дебютирует в рутине !!!
PIT_TFLG0 = 1;
if (bEtat) {
digitalWriteFast(PINOUT1, HIGH);
//digitalWriteFast(LEDRED, HIGH);
bEtat = 0;
}
else {
bEtat = 1;
digitalWriteFast(PINOUT1, LOW);
//digitalWriteFast(LEDRED, LOW);
}
} //pit0_isr
- Использование millis() и micros() внутри процедуры прерывания
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Использование TIMER0_COMPB_vect
- 4-битный счетчик вверх и вниз
- Включить и отключить отдельные прерывания
- ATtiny85 AC Phase Control для регулировки яркости лампочки
- Присоедините функцию Arduino ISR к члену класса
- Прерывание переполнения Timer0 не работает
Вы про библиотеку
TimerOne
или про сам таймер?, @chrisl@chrisl хорошо, я использовал библиотеку TimerOne, но если единственный способ получить более быстрое прерывание - не использовать эту библиотеку, то меня это устраивает., @Jachdich
https://forum.pjrc.com/, @Juraj