Наносекундные импульсы

andrey3824
Offline
Зарегистрирован: 17.03.2020

Можно ли на ардуино организовать импульсы с задаваемой длительностью порядка нескольких сотен наносекунд?
Отправляют к таймерам, но везде одни и те же (не те) примеры. С прямым доступом к портам получалось сделать довольно точные импульсы в пределах нескольких микросекунд. В распоряжении Nano, Uno, Mega, Due.

nik182
Offline
Зарегистрирован: 04.05.2015

На таймере можно меандр с частотой равной половине частоты тактирования. Для 100 МГц блакпила на stm32f411 это импульс длиной 10 нс. Шаг прироста эти 10 нс. Т.е. можно сделать импульс от 10 нс и повтор через те же 10 нс или бошьше с шагом 10 мс. Как программировать описано в мануале на чип. Для stm есть куб, который генерит код по заданным параметрам и этот код можно использовать в среде ардуино.

andrey3824
Offline
Зарегистрирован: 17.03.2020

nik182 пишет:
Для stm есть куб, который генерит код по заданным параметрам и этот код можно использовать в среде ардуино.

Что за куб?

andrey3824
Offline
Зарегистрирован: 17.03.2020

10 нс это перебор.
Несколько сотен, как и отметил в начале.

andrey3824
Offline
Зарегистрирован: 17.03.2020

Про куб прочитал немного, вникать нужно.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

16 МГц - 125 наносекунд - меньше не получится

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Komandir пишет:

16 МГц - 125 наносекунд - меньше не получится

А не 62,5 нс?

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Jeka_M это один такт - можно либо установить либо сбросить бит. Что бы был импульс надо установить и сбросить.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

SBI

SBI

125 наносекунд

SBI

NOP

SBI

187.5 наносекунд

SBI

NOP

NOP

SBI

250 наносекунд

...

nik182
Offline
Зарегистрирован: 04.05.2015

Мы уже на форуме проходили как из программы минимальный длины импульс на ноге получить. Если нужны наносекунды - только hardware - только таймеры.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Jeka_M пишет:

Komandir пишет:

16 МГц - 125 наносекунд - меньше не получится

А не 62,5 нс?

А вот 72Мгц

b707
Offline
Зарегистрирован: 26.05.2017

andrey3824 пишет:
МОтправляют к таймерам, но везде одни и те же (не те) примеры.

чем не устраивают "не те примеры" для таймеров?

 

andrey3824
Offline
Зарегистрирован: 17.03.2020

b707 пишет:

andrey3824 пишет:
МОтправляют к таймерам, но везде одни и те же (не те) примеры.

чем не устраивают "не те примеры" для таймеров?

 

Может я их (примеры) не так понимаю. 
Нашел кое-что здесь же на форуме, буду переделывать под себя.

andrey3824
Offline
Зарегистрирован: 17.03.2020

Мне вроде понятен смысл таймеров. Такты кварца идут всегда, независимо от выполняемых задач.
Таймерами отсчитываются нужное количество тактов и дергаются ноги или внутренние процессы.
Пока все это не стало для меня наглядным. Буду изучать матчасть. 

sadman41
Offline
Зарегистрирован: 19.10.2016

Можете в этих примерах покопаться: http://arduino.ru/forum/obshchii/diving-pwm

andrey3824
Offline
Зарегистрирован: 17.03.2020

Поразбирался с таймерами, вроде ничего сверхсложного нет.
Вернусь к импульсам.
По ходу "учебы" возник вопрос. Возьмём 16-битный таймер. Небольшой код, проверял на Меге.
 

void setup()
{
DDRL=DDRL | B10000000;
cli(); 
TCCR1A = 0;
TCCR1B = 0;
OCR1A = 100;
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << CS10);
TIMSK1 |= (1 << OCIE1A);
sei();
}
void loop(){}
ISR(TIMER1_COMPA_vect)
{
PORTL=~PORTL; // Здесь был digitalWrite, избавился
}

На 42 ноге меандр. Код по сравнению регистров. OCR1A = 100; - это количество тактов до сброса регистра счета в ноль.
Прескалер выключил, вернее оставил прямые такты. Максимум частоты получается примерно 150 кГц. На определенном значении регистра сравнения уменьшение периода заканчивается. Почему?

О чем я еще не знаю?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andrey3824 пишет:

О чем я еще не знаю?

