Делитель/умножитель ШИМ

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение СКАЗОЧНИК »

Доброго дня. ) Давно забросил уже все это дело, а тут вдруг понадобилось.

Помогите пнуть меня в нужном направлении.

Есть входной сигнал , пусть с частотой 4 Гц. Его я делаю захват на выводе ICP1 контроллера Атмега8.
Настроил таймер1 с делителем на 256 при частоте 16 МГц.
В прерывании по фронту входящего импульса значение регистра ICR1 записывается в буферную переменную.

Теперь мне нужно вывести такой же сигнал на любой вывод любого порта МК. Т.е. тупо повторить его. (не спрашивайте зачем).

Думал тоже таймером Т1, но не подходит, т.к. он занят измерениями периода. А другие таймеры 8 разрядные. Как я в них впихну 2 байтную переменную?

З.Ы. сигнал входящий может плавать до 400 Гц примерно. А в последующем мне надо будет выходной сигнал с МК не тупо копировать, а чуток менять, например умножать на два.

З.З.Ы. входящий ровный меандр

З.З.З.Ы. выходной сигнал от входного отстает на один период, т.е. сначала МК определяет время периода, потом выдает такой же на другом выходе.
Станислав
Реклама
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение akl »

Думаю, надо выделять оба полупериода как длительность 1, так и длительность 0, благо это просто делается установкой/сбросом ICES1
Реклама
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение СКАЗОЧНИК »

Тогда я смогу точно измерять длительность импульса и период. Можно будет копировать ШИМ. Об этом думал.
Пока задача стоит тупо повторить сигнал на другом выводе МК. С опозданием на 1 период.

Добавлено after 3 minutes 8 seconds:
Может не туда пишу, но можно ли это реализовать на одном таймере1, который 16 битный?
Т.е. захват сигнала, его измерение и выдать этот же сигнал на ОС1А вывод? При этом, чтобы его можно было умножить/поделить на 2.
Последний раз редактировалось СКАЗОЧНИК Ср мар 04, 2020 14:16:36, всего редактировалось 1 раз.
Станислав
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение akl »

Если не использовать канал ICP для сравнения, то, думаю, можно.
When the ICR1 is used as TOP value (see description of the WGM13:0 bits located in the TCCR1A and the TCCR1B Register), the ICP1 is disconnected and consequently the Input Capture function is disabled.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение СКАЗОЧНИК »

А как я тогда буду измерять период? :dont_know:

Что-то мне говорит, что надо реализовывать все на тиках какого-либо таймера... Вроде что-то подобное здесь описано: https://radiohlam.ru/shim_mul/
Станислав
Реклама
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Z_h_e »

СКАЗОЧНИК писал(а):З.З.З.Ы. выходной сигнал от входного отстает на один период, т.е. сначала МК определяет время периода, потом выдает такой же на другом выходе.
СКАЗОЧНИК писал(а):Т.е. захват сигнала, его измерение и выдать этот же сигнал на ОС1А вывод? При этом, чтобы его можно было умножить/поделить на 2.
Тут надо сразу закладывать в алгоритм что сигнал может быть модифицирован. Например, если сигнал разделен на 2, то как он может отставать на один период?
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение СКАЗОЧНИК »

Надо было свою тему создавать. Просто не захотел плодить.

Короче, идея простая. Для СВАПа. Поменяли двигатель или коробку или колеса в машине, а спидометр/тахометр врать начинают. Вот и надо устройство, которое может плавно подстраивать входящие импульсы в обе стороны. Примерно от 1 к 1 до 1 к 10.
Естественно, что делить это уже чуток другая тема, т.к. ждать придется, пока не закончится выходящий, чтобы скорректировать новый. А вот при умножении можно сразу.
Почему и пишу, что отстает выход от входа на один период. При делении будет все по другому.

Есть у меня устройство готовое. На Атмега8. Но прошивка залочена, естественно, он же коммерческий. ))))
Приходится мутить свое.

З.Ы. Естественно, входящий сигнал может меняться в зависимости от частоты вращения агрегата.
Станислав
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Делитель/умножитель ШИМ

Сообщение Z_h_e »

