Обсуждаем контроллеры компании Atmel.
Ответить

Re: Нестабильность из-за задержек

Пт апр 23, 2021 07:53:40

МК -- аналог обычного кнопочного переключателя. ((Корпус генератора очень маленький, галетник или типа п2к уж больно много места займут. Делать на жменьке логике или триггеров на сегодняшний день -- " религия не позволяет", да и экономия места . На одном мк все переключения -- класс. Кнопки поставлю под с-диодами, давим сд -- он проседает и мжёт кн. Один элемент на панели -- две функции : кн и индикатор, опять же экономия места.)) Пост от Ivanoff-iv на 5-ой стр. вверху отвечает по полной , но без д11-13 и кн на РС5 , и с добавкой двух строк на начальное включение РВ0 и РВ4. В железе пока не пробовал, а в протеусе всё идёт на ура.

Re: Нестабильность из-за задержек

Пт апр 23, 2021 08:27:28

Ivanoff-iv писал(а):Генератор... держи
Не впечатляет, это делитель, и шаг в 1Гц вы не получите и привязан к определенному выводу порта, хотя джиттер отсутствует.

dds-синтез, меандр, правда с джиттером (на ошибку таймера 1 тик), шаг в 1Гц, и на любую ножку порта

Re: Нестабильность из-за задержек

Пт апр 23, 2021 10:11:57

к выводу порта не привязан, не делитель, но и на высоких частотах в 1 Гц может и не влезть...
сейчас усовершенствую... добавлю сохранение остатка от деления - это повысит точность, но должно добавить джиттер в пределах 2 тактов ядра МК.

Re: Нестабильность из-за задержек

Пт апр 23, 2021 14:03:26

Ivanoff-iv, не надо соревноваться, нет смысла.

Максимум что я могу получить на тактовой частоте ядра 16МГц, частота таймера 131072Гц, шаг перестройки равен 0,000030517578125Гц, это точное число, умножите его на 32768 вы получите ровно 1Гц, максимально генерируемая частота 65536Гц.

Этим алгоритмом мне удавалось разгонять stm32f030 тактовая ядра 72МГц, частота таймера 2097152Гц (да 2МГц), что давало мне шаг перестройки 0,00048828125, умножите его на 2048 вы получите ровно 1Гц, и максимум генерируемой частоты 1048576Гц(1МГц).

В этом алгоритме чем выше частота таймере тем меньше джиттер.

Re: Нестабильность из-за задержек

Пт апр 23, 2021 14:32:30

Ридико Леонид Иванович на ассемблере как то решал проблему джитера. Я тогда ещё прогал на асме. Потом мне было не до этого, и я не занимался этим вопросом. Позже обстоятельства, перешёл на си, другие задачи. Недавно столкнулся с этим вопросом. Делал что то вроде генератора импульсов. Вывод на пины программный, по прерыванию. И обратил внимание, что есть задержка. Пишу на си. Полез в дизасм, увидел, что пролог, эпилог портит всю картину. Я стал менять местами переключение пина мк. Добился стабильности, но джитер на один такт остался. Я понимаю так. Нужно отталкиваться от чего то, то ли младшего бита таймера, то ли счётчика команд. Но, я не помню, доступно ли значение счётчика команд. И в ближайшее время собираюсь поднять этот вопрос.
Скорее всего, значение счётчика команд будет недоступно. И нужно отталкиваться от аппаратного таймера, настроенного на работу без предделителя. А это означает, что один таймер будет уже занят как минимум именно для этой задачи.
Короче, навскидку, решение джитера. Смотрим на младший бит. В зависимости от ситуации, если выставлен бит, то. Или наеборот. Ставим nop-ы.

Re: Нестабильность из-за задержек

Пт апр 23, 2021 15:18:31

я сделал по другому: сначала получаю период импульса в тактах мк, это лонг переменная, откусываю от неё младший бит, сколько осталось в старшем, столько раз (минус 1) насчитываю переполнение 8битного таймера, число в младшем бите делю на 2, прибавляю к нему 128 полученное число записываю в регистр сравнения (таймер в стс режиме в регистре до этого было фф) и делаю 2 оборота.
так получаю точность в 2 такта мк.