О прерываниях, вестимо. Они ж тоже занимают вычислительные мощности. Порядка ~25 тактов МК на каждый вход и выход нужно. Итого что-б дёрнуть портом туда-сюда нужно 2 раза войти, и 2 раза выйти. Итого на круг выходят те самые 100 тактов, в которые вы и упёрлись.

 

andrey3824
Offline
Зарегистрирован: 17.03.2020

dimax пишет:

andrey3824 пишет:

О чем я еще не знаю?

О прерываниях, вестимо. Они ж тоже занимают вычислительные мощности. Порядка ~25 тактов МК на каждый вход и выход нужно. Итого что-б дёрнуть портом туда-сюда нужно 2 раза войти, и 2 раза выйти. Итого на круг выходят те самые 100 тактов, в которые вы и упёрлись.

 

То есть получить 4-5 тактов нереально при 16М?
Или есть способ это обойти?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andrey3824, можно получить хоть 8MHz, но без прерываний. Вы кстати, уже определитесь, что нужно -периодический сигнал или одиночный импульс. 

andrey3824
Offline
Зарегистрирован: 17.03.2020

dimax пишет:

andrey3824, можно получить хоть 8MHz, но без прерываний. Вы кстати, уже определитесь, что нужно -периодический сигнал или одиночный импульс. 

В итоге будет нужна пачка импульсов с разной длительностью.
Поэтому подумал, что без прерываний не обойтись.
Еще подумал использовать Due. Там тактовая выше.
Или внешнее тактирование, но наверное проблему с прерываниями это не решит.

nik182
Offline
Зарегистрирован: 04.05.2015

Комплексно надо. Таймер имеет выходную ногу. На ней можно получить даже одиночный импульс длительностью в половину тактовой частоты. Если нужен ещё один импульс, то в прерывании таймера можно перепрограмировать таймер на нужный импульс, который может случится ещё до выхода из прерывания. Можно услышать параметры импульсов? А то рассуждать о сферических конях в вакууме не очень хочется.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andrey3824, на AVR сделать пачку разных коротких импульсов - только ассемблер. Due тоже не фонтан. Про прерывания забудьте. Следующий шаг удобства -stm32, на таймере и DMA можно сделать любую пачку.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

nik182 пишет:
Комплексно надо. Таймер имеет выходную ногу. На ней можно получить даже одиночный импульс длительностью в половину тактовой частоты.

Ого, это как?? У меня таймером получалось сделать импульс не короче 5 толи 6 тактов МК.

andrey3824
Offline
Зарегистрирован: 17.03.2020

nik182 пишет:
Комплексно надо. Таймер имеет выходную ногу. На ней можно получить даже одиночный импульс длительностью в половину тактовой частоты. Если нужен ещё один импульс, то в прерывании таймера можно перепрограмировать таймер на нужный импульс, который может случится ещё до выхода из прерывания. Можно услышать параметры импульсов? А то рассуждать о сферических конях в вакууме не очень хочется.

Снимал данные анализатором и потом уже выяснил, что частоты дискретизации не хватило.

andrey3824
Offline
Зарегистрирован: 17.03.2020

Позже точнее данные сниму,но пока то, что есть.
Длительность на скрине в 2 такта дискретизации (12МГц), нужно больше.

Это минимальный импульс в пачке

andrey3824
Offline
Зарегистрирован: 17.03.2020

Есть еще меньше.

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andrey3824, надо опираться на минимальный. 83nS -это надо что-б МК работал на 12МГц, т.е. заменить кварц.  И на голом ассемблере выписать все задержки. По другому, IMHO, на AVR невозможно. Это если задержки реальны, а то может они и снялись некорректно. Такие вещи надо снимать с дискретизацией хотя б 1ГГц

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

nik182 пишет:
...Таймер имеет выходную ногу. На ней можно получить даже одиночный импульс длительностью в половину тактовой частоты...

Код предъявите ?

andrey3824
Offline
Зарегистрирован: 17.03.2020

dimax пишет:

andrey3824, надо опираться на минимальный. 83nS -это надо что-б МК работал на 12МГц, т.е. заменить кварц.  И на голом ассемблере выписать все задержки. По другому, IMHO, на AVR невозможно. Это если задержки реальны, а то может они и снялись некорректно. Такие вещи надо снимать с дискретизацией хотя б 1ГГц

Мне максимум доступно 108МГц на анализаторе. На камне, с которого читаю, кварц на 25. Если отталкиваться от этого, то, возможно, 80ns - это 2 такта. Не дока в процессорах, но думаю, что длительность принимаемых импульсов не должна быть меньше такта.

