Не проверял, но скорее всего там адрес OCR1A который как бы “первый”, из которого потом запишется в другой с которым уже идет сравнение.
Если стоп без старта несущественен, можно автоматом формировать стоп-старт-стоп, во время формирования первого стопа записывая значения OCR.
Есть, но это адрес буферизованного регистра.
Думаю, раз в даташите написано, что в FastPWM режиме OCR1A обновляется только при переходе таймера через TOP/BOTTOM - то никак вы это не обойдете.
Да и зачем? Регистр ICR1 не имеет такого ограничения, он обновляется сразу. Замена одного варианта на другой - один бит в настройке режима таймера. Вы можете взять свой код и использовать его с ICR1
OCR обновляется не при старт-стопе, а при прохождении счетчика таймера через TOP/BOTTOM
Я про это же. На выходе имеем 2 импульса - старт и стоп. Стоп формируем с помощью таймера с прохождением через TOP. Первый стоповый фиктивный, во время его формирования записываем новое значение OCR, пока не достигли ТОП. После этого формируем стартовый импульс и через время заданное с помощью (уже требуемого) OCR, стоповый.
А с чем связаны эти выбросы: с переводом пина, настроенного на выход, в ноль или с переводом пина в высокоимпедансное состояние?
Если второе - выброс можно устранить внешней подтяжкой. Если первое - можно попытаться так переконфигурировать пин, чтобы в предполагаемый момент выброса он был настроен на вход (и свести тем самым первый вариант ко второму).
Это я ввел всех в заблуждение. Нет там выбросов, если даташит читать внимательно
см код в следующем сообщении
Переделал
Теперь импульсы подаются всегда в одном порядке - AB - AB - AB…
Чтобы можно было управлять интервалом, добавил функцию генерации pulse_train(uint16_t pp)
с параметром, равным задержке между импульсами. Каждый раз можете вызывать функцию с новой задержкой. Число вызовов не ограничено, главное не вызывать функцию раньше, чем завершила работу прежняя. Длительность работы функции - 4х кратная задержка между импульсами.
// interval between first pulse falling edge
// and raising edge of the second pulse (in timer ticks)
volatile uint16_t period =1000;
volatile uint8_t cc =1;
void setup() {
DDRB |= (1<<PB1) | (1<<PB2);
PORTB |= (1<<PB1) | (1<<PB2);
cli(); //stop interrupts for till we make the settings
TCCR1A = 0; // Reset entire TCCR1A to 0
TCCR1B = 0; // Reset entire TCCR1B to 0
TCNT1 = 0; //reset clock value
////set to fast PWM mode 14 via WGM bits(count from 0 to ICR1):
////TOP = ICR1
TCCR1A |= (0 << WGM10) | (1 << WGM11) ;
TCCR1B |= (1 << WGM12) | (1 << WGM13) ;
////Timer/Counter1 Interrupt Mask Register:
TIMSK1 |= (1 << OCIE1A); // enable compare OCR1A itrerrupt
TIMSK1 |= (1 << OCIE1B); // enable compare OCR1B itrerrupt
//TIMSK1 |= (1 << TOIE1); //enable overflow vector interrupt
OCR1A = period - 1; //match 1 tick before TOP
ICR1 = period; //top value
OCR1B = 0xFFFE; // never match value
//Clear OC1A/OC1B on Compare Match, set OC1A/OC1B at
// BOTTOM (non-inverting PWM mode)
TCCR1A |= (1 << COM1A1) | (1 << COM1B1);
// clear all irq flags
TIFR1 = B111; // (1<<TOV1)| (1<< OCFB) |(1<< OCFA);;
sei();
TCCR1B|= 1; //start timer at 16 MHz, no prescaling
}
ISR(TIMER1_COMPB_vect) {
OCR1A = period -1; // match 1 tick before TOP
OCR1B = 0xFFFE; // never match value
TCCR1A &= ~((1 << COM1A1) | (1 << COM1B1)); // disable pin outputs
}
ISR(TIMER1_COMPA_vect) {
OCR1A = 0xFFFE; // never match value
OCR1B = period -1; // match 1 tick before TOP
ICR1 = period;
if (cc) TCCR1B &= ~bit(0); // stop the timer
cc++;
}
//generate impulse pairs with interval pp clock ticks
void pulse_train(uint16_t pp) {
cc=0;
period = pp;
OCR1B = period -1;
TCCR1A |= (1 << COM1A1) | (1 << COM1B1); // enable pin outputs
TCCR1B|= 1; //start timer at 16 MHz, no prescaling
}
void loop() {
static bool flag = true;
if (flag)
{
delay(100);
pulse_train(1000);
delay(50);
pulse_train(500);
delay(50);
pulse_train(1500);
delay(50);
pulse_train(600);
flag = false;
}
}
Попробовал немного, как то странно себя ведёт при задержке в 50тактов.
И в целом как будто останавливается после одного цикла намертво. В общем до конца не разобрался, там хитро написано, но предварительно понял, что:
- сработало совпадение А и задались значения для В, а так же канал А выдал импульс.
- после нужной задержки импульс В сработал и выставились настройки под А.
Надо сидеть разбираться , не особо много времени есть.
50 тактов я не пробовал… 500 тактов работает стабильно.
может вы вызывали функцию 2 раза подряд? - так нельзя, надо с перерывом
Насколько я вижу, вы так и не ответили на несколько раз заданный вопрос - какие именно характеристики импульсов вам нужны ? - не в тактах, а в микро или нано-секундах.
Ширина самих импульсов?
Диапазон задержки? - мин и макс?
Сколько пар импульсов надо генерить в последовательности?
Интервал между парами - минимум и максимум?
А я не понимаю почему не использовать два таймер? Второй 8 битный формирует первый импульс на одной ноге. Одновременно запускаем первый 16 битный, который через необходимую задержку формирует импульс на другой ноге. между импульсами будет всегда точная задержка.
она и на одном таймере точная получается
Тут все упирается в ТС - ему надо сесть и вдумчиво все проверить. Но ему все время некогда… решать свою проблему…
У других ведь полно свободного времени, ага…вот пусть они и думают.
Вчера не смог точно ответить, так как нужных бумаг под рукрй не было.
Стартовый 100-200нс
Стоповый 100±30нс
Задержка между ними от 3 до 35 микросекунд.
Точность задержки, чем выше тем лучше. Ардуиновский шаг в 62,5нс, что бы скорректировать при необходимости нужное значение это на грани. По этому и нужна в данном случае точность а 1 такт
Всегда одна пара импульсов.
Интервал между парами: генерация происходит по нажатию кнопки, то есть можно спокойно раз в секунду, или в две, или в пол секунды.
Перед парой будет всегда идти ещё один сигнал, но задержка между ним и парой не строгая 15-25us и длительность 700-1000нс.
Если в pulse_train забить 63 то всё ещё работает. Если 62 то выдает 2 импульса и зависает. Не выдает больше импульсов.
При 63 задержка выходит 4uS
значит это минимум. Вход в прерывание, вызов обработчика, выполнение кода и выход требует времени,
Период должен быть длиннее, чем сумма всего вышеперечисленного.
менять МК или аппаратное решение на микросхемах
+100
давно бы на СТМ32 сделали
Так и предполагал. Но все равно гениально, до такого не додумался бы:)
Сделаю тогда пока с костылем либо на fastpwm+wgm mode 15, либо можно разбить задержку: дольше 62 тактов wgm14 с вашим методом, меньше wgm15 + настроечный стоповый сигнал.
Можно каких то пару советов на последок по stm32 на чем там делать подобную задержку, что изучить, пока они идут и уже быть готовым к доработке?
Спасибо.
нет никаких советов
таймеры в STM32 целая огромная тема, читать читать…вникать, программировать.
в Arduino IDE с STM32 не работал, поэтому пусть другие коллеги подскажут насколько там реально произвести тонкую настройку с регистрами МК.
но я б посоветовал сразу ставить STM32 Cube IDE и писать сразу на регистрах, вдумчиво читая даташит на МК.
И калокуб (HAL/CubeMX) с моей точки зрения не стоит сил на изучение, сразу пишите по уму, да, сложно, но оно стОит того.
Б707! Напиши мне, плз, ТЗ от ТС, как ты его понял.
Мне интересно написать это на прямой задержке. Я слышал, что нужно на низкой тактовой частоте? В качестве прокрастинации… ;))