delayMicroseconds- ошибка?
запускаем очень короткую программу на мега, просто чтобы генерировать тактовый импульс шириной 8 микросекунд на выводе 18 каждые 250 микросекунд — Ближайшие значения задержки , которые я могу получить, — это значение задержкиMicroсекунды(3), а (83) выключено, дает импульс шириной 7,5 микросекунд каждые 249 микросекунд. Есть предложения по лучшему способу?
вот что работает:
int i=0;
int req=18;
void setup(){
Serial.begin(115200);
DDRD = DDRD | B10000010;
interrupts();
pinMode(req,OUTPUT);
}
void loop(){
i=1;
digitalWrite(req, HIGH);
delayMicroseconds(3); //дает импульс длительностью 7,5 микросекунд?
digitalWrite(req, LOW);
while(i<83){//дает 249 микросекунд от начала импульса до начала следующего импульса?
delayMicroseconds(1);
i=(i+1);}
}
@tc429, 👍0
Обсуждение2 ответа
Если вам не нужен программный таймер ШИМ, как предложено в комментарии, тогда для коротких задержек вам нужно рассчитать, сколько командных циклов необходимо, чтобы сделать такую задержку на основе тактовой/кристаллической частоты, и сделать эту задержку во встроенном ассемблере, чтобы иметь контроль над кодом. Для управления цифровым выводом используйте запись данных в PINx (что эквивалентно xoring PORTx).
Чтобы обеспечить точные 250 мс, вам необходимо компенсировать ошибки из-за округления. Функции задержки/тикания Arduino делают это. Для больших задержек нужен простой планировщик, чтобы не тратить все время процессора на генерацию импульсов.
Это очень частичный ответ. Я не знаю ваших требований, или ШИМ не может выполнить эту работу и т. д. Я просто хотел отметить, что вы можете создайте импульс длительностью ровно 8 мкс следующим образом:
#include <util/delay.h>
#include <util/atomic.h>
// Импульсный PD3 (цифровой 18 на Mega 2560)
// ровно 8 мкс (128 тактов @ 16 МГц)
static void pulse() {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
PORTD |= 1 << 3;
_delay_us(8 - 0.125);
PORTD &= ~(1 << 3);
}
}
Функция _delay_us()
из avr-libc на самом деле работает с точностью до цикла
линейная сборка. 0,125 мкс, которые я вычел, — это время, необходимое для
реальный порт пишет: и инструкции sbi, и cbi выполняются по два такта
(0,125 мкс), но эту задержку следует учитывать только один раз.
digitalWrite()
всегда следует избегать в коде, критичном ко времени.
Задержку в 242 мкс между импульсами было бы сложнее создать без ШИМ. Прерывание по таймеру на частоте 4 кГц кажется самым простым вариантом, но это неточно с точностью до цикла.
Изменить: вот трассировка области, показывающая довольно точное время:
- Как разделить входящую строку?
- Как использовать SPI на Arduino?
- Как сбросить или отформатировать Arduino?
- Управление скоростью вентилятора с помощью библиотеки Arduino PID
- Arduino Due vs Mega 2560
- Как получить уникальный идентификатор для всех плат Arduino?
- Почему я получаю avrdude: stk500v2_ReceiveMessage(): timeout error when uploading to Arduino Mega?
- Тайм-аут связи Arduino Mega с ошибкой программатора
Есть ли какая-то конкретная причина, по которой вы не хотите использовать ШИМ?, @Ignacio Vazquez-Abrams
Насколько я понимаю, частота ШИМ «примерно» 490 Гц, мне нужно именно 4000 Гц. есть ли где-нибудь опубликованный список времени обработки инструкций для расчета накладных расходов? Micros даст все это, но не только цикл while, @Tim
Только если вы будете придерживаться того, что дает вам Arduino. Выход за рамки стандартного делает вещи более гибкими., @Ignacio Vazquez-Abrams
Попробуйте библиотеку TimerOne., @Gerben
спасибо, ребята, переосмысление, чтение Micros в различных частях программы может позволить мне сдвигать время по мере необходимости для чтения следующего бита в следующем байте - будет работать только для статических условий, но на данный момент это нормально. Спасибо за предложение ШИМ - да, стандартный, он тактирует очень медленно, но он точен - длительность импульса 1% просто дает тик 8 микросекунд, запуская отправку устройства - чрезвычайно долгое время ожидания не возражало. спасибо за комментарии — все это для меня в новинку, но я вижу огромный потенциал для создания инструментов для ремонта наших компонентов с ЧПУ :), @tc429