Генерация наносекундных импульсов на Arduino

herzdp
Offline
Зарегистрирован: 30.11.2021

Всем доброго времени суток.

Нашел код в интернетах, слегка модифицировал, очень нужны были субмикросекундные импульсы.

1. Первый цикл задает длину импульса, второй расстояние между ними. 

В коде при выставлении значений length и delay более 8 происходит резкий скачок во времени и изменение шага в 6 раз. Измерял на осциле, см. зависимость на картинке. По оси x - количество итераций цикла, по y - длина/расстояние между импульсами. С чем это может быть связано? Выставлял разные типы переменных, выходил в восьмеричную и тд системы, но ничего не помогло. При этом, если накопировать в лоб строки с 1 и 0 условные 10 раз вместо цикла, то такого не наблюдается, идет линейный рост без скачков. Пробовал загонять в while и тп, ситуация как с for.

Спасибо, если кто-то подскажет, как это лечится. Проблема не критичная, но принципиальная.

2. Можно ли организовать подобные импульсы на двух независимых каналах, например, на Arduino Mega?

p.s. Использую Arduino Uno.

void setup()
{
  DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}

void loop()
{
   int length = 1;
   int delay = 1;
      for (int i = 1; i <= length; i++) 
  {
      PORTD = B11111111; // set PORTD pins (digital 7~0) high
  }
 
   
      for (int j = 1; j <= 1; j++) 
   {
      PORTD = B00000000; // set PORTD pins (digital 7~0) low
   }
}

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

herzdp пишет:

В коде при выставлении значений length и delay более 8 происходит резкий скачок во времени и изменение шага в 6 раз.

Количество проходов цикла известно заранее (на этапе компиляции), поэтому компилятор оптимизирует так, как ему кажется наиболее оптимально: если количество повторений не превышает 8, цикл не организуется, а "тело цикла" включается в код непосредственно нужное число раз (до 8), если количество повторений превышает 8, организуется настоящий цикл, со всеми накладными расходами на него.

Green
Offline
Зарегистрирован: 01.10.2015

Переменная delay не используется, второй цикл выполняется один раз только... Как то кривенько, не?

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

код не соответвует описанию

herzdp
Offline
Зарегистрирован: 30.11.2021

upd. Код копировал черновой, не рабочий. Прикладываю реальный. Задаю разные delay и length.

​void setup()
{
   DDRD = B11111111; // set PORTD (digital 7~0) to outputs
}

void loop()
{
   int length = 1;
   int delay = 1;
      for (int i = 1; i <= length; i++) 
  {
      PORTD = B11111111; // set PORTD pins (digital 7~0) high
  }
 
   
      for (int j = 1; j <= delay; j++) 
   {
      PORTD = B00000000; // set PORTD pins (digital 7~0) low
   }
}

Далее картинки с разными случаями.

1. length = 1, delay = 1

2. length = 4, delay = 1

3. length = 7, delay = 1

4. length = 8, delay = 1

5. length = 9, delay = 1 (масштаб изменился)

6. length = 4, delay = 8

7. length = 4, delay = 9

herzdp
Offline
Зарегистрирован: 30.11.2021

Спасибо за ответ.

То есть единственным вариантом тут будет избавиться от цикла и просто устроить копипасту?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

herzdp пишет:

Код копировал черновой, не рабочий. Прикладываю реальный. 

А люди, которые хотели Вам помочь, тратили время на то, чтобы в нём разбираться. Признаёте, что смудачили?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

herzdp пишет:

То есть единственным вариантом тут будет избавиться от цикла и просто устроить копипасту?

А почему ШИМом не воспользоваться? С ним что-то не так?

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

Тут http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/nanosekundnye-impulsy?page=1#comment-632430 ответил.

ТС чем вы компилируете и какой уровень оптимизации выставлен ? Хорошо бы листинги обоих версий увидеть.

herzdp
Offline
Зарегистрирован: 30.11.2021

Признаю, мой косяк. Приношу извинения.

Пытался работать со стандартным кодом, но на нем у меня не вышло получить длину импульсов порядка 200 нс с большой скважностью (>10000). Ставил еще библиотеку TimerOne.h, но там не хватало скважности.