Что-то мне кажется тут лучше не по частоте. Я бы по количеству импульсов сделал наверное.
На входе считать количество импульсов.
Работу МК дискретизировать на тайминги, например по 250мс. Считаешь разницу между количеством на конец тайминга и начало, пускай это Nf.
Считаешь сколько надо отправить Nc=Nf*K, с огруглением вниз до целого. Откинутый остаток запоминаешь и суммируешь его с предыщущим остатком, если остаток больше 1, то Nc+=1; а у остатка вычитаешь 1. И в следующий тайминг, размазав равномерно количество Nc по периоду 250мс, отправляешь это количество, одновременно считая входные импульсы для нового тайминга.

Не знаю, удалось нет сформулировать мылю понятно или нет.

Добавлено after 4 minutes 50 seconds:
Будет стабильная задержка на 250мс. Думаю допустимая , ведь реакция человека это "медленный газ". Но можно и уменьшить.

В принципе тут скорее всего лучше все прогарммно реализовать, кроме прерываний для отметок тайминга. При этом даже "кварцевать" генератор на надо, сойдет и внутренний генератор.

Ну еще прерывание , то же по переполнению, но другого таймера, для выдачи Nc размазанных импульсов. Но тут дело вкуса уже в реализации.
Последний раз редактировалось Z_h_e Ср мар 04, 2020 17:46:30, всего редактировалось 1 раз.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение СКАЗОЧНИК »

А если входные импульсы идут с частотой всего в 4 Гц? Они как раз 250 мс...
Станислав
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Z_h_e »

Они не пропадут.

Добавлено after 1 minute 3 seconds:
Выходная частота будет, при К=1, то 2 импулса в один 250мс, то ни одного, например.

Добавлено after 46 seconds:
Ну этот так, предложение. Надо думать и проверять.

Добавлено after 3 minutes 27 seconds:
Тайминги можно уменьшить или увеличить. Если делать по счету импульсов, то для одометра будет погрешность ноль, а вот как показания спидометра будут, надо пробовать. Что там с усреднением у стрелки?

Добавлено after 1 minute 34 seconds:
ИМХО. Тему действительно стоит вынести в отдельный топик, можно модератора спросить.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение СКАЗОЧНИК »

А вот не знаю, что там с усреднением. Но больше в этом волнует тахометр. Он то должен вроде живо отзываться на изменения.
Потому и думал, что надо по одному периоду вычислять новые значения.
А вот как быть, если я поделил на 9 входной и выдал на выход. У меня пока этот один будет длиться (в 9 раз длиннее) может много чего произойти на входе.

Модераторы, пожалуйста выделите тему в отдельный топик. :oops: Можно его обозвать делитель/умножитель ШИМ.
Станислав
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Z_h_e »

СКАЗОЧНИК писал(а):Модераторы, пожалуйста выделите тему в отдельный топик. :oops: Можно его обозвать делитель/умножитель ШИМ.
В личку напишите, не думаю что тут каждый пост модеры просматривают.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение akl »

Когда-то давно была похожая тема. Лень искать в теме, проще повторить. :)
N_M.rar
(15.68 КБ) 233 скачивания
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

Эта задача не обязана решаться "в реальном времени", т.е. период в период. Для спидометра и тахометра вполне достаточно запаздывания до 1 секунды, а то и более.
Организуете измерение периода (или длительности одного импульса, если меандр) и выкладываете результат в глобальную переменную. В главном цикле время от времени смотрите эту переменную и на любом другом таймере (да хоть и на тупых задержках, пофиг!) реализуете выходной сигнал.
Вот и весь алгоритм, и не надо привязывать входной сигнал к входному, они могут быть (и должны быть, имхо) независимыми.
Последний раз редактировалось ARV Ср мар 04, 2020 21:13:22, всего редактировалось 1 раз.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение NStorm »