сейчас пошел дальше: пытаюсь достичь точность в 1 такт, и учесть остаток от деления при вычислении периода (это будет джиттер в 1 такт мк, но иначе точнее чем 1 такт не получить...
код почти дописан - на следующей неделе буду довылизывать и утрамбовывать в тини13...

Re: Нестабильность из-за задержек

Пт апр 23, 2021 15:42:38

Для того чтобы устранить джитер, нужно понимать архитектуру мк. Когда срабатывает прерывание, может выполняться команда либо за один такт, либо 2 такта. Именно поэтому нужно следить за младшим байтом счётчика. Но и этого мало, нужно просчитывать весь путь в обработчике прерывания до переключения пина, для того, чтобы в нужном месте вставить nop-ы.

Re: Нестабильность из-за задержек

Пт апр 23, 2021 16:47:34

да, это я понимаю. поэтому все зависимые от времени процессы возлагаю на периферию - мне проще правильно и заранее рассчитать OCR0A, чем лепить нопы или программные задержки.
в прерывании же от момента вызова до момента переключения пина не будет ничего изменяющего время, даже пин будет переключаться тогглом, чтобы код включения и выключения не отличался.

Добавлено after 5 minutes 29 seconds:
единственный джиттер при правильном коде возможен и он неустраним - это от того что 1 такт мк составляет 1/9600000 секунды и из программы его длительность никак в достаточной степени предсказуемо не изменить.

Добавлено after 16 minutes 32 seconds:
чтото я припоминаю про разное время входа в прерывание... надо бы освежить - перечитать Demiurg, спасибо за напоминание :beer:

Re: Нестабильность из-за задержек

Пт апр 23, 2021 17:28:27

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

Re: Нестабильность из-за задержек

Пт апр 23, 2021 18:12:19

Ivanoff-iv, глянул я ваш код, в протеусе его осциллографом, джиттер просто ужасный, я имею ввиду фазовое дрожание сигнала, в том коде то что вы предоставили джиттер 330мкс.

Если вкратце: в PIC есть NCO-модуль, это аппаратный сумматор, он качается от тактовой частоты ядра 16МГц, джиттер в нем 1/16МГц.
В моем коде использовался программный сумматор.
И так чип stm32f030, код обработки прерывания DMA
Тактовая МК 72МГц, чем выше эта частота тем быстрее выполняется расчет в прерывании, таймер настроен на частоту 3МГц, увы, выше надо поднимать тактовую частоту, чип выше не тянет.
Таймер пинает с частотой 3МГц DMA, буфер DMA 512 ячеек. можно было бы сказать байт, но там не байт, uint16_t.
Прерывание DMA половинка и полный, пока 1 половинка заполняется, 2 половинка выплевывается, процесс кольцевой, запустил и забыл.
Выплевывается в регистр ШИМ который принимает всего два значения, 0-0% 1-100%.

Всего 3МГц при оптимизации -Os, на помню NCO-модуль в PIC качается от 16МГц, а AD9833 от 25МГц.

Re: Нестабильность из-за задержек

Пт апр 23, 2021 18:17:43

Но мы в теме AVR.

Re: Нестабильность из-за задержек

Пт апр 23, 2021 18:21:04

Но мы в теме AVR.
При тактовой 16МГц, частота таймера 200кГц, с натягом 250кГц, джиттер составит 1/250кГц = 4мкс.
Вопросы есть?

Re: Нестабильность из-за задержек

Пт апр 23, 2021 19:06:31

Ну как бы я выше написал. На си, разбег 1-2 такта. Прибил гвоздями переключение пина в прерывании. На ассемблере я это сделаю ещё лучше. Понял как. Как бы решение уже написал.

Re: Нестабильность из-за задержек

Пт апр 23, 2021 19:56:59

Demiurg писал(а):На ассемблере я это сделаю ещё лучше.
Частота прерывания таймера должна соответствовать степени двойки: 65536Гц 131072Гц 262144Гц и т.д. это нужно что бы получить идеальный шаг к примеру в 1Гц, в противном случае он будет дробный, к примеру 1,05Гц или 1,34Гц.

Емкость сумматора (битность) влияет на шаг перестройки:
к примеру при частоте прерывания таймера 65536Гц
16 бит - шаг 1Гц
17 бит - шаг 0,5Гц
18 бит - шаг 0,25Гц
джиттер в любом случае составит 1/65536Гц = ~15мкс

при частоте прерывания таймера 131072Гц
17 бит - шаг 1Гц
18 бит - шаг 0,5Гц
19 бит - шаг 0,25Гц
джиттер в любом случае составит 1/131072Гц = ~7,62мкс

Проблема в том что при 17 бит уже 32 битная переменная нужна, ну нету у нас uint24_t.
А вот эта конструкция
Код:
   if(myBByte.bit.b7)
   PORTB |= (1<<(PORTB0));
    else
   PORTB &= (~(1<<(PORTB0)));
занимает всего 4 строчки asm,
Код:
sbrs
rjmp
sbi
cbi
эффективнее ее не сделаешь.
Вот эта
Код:
uint16_t  n_counter = 1012;
переменная, не константа, что бы загружать из вне.
Если прерывание таймера 131072Гц, то максимум n_counter может принимать 65535, 2 байта.
А если прерывание таймера 262144Гц, то максимум n_counter может принимать 131071, увы 4 байта надо.
На stm32 проще дело обстоит, там расчеты идут непосредственно с 32 битными переменными.

Как опыты показали, Атмега с успехом гонится до 27МГц, а не которые экземпляры работают и от 32МГц.
А с другой стороны есть специализированная микруха AD9833, и стоит копейки.

Re: Нестабильность из-за задержек

Сб апр 24, 2021 05:11:34

Код:
sbic
rjmp label_1
sbi
rjmp label_2
label_1:
cbi
label_2:

Ты асм подзабыл...
AD9833, интересная таракашка. Где, почём берёшь?

Re: Нестабильность из-за задержек

Сб апр 24, 2021 17:22:11

Demiurg писал(а):Ты асм подзабыл...
Вроде бы.
Во общем так:

Re: Нестабильность из-за задержек

Сб апр 24, 2021 19:22:40

Я бы посоветовал тебе найти статью Ридико про генератор сигналов на AVR. Он писал, что ему самому давали советы зарубежные эмбеддеры по оптимизации ассемблерного кода. Можно от регистра отталкиваться, можно от пина. И именно второй метод эффективнее при меандре. Да и вообще, зачастую есть случаи, когда нужно смотреть на состояние пина. Это ресурс вообще то. Когда сам пин и есть индикатор состояния. Не нужен доп регистр под эту задачу.
Кстати, Ридико один из тех, у кого я учился примерам работы с AVR.

Re: Нестабильность из-за задержек

Сб апр 24, 2021 21:08:43

Demiurg писал(а):Я бы посоветовал тебе найти статью Ридико
Это вот эту что ли?
Уважаемый, я перепробовал все методы, все коды, которые есть в инете, даже Чена на stm32f100 12 битный DAC, +еще по i2c лепил к f030 mcp4725, других не было в наличии.
В основе всех методов лежит один и тот же принцип.
В статье Ридико используется 28 битный сумматор, +внешний ЦАП.
Синус, элементарно
Что бы проверить теорию, вы можете протеус раскочегарить до космических скоростей, скорректировав время прерывания таймера, +увеличить сумматор в плоть до 64бит. Протеус все это переварить.

Re: Нестабильность из-за задержек

Пн апр 26, 2021 16:18:57

Ivanoff-iv, глянул я ваш код, в протеусе его осциллографом, джиттер просто ужасный, я имею ввиду фазовое дрожание сигнала, в том коде то что вы предоставили джиттер 330 мкс
Где такое :shock: как увидеть? да, шаг приращения частоты просто ужасный на "верхах", но джиттера нет совсем.
сейчас переделываю - при такте 9,6МГц получил до 15кГц с шагом от 0,3Гц с меньшим шагом упирается в разрядность инт переменной, задающей частоту (при шаге 0,1 максимум составляет 6,5кГц).
джиттер теперь есть, составляет 1 такт МК, т.е. чуть больше 0,1us.
по прежнему хватает тини 13, задействован её таймер... ресурсов хватает и на другие вычисления. (писал на С).
принцип такой: из частоты (Frq) нахожу полупериод, который разделяю на 3 переменные:
Hr-количество полных оборотов таймера
Min - количество тактов плюсом к оборотам таймера (эти переменные были и в прошлой версии но под другими именами)
Sec - остаток от деления - т.е. к каждому полупериоду надо добавить Sec/Frq такта. но т.к. добавить величину меньше такта нельзя, то я складываю её в счетчик (почти DDS :) ) и по его переполнению увеличиваю на 1 раз период на 1 такт - так в среднем получается ровно та частота, которую задавали.

Re: Нестабильность из-за задержек

Пн апр 26, 2021 16:25:57

сейчас переделываю - при такте 9,6МГц получил до 15кГц с шагом от 0,3Гц с меньшим шагом упирается в разрядность инт переменной, задающей частоту (при шаге 0,1 максимум составляет 6,5кГц).
джиттер теперь есть, составляет 1 такт МК, т.е. чуть больше 0,1us.
по прежнему хватает тини 13, задействован её таймер... ресурсов хватает и на другие вычисления. (писал на С).

А ничего что у встроенного генератора tiny13 точность ±2% после калибровки? Это сколько тактов помимо того одного? :)
Ответить