Про ассемблер почитал, сложновато пока для меня. С подходящими примерами, возможно, справлюсь.
Мне часто собрать на железе проще, чем программно. 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andrey3824, ну если что, ардуину на 25МГц можно разогнать. Но ассемблер не обойти никак. Либо сразу переходите на stm32.

andrey3824
Offline
Зарегистрирован: 17.03.2020

dimax пишет:

andrey3824, ну если что, ардуину на 25МГц можно разогнать. Но ассемблер не обойти никак. Либо сразу переходите на stm32.

Ассемблер попробую освоить.
Посоветуйте что-нибудь для начала.
DUE на 84 работает, её можно использовать?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andrey3824, моё личное мнение -не стоит терять время на её изучение. Обычный блюпилл/блэкпилл stm32 по функционалу периферии на голову выше Due и при желании ещё и разгоняется . По stm32 масса различных примеров программ в интернете -по Due сущие крохи.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

andrey3824 Полностью на ASM переходить не обязательно.

#define PULSEPORT PORTC
#define PULSEPIN PORTC5

void __attribute__ ((naked)) init_pulse_pin() {
  asm volatile(
    "SBI %0-1,%1\n\t"
    "RET \n\t"
    ::"I" (_SFR_IO_ADDR(PULSEPORT)), "I" (PULSEPIN)
  );
}

void __attribute__ ((naked)) one_pulse_125() {
  asm volatile(
    "SBI %0-2,%1\n\t"
    "SBI %0-2,%1\n\t"
    "RET \n\t"
    ::"I" (_SFR_IO_ADDR(PULSEPORT)), "I" (PULSEPIN)
  );
}

void __attribute__ ((naked)) one_pulse_250() {
  asm volatile(
    "SBI %0-2,%1\n\t"
    "NOP \n\t"
    "NOP \n\t"
    "SBI %0-2,%1\n\t"
    "RET \n\t"
    ::"I" (_SFR_IO_ADDR(PULSEPORT)), "I" (PULSEPIN)
  );
}

void setup () {
	init_pulse_pin();
}

void loop() {
	one_pulse_125();
	one_pulse_250();
}

Шаг сетки 500 наносекунд...

Листинг самих функций:

000000a6 <_Z14init_pulse_pinv>:
  a6: 3d 9a        sbi 0x07, 5 ; 7
  a8: 08 95        ret
 
000000aa <_Z13one_pulse_125v>:
  aa: 35 9a        sbi 0x06, 5 ; 6
  ac: 35 9a        sbi 0x06, 5 ; 6
  ae: 08 95        ret
 
000000b0 <_Z13one_pulse_250v>:
  b0: 35 9a        sbi 0x06, 5 ; 6
  b2: 00 00        nop
  b4: 00 00        nop
  b6: 35 9a        sbi 0x06, 5 ; 6
  b8: 08 95        ret
 
000000ba <setup>:
  ba: cf 93        push r28
  bc: df 93        push r29
  be: cd b7        in r28, 0x3d ; 61
  c0: de b7        in r29, 0x3e ; 62
  c2: 0e 94 53 00 call 0xa6 ; 0xa6 <_Z14init_pulse_pinv>
  c6: df 91        pop r29
  c8: cf 91        pop r28
  ca: 08 95        ret
 
000000cc <loop>:
  cc: cf 93        push r28
  ce: df 93        push r29
  d0: cd b7        in r28, 0x3d ; 61
  d2: de b7        in r29, 0x3e ; 62
  d4: 0e 94 55 00 call 0xaa ; 0xaa <_Z13one_pulse_125v>
  d8: 0e 94 58 00 call 0xb0 ; 0xb0 <_Z13one_pulse_250v>
  dc: df 91        pop r29
  de: cf 91        pop r28
  e0: 08 95        ret

 

andrey3824
Offline
Зарегистрирован: 17.03.2020

dimax пишет:

andrey3824, моё личное мнение -не стоит терять время на её изучение. Обычный блюпилл/блэкпилл stm32 по функционалу периферии на голову выше Due и при желании ещё и разгоняется . По stm32 масса различных примеров программ в интернете -по Due сущие крохи.

Да, по Due мало что есть.

nik182
Offline
Зарегистрирован: 04.05.2015

Komandir пишет:

nik182 пишет:
...Таймер имеет выходную ногу. На ней можно получить даже одиночный импульс длительностью в половину тактовой частоты...

Код предъявите ?