herzdp
Offline
Зарегистрирован: 30.11.2021

Komandir пишет:

Тут http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/nanosekundnye-impulsy?page=1#comment-632430 ответил.

ТС чем вы компилируете и какой уровень оптимизации выставлен ? Хорошо бы листинги обоих версий увидеть.

Спасибо за ответ в той ветке. Ваше объяснение проблемы выглядит исчерпывающе.

Я использую Arduino IDE 1.8.13. Все на стандартных настройках. Если честно, то разбираюсь только в базовых вещах на уровне школьной программы. Не подскажете, как выгрузить листинги?

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

При компиляции в логе видно путь к временной папке - в ней есть файл .lst

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ещё раз спрошу: ШИМ-то чем не устроил?

И второй вопрос, уже второй десяток постов пошёл, может пора, наконец, внятно сказать что нужно? А именно, укажите максимальные и минимальные требуемые частоты и скважности, а то разговор как-то ни о чём.

herzdp
Offline
Зарегистрирован: 30.11.2021

ЕвгенийП пишет:

Ещё раз спрошу: ШИМ-то чем не устроил?

И второй вопрос, уже второй десяток постов пошёл, может пора, наконец, внятно сказать что нужно? А именно, укажите максимальные и минимальные требуемые частоты и скважности, а то разговор как-то ни о чём.

Минимальная длительность импульса - 100 нс, максимальная - 5 мкс, шаг изменения <=100 нс. Частота от 25 Гц до 300 кГц. Программой нужно выставить фиксированный режим работы, но должна быть возможность просто изменить его в коде.

herzdp
Offline
Зарегистрирован: 30.11.2021

Komandir пишет:

При компиляции в логе видно путь к временной папке - в ней есть файл .lst

Файла не нашел, как понимаю, все то же самое пишется просто в окне снизу. Все переменные заменил на byte.

При length = 8, delay = 1 :

