Максимальная точность формирования импульсов

anri3489
Offline
Зарегистрирован: 04.02.2014

Всем привет!

Помогите пожалуйста со счётчиком 1.

Необходимо с максимальной точностью формировать последовательность прямоугольных импульсов с переменной частотой и скважностью. Длина импульса постоянная, например 3.32 мкс. А интервал между импульсами составляет от 38.52 до 138.44 мкс (есть набор фиксированных значений).

Конечно возможно воспользоваться delayMicroseconds, а остальное "добить" в ассемблере n-м количеством "nop\n\t". Но, хочется сделать покрасивее.

Попробовал с PWM. Можно добиться импульсов с нужной частотой и скважностью, но вот если их быстро изменять, прямо какая-то ерунда получется. Решил попробовать задействовать счётчик 1 напрямую. Установил коэффициент деления "1". Код:

void setup() {                
cli();                // запрет прерываний
DDRB |= B00000010;    // вывод 9 устанавливаем на выход
TCCR1A = B01000100;   // 4 ст.бита: normal; 4мл.бита: СТС(OCR1A)=0100
TCCR1B = B00001001;   // 4-й бит СТС. режим делителя, 3мл. бита: 001
TCNT1 = 0; // сбрасываем счетный регистр таймера 1
TIMSK1 = 0;
}

void loop() {
 PORTB |= (1 << 1);    // вкл
 OCR1A = 52;           // запускаем счётчик
 while (TCNT1 > 0) {}; // ждём пока он отработает
 PORTB &= (0 << 1);    // выкл
 OCR1A = 401;           // запускаем счётчик
 while (TCNT1 > 0) {}; // ждём пока он отработает
}

Если длительность равна паузе, то всё замечательно. Если неравные, то получается сигнал типа (с цифрами из данного примера): импульс длительностью 401, пауза длит. 52, импульс длит.52, пауза длит.52, и всё снова.

Я неверно задал параметры счётчика?

anri3489
Offline
Зарегистрирован: 04.02.2014

Всем спасибо, вопрос решён.

KNT
Offline
Зарегистрирован: 08.03.2014

anri3489 пишет:

Всем привет!

Помогите пожалуйста со счётчиком 1.

Необходимо с максимальной точностью формировать последовательность прямоугольных импульсов с переменной частотой и скважностью. Длина импульса постоянная, например 3.32 мкс. А интервал между импульсами составляет от 38.52 до 138.44 мкс (есть набор фиксированных значений).

Конечно возможно воспользоваться delayMicroseconds, а остальное "добить" в ассемблере n-м количеством "nop\n\t". Но, хочется сделать покрасивее.

Попробовал с PWM. Можно добиться импульсов с нужной частотой и скважностью, но вот если их быстро изменять, прямо какая-то ерунда получется. Решил попробовать задействовать счётчик 1 напрямую. Установил коэффициент деления "1". Код:

void setup() {                
cli();                // запрет прерываний
DDRB |= B00000010;    // вывод 9 устанавливаем на выход
TCCR1A = B01000100;   // 4 ст.бита: normal; 4мл.бита: СТС(OCR1A)=0100
TCCR1B = B00001001;   // 4-й бит СТС. режим делителя, 3мл. бита: 001
TCNT1 = 0; // сбрасываем счетный регистр таймера 1
TIMSK1 = 0;
}

void loop() {
 PORTB |= (1 << 1);    // вкл
 OCR1A = 52;           // запускаем счётчик
 while (TCNT1 > 0) {}; // ждём пока он отработает
 PORTB &= (0 << 1);    // выкл
 OCR1A = 401;           // запускаем счётчик
 while (TCNT1 > 0) {}; // ждём пока он отработает
}

Если длительность равна паузе, то всё замечательно. Если неравные, то получается сигнал типа (с цифрами из данного примера): импульс длительностью 401, пауза длит. 52, импульс длит.52, пауза длит.52, и всё снова.

Я неверно задал параметры счётчика?

мне тоже нужно, помогите пожалуйста