Если очень надо код, то чуть позже, когда проверю в железе, но общая идея таймер в режиме однократного импульса PWM c единичкой в регистре канала и двойкой в регистре периода. 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

А половина тактовой откуда ?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Komandir пишет:

Шаг сетки 500 наносекунд...

Дык в том и дело. Каждый вызов функции и возврат забирают по 4 такта, итого 8 тактов. + 2 такта нужно ожидать исполнения следующей команды. Выходит  10 тактов минимальная пауза между импульсами. А у ТС речь идёт о 80nS паузах, т.е. один такт максимум при 12МГц.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

dimax Можно и без вызовов:

#define PULSEPORT PORTC
#define PULSEPIN PORTC5

void __attribute__ ((always_inline)) init_pulse_pin() {
  asm volatile(
    "SBI %0-1,%1\n\t"
    ::"I" (_SFR_IO_ADDR(PULSEPORT)), "I" (PULSEPIN)
  );
}

void __attribute__ ((always_inline)) one_pulse_125() {
  asm volatile(
    "SBI %0-2,%1\n\t"
    "SBI %0-2,%1\n\t"
    ::"I" (_SFR_IO_ADDR(PULSEPORT)), "I" (PULSEPIN)
  );
}

void __attribute__ ((always_inline)) one_pulse_250() {
  asm volatile(
    "SBI %0-2,%1\n\t"
    "NOP \n\t"
    "NOP \n\t"
    "SBI %0-2,%1\n\t"
    ::"I" (_SFR_IO_ADDR(PULSEPORT)), "I" (PULSEPIN)
  );
}

void setup () {
	init_pulse_pin();
}

void loop() {
	one_pulse_125();
	one_pulse_250();
}
Шаг сетки 500 наносекунд при 16Мгц...
 
Листинг самих функций:
000000a6 <setup>:
  a6: cf 93        push r28
  a8: df 93        push r29
  aa: cd b7        in r28, 0x3d ; 61
  ac: de b7        in r29, 0x3e ; 62
  ae: 3d 9a        sbi 0x07, 5 ; 7
  b0: df 91        pop r29
  b2: cf 91        pop r28
  b4: 08 95        ret
 
000000b6 <loop>:
  b6: cf 93        push r28
  b8: df 93        push r29
  ba: cd b7        in r28, 0x3d ; 61
  bc: de b7        in r29, 0x3e ; 62
  be: 35 9a        sbi 0x06, 5 ; 6
  c0: 35 9a        sbi 0x06, 5 ; 6
  c2: 35 9a        sbi 0x06, 5 ; 6
  c4: 00 00        nop
  c6: 00 00        nop
  c8: 35 9a        sbi 0x06, 5 ; 6
  ca: df 91        pop r29
  cc: cf 91        pop r28
  ce: 08 95        ret

На старте ТС ничего не писал про паузы !!!

andrey3824
Offline
Зарегистрирован: 17.03.2020

Ардуина для этого не очень подходит, уже осознал. 
Нужно двигаться в сторону STM

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Komandir пишет:

Можно и без вызовов:

Да, теперь другое дело :) 2 такта между импульсами. Если sbi поменять на out, то будет 1 такт. 

andrey3824
Offline
Зарегистрирован: 17.03.2020

Komandir пишет:

На старте ТС ничего не писал про паузы !!!

Позже отметил, что нужна пачка импульсов с разной длительностью.
Там всё будет важно, и импульсы и паузы. 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

andrey3824 то есть 125 наносекунд Вас не устраивают ???

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

dimax пишет:

Да, теперь другое дело :) 2 такта между импульсами. Если sbi поменять на out, то будет 1 такт. 

OUT может задеть другие биты ... плюс надо занять один регистр и запретить компилятору его портить ...

Вот 62.5 импульсы и 62.5 паузы ...

#define PULSEPORT PORTC
#define PULSEPIN PORTC5
register unsigned char pp asm("r3");
void __attribute__ ((always_inline)) init_pulse_pin() {
  asm volatile(
    "SBI %0-1,%1 \n\t"
    "SET \n\t"
    "CLR %2 \n\t"
    "BLD %2,%1 \n\t"
    ::"I" (_SFR_IO_ADDR(PULSEPORT)), "I" (PULSEPIN), "r" (pp)
  );
}

void __attribute__ ((always_inline)) one_pulse_62_5() {
  asm volatile(
    "OUT %0-2,%1 \n\t"
    "OUT %0-2,%1 \n\t"
    ::"I" (_SFR_IO_ADDR(PULSEPORT)), "r" (pp)
  );
}

