Arduino Zero - управление шаговым двигателем (прерывание)?
У меня есть плата контроллера шагового двигателя, которая должна пульсировать каждые 40 мкс или около того.
У меня также есть датчики I2C и последовательная запись в преформу.
В настоящее время я запускаю вызов обновления в тесном цикле, но датчики I2C и последовательные записи вызывают значительные задержки, из-за которых моторы заикаются и останавливаются.
Я хотел бы использовать ISR для периодического вызова метода обновления мотора.
Однако я ни за что не могу разобраться с этим таймером.
Вот моя текущая попытка:
void TC4_Handler() {
Stepper::updateAll();
}
void setup() {
// Таймеры
// Настраиваем общие часы (GCLK4), используемые для тактирования таймеров
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | // Делим источник тактовой частоты 48 МГц на делитель 1: 48 МГц/1=48 МГц
GCLK_GENDIV_ID(4); // Выбор общих часов (GCLK) 4
while (GCLK->STATUS.bit.SYNCBUSY); // Ждем синхронизации
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | // Установите рабочий цикл на 50/50 ВЫСОКИЙ/НИЗКИЙ
GCLK_GENCTRL_GENEN | // Включить GCLK4
GCLK_GENCTRL_SRC_DFLL48M | // Установите источник тактовой частоты 48 МГц
GCLK_GENCTRL_ID(4); // Выбираем GCLK4
while (GCLK->STATUS.bit.SYNCBUSY); // Ждем синхронизации
// Подача GCLK4 на TC4 и TC5
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Включить GCLK4 для TC4 и TC5
GCLK_CLKCTRL_GEN_GCLK4 | // Выбираем GCLK4
GCLK_CLKCTRL_ID_TC4_TC5; // Подача GCLK4 на TC4 и TC5
while (GCLK->STATUS.bit.SYNCBUSY); // Ждем синхронизации
REG_TC4_COUNT16_CC0 = 0x000F; // Установить регистр TC4 CC0 в качестве значения TOP в режиме совпадения частот
while (TC4->COUNT16.STATUS.bit.SYNCBUSY); // Ждем синхронизации
//NVIC_DisableIRQ(TC4_IRQn);
//NVIC_ClearPendingIRQ(TC4_IRQn);
NVIC_SetPriority(TC4_IRQn, 0); // Установите приоритет Nested Vector Interrupt Controller (NVIC) для TC4 на 0 (самый высокий)
NVIC_EnableIRQ(TC4_IRQn); // Подключаем TC4 к вложенному контроллеру векторных прерываний (NVIC)
REG_TC4_INTFLAG |= TC_INTFLAG_OVF; // Сбрасываем флаги прерывания
REG_TC4_INTENSET = TC_INTENSET_OVF; // Разрешить прерывания TC4
// REG_TC4_INTENCLR = TC_INTENCLR_OVF; // Отключить прерывания TC4
REG_TC4_CTRLA |= TC_CTRLA_PRESCALER_DIV1024 | // Установите прескалер на 1024, 48 МГц/1024 = 46,875 кГц
TC_CTRLA_WAVEGEN_MFRQ | // Переводим таймер TC4 в режим согласования частоты (MFRQ)
TC_CTRLA_ENABLE; // Включить TC4
while (TC4->COUNT16.STATUS.bit.SYNCBUSY); // Ждем синхронизации
// ...
}
@Cody Smith, 👍0
1 ответ
Поскольку Stepper::updateAll();
не отображается, я не знаю, что он делает. Для точной синхронизации имеет смысл использовать аппаратно управляемые выходные контакты сравнения вывода, такие как TIOAx и TIOBx, вместо того, чтобы запускать какой-либо код для управления выводами при возникновении прерывания.
Если вам нужно управлять несколькими проводами на двигатель, так что импульса на одной выходной линии недостаточно, вы можете рассмотреть возможность использования 74HC595 (или другого регистра сдвига) для передачи битов. Таким образом, каждый раз, когда происходит сравнение выходных данных, линии TIOAx и TIOBx будут посылать импульсы на линию ST_CLK (хранение-часы) SR для передачи битов с триггеров цепочки сдвига на выходные триггеры; затем, на досуге, процедура прерывания может сместить следующий набор битов в '595, готовый к передаче в нужный момент, когда произойдет следующее сравнение выходных данных.
Во время шагового ускорения или замедления лимит счетчика таймера также необходимо обновить в ISR.
- Использование millis() и micros() внутри процедуры прерывания
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Использование TIMER0_COMPB_vect
- 4-битный счетчик вверх и вниз
- Включить и отключить отдельные прерывания
- ATtiny85 AC Phase Control для регулировки яркости лампочки
- Присоедините функцию Arduino ISR к члену класса
- Быстрее TimerOne с Teensy 4.0 (600 МГц)
Я использую этот драйвер https://www.pololu.com/product/2975, все, что делает Stepper::updateAll(), это проверяет, нужно ли импульсировать шаговый штифт., @Cody Smith
В этом случае вы должны использовать линию TIOAx или TIOBx для подачи импульса на A4988 и должны рассчитать ограничения счетчика таймера для установки ISR. Другими словами, не «проверяйте, нужно ли импульсировать шаговый штифт», что равносильно попытке запустить шаговый двигатель с использованием опроса, что является плохой идеей, а вместо этого вычислите, когда шаговый штифт должен быть импульсным, установите таймер. соответственно и есть таймер импульса А4988., @James Waldby - jwpat7