Проблема с использованием micros() вместо millis()
У меня есть две реализации функций, которые, как я ожидал, будут работать одинаково:
#define HEAD_STEP_DELAY 1000
unsigned long HeadLastMicros;
void HeadUpdate()
{
if ((micros()>=HeadLastMicros) && ((micros()-HeadLastMicros)<HEAD_STEP_DELAY)) {
return;
}
HeadLastMicros = micros();
HeadStep(true);
}
и
#define HEAD_STEP_DELAY 1
unsigned long HeadLastMillis;
void HeadUpdate()
{
if ((millis()>=HeadLastMillis) && ((millis()-HeadLastMillis)<HEAD_STEP_DELAY)) {
return;
}
HeadLastMillis = millis();
HeadStep(true);
}
Я знаю, что разрешение micros()
ограничено примерно 8us, но я полагаю, что, учитывая, что у меня ожидание 1000us, оба вышеперечисленных параметра должны быть относительно близки к одному и тому же поведению. Я управляю шаговым двигателем с помощью этого кода, и шаговый двигатель, который использовал micros()
, вел себя неустойчиво. Я еще не навел на него оптический прицел, так что не знаю наверняка, но крутящий момент был значительно меньше (мотор легко глох), и он звучал шатко.
Я использую ATMEGA324A вместе с библиотекой MightyCore.
Есть ли что-то неправильное в моем подходе? Спасибо.
РЕДАКТИРОВАТЬ: я поместил область действия на него после моего первоначального сообщения, и период кода micros () составляет примерно половину периода кода millis ().
@smbaker, 👍-1
1 ответ
Во-первых, когда имеешь дело с системой времени, которая постоянно меняется, не сравнивай два раза. Сравните различия.
Во-вторых, кэшируйте результаты вызова функции, если вы собираетесь использовать ее более одного раза.
В-третьих, если вам нужен постоянный временной интервал, попросите об этом. Ваш текущий код на основе micros() вполне может занять 1990 мкс на одних итерациях и 1001 мкс на других.
В-четвертых, не используйте текущее время более одного раза...
Сделайте что-то вроде (не указывая millis() или micros()):
unsigned long HeadLast; /* Это должно быть где-то инициализировано (HeadStart()?),
потому что в противном случае все может пойти странно.
На платформе Arduino инициализация равна 0
может сработать. В других системах время может начаться в любой момент.
Это привело к тому, что у Microsoft Windows возникли проблемы после
работает в течение 49 дней (начато с 0), в то время как X Windows
не имеет такой проблемы (запускайте в любое время).
*/
void HeadUpdate()
{
/* скомпилируйте с помощью -O, и это оптимизирует работу с регистром. */
unsigned long now = get_time_function();
/* Нам не нужно тестировать сейчас >= HeadLast, так как время монотонно. */
if ((now-HeadLast)<HEAD_STEP_DELAY)) {
return;
}
/* Выберите время, в которое, по нашему мнению, это началось.
Это вполне может произойти раньше текущего времени. */
HeadLast += HEAD_STEP_DELAY;
HeadStep(true);
}
- Использовать timer0, не влияя на millis() и micros().
- Arduino Мигает двумя светодиодами без задержки (количество повторений)
- Аппаратное прерывание срабатывает случайным образом
- _delay_ms() работает намного медленнее, чем ожидалось (в 6 раз) на tinyAVR 0/1 (ATTiny1604)
- Как рандомизировать задержку в коде шагового двигателя Arduino?
- Запуск двигателя постоянного тока в течение заданного промежутка времени
- Как заставить ЖК-экран прокручивать текст , позволяя вводить кнопки?
- Как запустить 4 светодиода последовательно на основе кнопочного входа?