void __attribute__ ((always_inline)) one_pulse_125() {
  asm volatile(
    "OUT %0-2,%1 \n\t"
    "NOP \n\t"
    "OUT %0-2,%1 \n\t"
    ::"I" (_SFR_IO_ADDR(PULSEPORT)), "r" (pp)
  );
}

void setup () {
	init_pulse_pin();
}

void loop() {
	one_pulse_62_5();
	one_pulse_125();
}

Шаг сетки 500 наносекунд при 16Мгц...

Листинг самих функций:

000000a6 <setup>:
  a6:	cf 93       	push	r28
  a8:	df 93       	push	r29
  aa:	cd b7       	in	r28, 0x3d	; 61
  ac:	de b7       	in	r29, 0x3e	; 62
  ae:	3d 9a       	sbi	0x07, 5	; 7
  b0:	68 94       	set
  b2:	33 24       	eor	r3, r3
  b4:	35 f8       	bld	r3, 5
  b6:	df 91       	pop	r29
  b8:	cf 91       	pop	r28
  ba:	08 95       	ret

000000bc <loop>:
  bc:	cf 93       	push	r28
  be:	df 93       	push	r29
  c0:	cd b7       	in	r28, 0x3d	; 61
  c2:	de b7       	in	r29, 0x3e	; 62
  c4:	36 b8       	out	0x06, r3	; 6
  c6:	36 b8       	out	0x06, r3	; 6
  c8:	36 b8       	out	0x06, r3	; 6
  ca:	00 00       	nop
  cc:	36 b8       	out	0x06, r3	; 6
  ce:	df 91       	pop	r29
  d0:	cf 91       	pop	r28
  d2:	08 95       	ret

 

 

andrey3824
Offline
Зарегистрирован: 17.03.2020

Komandir пишет:

andrey3824 то есть 125 наносекунд Вас не устраивают ???

Выше есть скрин, на котором 1 имп 83ns. Это учитывая то, что данные снимались при частоте дискретизации всего 12МГц.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andrey3824, вот если разгоните дуню на 25МГц то 125nS аккурат превратятся в 80 :)Komandir дал вам фактически готовое решение для малых импульсов, осталось только для больших что-то простое придумать.

andrey3824
Offline
Зарегистрирован: 17.03.2020

dimax пишет:

andrey3824, вот если разгоните дуню на 25МГц то 125nS аккурат превратятся в 80 :)Komandir дал вам фактически готовое решение для малых импульсов, осталось только для больших что-то простое придумать.

Понял, попробую. 
Еще раз про Due спрошу, её можно в таком случае использовать, или там свои заморочки?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

andrey3824, я не настолько хорошо знаю Due, что б заявлять что на ней не получится. Лучше взять плату, где точно получится. Stm32f401 цена вопроса около 300руб

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

В #42 сделал 62.5 нс импульсы и 62.5 нс паузы.

на основе этого можно через NOP нарисовать что угодно с шагом 62.5 нс для 16 МГщ

при 20 Мгц будут более красивые 50 нс

andrey3824
Offline
Зарегистрирован: 17.03.2020

Komandir пишет:

В #42 сделал 62.5 нс импульсы и 62.5 паузы.

на основе этого можно через NOP нарисовать что угодно с шагом 62.5 для 16 МГщ

при 20 Мгц будут более красивые 50 нс

Мне для начала нужно с Нопами, Аутами и прочими познакомиться.
Чтобы проще было, поясню. Кнопку жмакаем (или команда) - пачка улетела.
Чтобы не было это по бесконечному кругу.
 

andrey3824
Offline
Зарегистрирован: 17.03.2020

Я постепенно все познаю. 
До недавнего времени прямой доступ к портам тоже был чем-то необъятным.
Поизучал, вроде ближе к этому стал.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

andrey3824 пишет:

Komandir пишет:

В #42 сделал 62.5 нс импульсы и 62.5 паузы.

на основе этого можно через NOP нарисовать что угодно с шагом 62.5 для 16 МГщ

при 20 Мгц будут более красивые 50 нс

Мне для начала нужно с Нопами, Аутами и прочими познакомиться.
Чтобы проще было, поясню. Кнопку жмакаем (или команда) - пачка улетела.
Чтобы не было это по бесконечному кругу.
 

По кругу сделано что бы видеть на приборах ... одиночный импульс не поймать ...

Вы видимо не видели документацию про программированию STM, раз AVR для Вас сложно ... :-)))