[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=3801490#p3801490"]Короче, идея простая. Для СВАПа. Поменяли двигатель или коробку или колеса в машине, а спидометр/тахометр врать начинают. Вот и надо устройство, которое может плавно подстраивать входящие импульсы в обе стороны. Примерно от 1 к 1 до 1 к 10.

З.Ы. Естественно, входящий сигнал может меняться в зависимости от частоты вращения агрегата.[/uquote]
Очень похожую решал знакомому задачу для тахометра. Только на простеньком pic12f683, хватило с головой. Надо было увеличивать длительность импульсов на 1/3. Но это по-умолчанию, а переменником на АЦП это дело еще регулировалось от 1/5 до 1 вроде. Вход делал захватом, выход после захвата одного периода измененный выдавался. Просто с захваченными цифрами пересчитывал их настраивал ими другой таймер на выход. Один период задержки вполне устраивал, реакция на изменения тоже за глаза получалась. Завтра гляну код, что я там писал точно не помню уже, а сегодня уже некогда.
EDIT: Поправил цифры в абзаце выше после заглядывания в код.

Добавлено after 13 minutes 43 seconds:
Залез всё-таки в код - захват делал на 16-битном таймере, выводил на 8-битном. Считал вообще через float, т.к. плавно по АЦП менялось когда надо было. У меня двойной буфер был - сначала считал значение после захвата, если оно изменилось, как посчитал выходное значение - если оно отличается от прошлого, то тогда обновляем его и поднимаем флаг, что параметры выходного таймера надо обновить и всё. Математика на тех частотах сигнала всегда за один период всё успевала посчитать. Выходной 8-битный таймер в прерывании "эмулировал" 16-битный с дополнительной переменной кол-ва переполнений просто, выход банальном там же ногодрыгом. Как-то так:

Код: Выделить всё

uint16_t get_outval(uint16_t in) {
    float ratio = 1.33;
    if (flag.adcmd && adcval >= ADC_MIN && adcval <= 1024)
        ratio = ((float)adcval / 1024) + 1;

    return (uint16_t)((in / 2) * ratio);
}
...

void interrupt isr() {
    static volatile uint8_t t0ovfcnt = 0;

    if (T0IF && T0IE) {
        t0ovfcnt++;
        // overflow count == high byte of outval
        if (t0ovfcnt == outval.byte[1])
            // Preload Timer0 with low byte
            TMR0 = (uint8_t)(255 - outval.byte[0]);
        // Last overflow condition
        if (t0ovfcnt > outval.byte[1]) {
            OUT = ~OUT; // invert output
            t0ovfcnt = 0;
            // input value was updated, need to copy new
            if (flag.ccpup) {
                outval.word = outval_tmpbuf.word;
                flag.ccpup = false;
            }
            TMR0 = 0;
        }
        T0IF = 0;
    }
    // Input capture
    if (PIR1bits.CCP1IF) {
        if (!flag.t1ovf) {
            inval.word = CCPR1;
            flag.inrun = true;
        }
        else
            flag.t1ovf = false;

        TMR1 = 0;
        CCP1IF = 0;
    }
...
Добавлено after 23 minutes 20 seconds:
Но мне как видно только умножать длительность нужно было. Смещение из-за ногодрыга и нескольких условий в прерывании даже МК на 8МГц несколько тиков - совсем несущественно было для тахометра и тех частот в несколько сотен Гц.
С делением... программно больше заморочек будет, хотя тем же макаром с ногодрыром по таймеру - почему бы и нет? Вам же для показометров этих не нужна 100% точность по частоте, несколько тиков МК погоды не сделают, если у вас там и правда меандр около 4 Гц.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

Для тахометра отставание в 1 секунду уже очень много. Все же склоняюсь к измерению первого периода. Потом по результатам расчеты и вывод уже новой частоты. Причем, как я понял из предоставленных мне графиков, все же надо ШИМ копировать. Чистый меандр это частный случай лишь для некоторых видов.

Делать, похоже, надо по схеме с "частотой дискретизации" по прерываниям таймера. Все остальное уже почти тупым ногодрыгом. Замерять же фронты можно тупым захватом, но не использовать измеренное время, а просто в прерывании обновлять переменную.

Точность , та что написана в той статье, 3%. Это уже не сильно повлияет на результаты в стрелочных приборах.

И да, для любознательных или вредных людей, CAN-шину не рассматриваю. Это к тому, если начнут говорить, что есть крутые машины с такой шиной и к ним эту приблуду не прилепишь. ) И не собирался.

З.Ы. вот неплохой сайт с осциллограммами. но там бестолковые картинки в плане не подписано и не на тахометр. Просто датчики... ((((
https://injectorservice.com.ua/oscillograms.php#0
https://injectorservice.com.ua/docs/wav ... toyota.pdf
Станислав
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Делитель/умножитель ШИМ

Сообщение NStorm »

Я делал как - мне померили как стало после замены движка. Всегда чисто меандр был, ЧИМ. Померили на холостых, на макс оборотах и некую среднюю точку - написали частоты. И обороты сколько точно должно было быть на холостых и максимальных и примерно на средних. Ну и сколько показывает сейчас. В общем видно было, что зависимость изменения линейная, на треть. Но на всякий случай с АЦП решили реализовать "подгонку". Взял частоты - минимум на холостых и максимум на максимуме плюс-минус 30% добавил запасу. Чтобы в диапазон этих частот захват таймера попадал. Захват по одному из фронтов только, т.к. у меня меандр только. Частоты не помню уже какие были, где-то в пределах от сотни Гц до 1 кГц вроде.

Алгоритм - инит всего, замер ацп, запуск захвата. На входе может ничего и не быть какое-то время. В этом случае на входе низкий уровень. По этому и захват по спаду делаем, чтобы лишнее не считать просто. Как прошел захват - вот просто цифру таймера берем как есть и преобразуем как есть в виде uint16_t Складируем в буфер. Ну тут ес-но прикидываем чтобы после преобразования, с учетом диапазона частот входных, поместилось всё в эту переменную. Если это первый захват - копируем в основной буфер уже выходное значение, запускаем 2ой таймер с тем же предделителем. Ну и как я сказал считаем переполнения по старшему байту, по младшему догоняем последний прогон таймера, чтобы "симулировать" 16-битный таймер. Изменилось входное значение - в основном цикле где-нибудь считаем новое выходное значение, складируем его во 2ой буфер, поднимаем флаг об изменении частоты сигнала. В прерывании выходного таймера как полностью период готовый выдали - смотрим, если этот флаг поднят - обновляем выходное значение из буфера. Чтобы изменения не искажали сигнал.

Всё проверено, вполне работает. В протеусе сначала гонял, потом в железе. Как-то так, снизу входной сигнал, сверху выходной.
Вложения
car-gauge.png
(50.09 КБ) 259 скачиваний
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

Тоже сижу в протеусе моделирую. )

Вот и думал над делением также. Пока он выходной импульс выкидывает просто тупо мерить новые и постоянно обновлять. Закончился выходной, скорректировался с новыми значениями и опять в путь. Это для деления.
Для умножения вроде попроще.
Станислав
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Делитель/умножитель ШИМ

Сообщение NStorm »

Да в общем-то да, для деления принцип тот же самый. Но разница есть. У меня для умножения выходной таймер с той же частотой работает. Так я цифру захвата просто умножаю на нужный коэф и сразу могу "скармливать" выходному. А тут с той же частотой и заданной "частотой дискретизации" возможно весь диапазон не поместится выходной у вас. И придется выходной таймер запускать с другим предделителем и соотв. цифры пересчитывать. Хотя ничего невозможного конечно. Опять же пригодится двойной буфер, и да, корректировать выход после полного выходного импульса просто и всё. Смещение фаз для данной задачи никакой роли не играет, поэтому тут проще.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

Торможу.

Решил делать все таки по настроенным тикам таймера0 в 16 мкс (62500 раз в секунду). Каждый раз вызывается прерывание по переполнению, в котором происходит инкремент счетчика. Счетчик двухбайтная переменная.
Теперь пошли два варианта:
1. Тупо в прерывании проверять состояние пина (на который приходят входящие). и по его изменению регистрировать сколько прерываний было и это ширина импульса. Ну и период целиком. (не знаю понятно ли написал).
Потом пересчитывать значения этих двух счетчиков и загонять в Т1, который отмеряет уже выходящий импульс.
2. Таймером 1 ловить изменения фронта (делать захват) в этот момент сохранять значения счетчика прерываний Т0. менять значения, что ловить дальше, и фиксировать уже весь период. Дальше делать вычисления новой частоты и ... Как эти новые значения и через что выводить наружу? Если Т1 уже занят.

Добавлено after 1 minute 23 seconds:
Или можно теми же прерываниями от Т0 отсчитывать новые значения тупо делая декремент новых переменных и дергать любой пин...
Последний раз редактировалось СКАЗОЧНИК Чт мар 05, 2020 16:05:46, всего редактировалось 1 раз.
Станислав
Ответить

Вернуться в «AVR»