Скетч использует 778 байт (2%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.
 

При length = 9, delay = 1 :

Скетч использует 770 байт (2%) памяти устройства. Всего доступно 32256 байт.
Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.
 
Это то?
 

 

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

Upper
Offline
Зарегистрирован: 23.06.2020
herzdp
Offline
Зарегистрирован: 30.11.2021

Komandir пишет:

В папке нет .lst файлов.

Upper
Offline
Зарегистрирован: 23.06.2020

Дополнительно в настройках надо Файл Настройки  поставить галочку Подробного вывода компиляции

Дополнено позже. Про файлы lst написал выше.

Вариант без встраивания в IDE описан например здесь https://tsibrov.blogspot.com/2019/06/ide-arduino-disassembling.html

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Речь идёт именно о стандартной ардуине типа Uno/Nano/Mega и т.п.?

Тогда

herzdp пишет:

Минимальная длительность импульса - 100 нс,

Неразрешимо. Длительность импульса всегда кратна 62,5 нс. Т.е. 62,5нс, 125нс, 187,5нс - пожалуйста. А 100нс без переделок - хренушки

herzdp пишет:

шаг изменения <=100 нс. 

Неконкретно, но в целом ответ тот же - 62,5нс, 125нс, 187,5нс и далее.

herzdp пишет:

Частота от 25 Гц до 300 кГц.

Я Вас спрашивал о скважности. Вы не ответили. Из-за этого тут же возникают дополнительные вопросы. Например, минимальную длительность импульса необходимо обеспечить для любой из этих частот? Или для маленьких минимальный импульс подлиннее будет? Например, простыми средствами (совсем простыми) импульсы длительности 62,5нс можно получать для частот не меньше 244 Герц. Для меньших частот минимальный импульс будет длиннее (это, если просто делать).

Если Вам реально нужна помощь, то потрудитесь внятно задать вопрос. Не расписывать же мне все возможные варианты.

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

IDE 1.8.13 ничего не менял - lst есть

herzdp
Offline
Зарегистрирован: 30.11.2021

Попробовал сделать по этому треду, тупо вываливает ошибку.

В настройках установил галочку на компиляции, но в %temp%/папка ардуино... все еще нет .lst файла, код на плату прогрузил.

herzdp
Offline
Зарегистрирован: 30.11.2021

ЕвгенийП пишет:

Речь идёт именно о стандартной ардуине типа Uno/Nano/Mega и т.п.?

Да, arduino uno.

ЕвгенийП пишет:

Неразрешимо. Длительность импульса всегда кратна 62,5 нс. Т.е. 62,5нс, 125нс, 187,5нс - пожалуйста. 

Я Вас спрашивал о скважности. Вы не ответили. Из-за этого тут же возникают дополнительные вопросы. Например, минимальную длительность импульса необходимо обеспечить для любой из этих частот? Или для маленьких минимальный импульс подлиннее будет? Например, простыми средствами (совсем простыми) импульсы длительности 62,5нс можно получать для частот не меньше 244 Герц. Для меньших частот минимальный импульс будет длиннее (это, если просто делать).

В таком случае, раз есть ограничения платформы, придется поработать с такой кратностью времени. 62.5 нс, так 62.5 нс. Вообще возможность выставить минимальную частоту ~25-30 Гц нужно обеспечить на любой длине импульса, даже минимальной (62.5 нс). 

Возможно ли организовать такой режим работы в принципе?

 

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

При

   int length = 9;
   int delay = 9;
 1b4:	89 e0       	ldi	r24, 0x09	; 9
 1b6:	90 e0       	ldi	r25, 0x00	; 0
 1b8:	cb b9       	out	0x0b, r28	; 11
 1ba:	01 97       	sbiw	r24, 0x01	; 1
 1bc:	e9 f7       	brne	.-6      	; 0x1b8 <main+0x94>
 1be:	89 e0       	ldi	r24, 0x09	; 9
 1c0:	90 e0       	ldi	r25, 0x00	; 0
 1c2:	1b b8       	out	0x0b, r1	; 11
 1c4:	01 97       	sbiw	r24, 0x01	; 1
 1c6:	e9 f7       	brne	.-6      	; 0x1c2 <main+0x9e>

При

   int length = 8;
   int delay = 8;
 1b4:	cb b9       	out	0x0b, r28	; 11
 1b6:	cb b9       	out	0x0b, r28	; 11
 1b8:	cb b9       	out	0x0b, r28	; 11
 1ba:	cb b9       	out	0x0b, r28	; 11
 1bc:	cb b9       	out	0x0b, r28	; 11
 1be:	cb b9       	out	0x0b, r28	; 11
 1c0:	cb b9       	out	0x0b, r28	; 11
 1c2:	cb b9       	out	0x0b, r28	; 11
 1c4:	1b b8       	out	0x0b, r1	; 11
 1c6:	1b b8       	out	0x0b, r1	; 11
 1c8:	1b b8       	out	0x0b, r1	; 11
 1ca:	1b b8       	out	0x0b, r1	; 11
 1cc:	1b b8       	out	0x0b, r1	; 11
 1ce:	1b b8       	out	0x0b, r1	; 11
 1d0:	1b b8       	out	0x0b, r1	; 11
 1d2:	1b b8       	out	0x0b, r1	; 11

 

 

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

herzdp пишет:

Возможно ли организовать такой режим работы в принципе?

Для самого импульса:

http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/nanosekundnye-impulsy#comment-632193

А частоту можете задать хоть через delay() ...

Если надо кратность 50нс - надо кварц с 16 поменять на 20 МГш (со всеми вытекающими ...)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

herzdp пишет:

Возможно ли организовать такой режим работы в принципе?

В принципе, возможно, но не так просто как для частот 245 и больше Герц.

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

А как же блак пил? Любая длительность от 10 нс с шагом 10 нс при любой частоте повторений, пока не упрёшься в период повторений > 2^32. Или это не наш метод на нужную задачу  600 руб. потратить? Или 15 нс за 300 руб.? 

herzdp
Offline
Зарегистрирован: 30.11.2021

nik182 пишет:

А как же блак пил? 

Я так понимаю, речь про esp32? Уже видел в другом топике ее упоминание, думаю приобрести. Просто ардуина была под рукой, досталась от коллеги.

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

Про stm32f411

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

P.S. разобрался почему у меня есть .lst файлы по умолчанию - у меня установлен пакет MiniCore и в нем свой platform.txt.