Освоение Атмеги или кипит наш разум

Boroda

10к резистор будет уже заметно резать фронты, вполне достаточно 100 ом для чистоты фронта, а для надёжной защиты от сквозного тока 470 ом. Ограничение по ноге 20мА.

У 8 меги есть регистр захвата ширины импульса, работающий с первым таймером. Самое оно, чтоб ловить PPM в фоновом режиме. Как уже заметили выше, мощный PWM механизм таймеров позволит легко сформировать выходной сервосигнал. И опять-же аппаратно.
Изучайте документацию!
А всё остальное зависит от вашей фантазии и типа индикатора, который соберётесь использовать.

msv

Все так, конечно, но имхо есть одна тонкость…
Если с приемника попрет шум, есть шанс повесить МК, завалив прерываниями.
Может поэтому во всех декодерах на МК которые видел ( правда на PIC, да и смотрел исходники по диагонали) не используются прерывания вовсе?

ЗЫ Тоже вынашиваю идею сделать интегрированное устройство декодер+поисковую сиренку+контроль акков борта. Пока не определился на PIC или меге. Буду с интересом следить за темой.

Boroda
msv:


Если с приемника попрет шум, есть шанс повесить МК, завалив прерываниями.

А программная обработка шума на ноге его не повесит? Шумы несложно давить как схемотехникой, так и логикой самой прошивки.

BelMik
msv:

Все так, конечно, но имхо есть одна тонкость…
Если с приемника попрет шум, есть шанс повесить МК, завалив прерываниями.
Может поэтому во всех декодерах на МК которые видел ( правда на PIC, да и смотрел исходники по диагонали) не используются прерывания вовсе?
.

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

msv

А программная обработка шума на ноге его не повесит?

Ну опрашивать то можно так часто, сколько нужно. И даже специально делать паузы игнорируя возможные помехи (как это сделано в популярном SmartDecoder).
2BelMik Если полоса 3кгц, то надо быть готовым обрабатывать за ~0.16ms. Это дествительно без проблем пережует МК? (Пока не смотрел сколько тактов занимает процедура входа/выхода из прерываний, но готов вам поверить).
Еще, немного офф, где-то попадалось что в приемнике не желательно применять мегу, тк они более шумные чем пики. Это действительно так?

Pavel_E
Andrey73:

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

Именно поэтому тема и создана. Чтобы разобраться. Так что все советы всячески приветствуются!

За вчера думал попробовать прерывания и генерацию ШИМ. А успел освоить только вывод десятичной цифры на светодиодный индикатор. Осознал, что решительно не хватает ног на амтеге8 - индикация всего двух знаков отжирает 9 выводов! На все прочее остается маааало…

Читал даташит. Вроде все написано, а че-та непонятно. Объясните темному, что лучше использовать для срабатывания прерывания по сигналу от приемника?
Варианты: PD2 (INT0 - внешнее прерывание), PD3 (INT1- внешнее прерывание), PB0 (ICP1 - Timer/Counter1 Input Capture Pin), еще что-то? Как я это вижу - по изменению сигнала на ноге с 0 на 1 или с 1 на 0 включается прерывание, которое запускает или останавливает таймер. Если останавливает, то выдает в программу значение счетчика таймера.

Так?

msv:

ЗЫ Тоже вынашиваю идею сделать интегрированное устройство декодер+поисковую сиренку+контроль акков борта. Пока не определился на PIC или меге. Буду с интересом следить за темой.

Могу предложить поучаствовать 😃 Например по коду программы в части контроля акков борта. Пока не видел грамотных индикаторов липолек, которые бы кричали и моргали при просадке ЛЮБОГО элемента батареи ниже 2в. Индицировать-то все индицируют, а надо орать в голос.

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

Поисковая сиренка + фотовспышка (чтоб моргала в темное время суток) у меня тоже в планах.

sht0p0r
Pavel_E:

Читал даташит. Вроде все написано, а че-та непонятно. Объясните темному, что лучше использовать для срабатывания прерывания по сигналу от приемника?
Варианты: PD2 (INT0 - внешнее прерывание), PD3 (INT1- внешнее прерывание), PB0 (ICP1 - Timer/Counter1 Input Capture Pin), еще что-то? Как я это вижу - по изменению сигнала на ноге с 0 на 1 или с 1 на 0 включается прерывание, которое запускает или останавливает таймер. Если останавливает, то выдает в программу значение счетчика таймера.

Так?

нет не так
int 0,1 генерируют прерывания и запускают обработчик события (что в нем будет ваша проблема 😃 )
ICP1 может генерировать прерывание, а может и нет (только поднять флаг, что ICR1 обновлен) в любом случае в регистре ICR1 доступно положение счетчика таймера 1 в момент срабатывания ICP1.
таймеры при этом не перезапускаются пока вы это несделаете в ручную.
у вас 2 пути …
я сделал 2 канала с приемника по int и один, с датчика хола, по ICP

Pavel_E
sht0p0r:

int 0,1 генерируют прерывания и запускают обработчик события (что в нем будет ваша проблема )

Тогда так:
Вариант 1: на int0 или int1 заведен сигнал с приемника. Биты ISC11 и ISC10 регистра MCU установлены в значения 0 и 1 соответственно. Это должно установить режим “Any logical change on INT1 generates an interrupt request.” Т.е. любое изменение логического состояния вызывает прерывание. Правильно я понимаю? Тогда останется в обработчике прерывания посчитать время между его срабатываниями по нулю и по единице. Это можно сделать, запустив любой таймер по единице и остановив по нулю. Потом обнулить и снова в путь.

или Вариант 2:
Использовать ICP1. Установить прерывание по изменению состояния ноги и при срабатывании оного читать из регистра ICR1 сколько там натикало. И никаких таймеров запускать не надо.

А?

P.S.Я тоже вдруг сильно захотел 2 канала приемника и 1 датчик холла для контроля что вал крутится…

sht0p0r

я немного не так сделал
1 прерыванийе ставим на фронт
ждем
обработчик
1.1 берем timestamp с таймера 1 (он 16 бит)
1.2 проверяем что за прерывание пришло фронт или спад
1.3 пишем timestamp в timestamp_R или в timestamp_F (соответственно)
1.4 переключаем прерывание на определение фронта или спада (в зависсимости от того что пришло)
1.5 если пришел спад то поднимаем флаг(готово время для рассчета ширины импульса)
2 в основной программе
while(1){
2.1 если поднят флаг то рассчитываем ширину импулса (с учетом длинны счета таймера и переполнения, если таковое было между фронтом и спадом )
все можно наслаждаться.
2.2 если поднят флагг…
2.3 если поднят флаггг…
2.4 если поднят флаггггг…
2.n придушить бешеную собаку!!!
}
как использовать icp1 для тахометра попробуйте придумать сами
главное не перегружайте прерывания.
есть 2 пути
1 разрешить прерывание внутри преывания результаттом может стать stack overflow 😃
2 написать прерывания максимально короткими и быстрыми. таким образом быть почти уверенным, что прерывания не произойдут во время обработки другого.
тут опять же решать вам.
зы попробуйте написать сами экспириенс просто попрет…

Pavel_E

Тов. Штопор, мерси за алгоритм! Вроде вкурил что и как, пора в железо воплощать.

sht0p0r:

1 разрешить прерывание внутри преывания результаттом может стать stack overflow

В одной умной книжке прочитал, что, это типа невозможно и прерывания выполняются по очереди.

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

Я еще подумал, может плюнуть на это дело и тупо мерить усредненное конденсатором напряжение выхода приемника? Но эта мысль вредная, пока отгоняю.

sht0p0r

во время исполнения прерывания мега на внешние раздрожители не реагирует. если не разрешить их програмно внутри обработчика в конце за собой надо подчистить 😃

последняя мысль очень вредная. имхо
книжка товарища Шпака “порограмирование на С авр и пик” как то так называется. вам поможет освоить это б…ство.

valera_o

если будете покупать, купите мегу88, для внешних прерываний можно использовать практически все ноги портов, памяти столько же, опять же мега8 снята с производства.
Книга “Микроконтроллеры AVR семейства Mega” А.В.Евстифеев 2007
тоже хороша для освоения устройсва контроллеров.

Boroda
Pavel_E:

или Вариант 2:
Использовать ICP1. Установить прерывание по изменению состояния ноги и при срабатывании оного читать из регистра ICR1 сколько там натикало. И никаких таймеров запускать не надо.

Надо. В регистр ICP записывается значение из РАБОТАЮЩЕГО tcnt1 именно в
момент прихода сигнала на ногу. Таймер при этом не останавливается. Когда ICP будет прочитан в прерывании или основном теле, вам не надо будет задумываться о том сколько тиков прошло с момента прихода фронта до момента чтения регистра таймера.

PigTail
valera_o:

… опять же мега8 снята с производства.

И где это такие сведения? 😉 www.atmel.com/dyn/products/devices.asp?Status=Matu…® 8-Bit RISC
Если топикстартеру ща еще подсунуть 88 с разницей в регистрах после 8, то он точно закипит 😃

Pavel_E

м-да…
😵
надо выспаться. может уложится по полочкам и будет просто 😃

Слушайте, как вы женам объясняете, чем занимаетесь, а?

Aleksey_Gorelikov

ну объясните ей, что вот такая мелкая микросхемка - ни что иное, как полноценный компутер, что такая штука может являться брелком к авто сигнализации, самой сигнализацией, что авто, что домашней, “мозгами” стиральной машины, пультом от телека, часами с будильником и т.д. и т.п. Что все зависит от того, какую программу для нее написать. Глядишь, попросит мк с акселерометром в утюг встроить, чтоб отключался сам, если его на любимых трусах забыли и дырку не прожег. 😃

Pavel_E

Новости с фронтов.
Убит вечер пятницы, вся суббота и воскресенье. Поставленная задача решена на 70%. Умею управлять сервой и выводить произвольную информацию на четырехразрядный светодиодный индикатор. Осталось научиться расшифровывать сигнал с приемника, но вроде уже понятно как.

Не хватило ножек. Мигрировал на 40ногую атмегу16. Зверь.

Заодно вопрос-восклицание. 8-и битный таймер не может достойно управлять сервой в режиме PWM. Расчет простой - максимум на период 20мс (50Гц) приходится 256 отсчетов таймера. Т.е. 12,8 отсчета на одну миллисекунду. Нам нужен регулируемый импульс длительностью в диапазоне от 0,8 до 2,2 мс. Т.е. в лучшем случае - 18 отсчетов. Если рабочий угол сервы 180градусов, то получается можем задавать не точнее 10 градусов! Короче, в сад или в 16 бит. А 16 бит жалко на такое дело транжирить…

msv

Для декодирования по алгоритму sht0p0r можно и 8-разрядный таймер программно наростить и брать с него timestamp. А 16-разрядный использовать для ШИМА.
А что собственно за девайс изобретаете?
Если это декодер, никак не врублюсь как аппаратным PWM можно раздать импульсы на 8 каналов…

Pavel_E
sht0p0r:

я немного не так сделал
1 прерыванийе ставим на фронт
ждем
обработчик
1.1 берем timestamp с таймера 1 (он 16 бит)
1.2 проверяем что за прерывание пришло фронт или спад
1.3 пишем timestamp в timestamp_R или в timestamp_F (соответственно)
1.4 переключаем прерывание на определение фронта или спада (в зависсимости от того что пришло)
1.5 если пришел спад то поднимаем флаг(готово время для рассчета ширины импульса)
2 в основной программе
while(1){
2.1 если поднят флаг то рассчитываем ширину импулса (с учетом длинны счета таймера и переполнения, если таковое было между фронтом и спадом )
все можно наслаждаться.
2.2 если поднят флагг…
2.3 если поднят флаггг…
2.4 если поднят флаггггг…
2.n придушить бешеную собаку!!!
}

А вот вопрос. Под “поднятием флага” понимается просто запись значения в какую-нибудь переменную для обработки программой? А как оно будет работать, если программа сложная и быстродействия не хватит, чтобы успевать между импульсами (20мс)?. Т.е. может быть, что флаг поднят, но значение по фронту уже перезаписалось другим импульсом, не успев быть учтенным в программе. И тут она начнет его учитывать…

msv:

Для декодирования по алгоритму sht0p0r можно и 8-разрядный таймер программно наростить и брать с него timestamp. А 16-разрядный использовать для ШИМА.

Наверно так и сделаю. Но уж очень удобна автоматизация работы внешних прерываний именно с 16-битным таймером. Тем более, на атмеге16 внешних прерываний 3.

Альтернативная мысль: “наростить программно” ШИМ на 8-битном таймере. Т.е. в цикл таймера загнать время импульса, а скважность считать по количеству циклов, используя для хранения количества переменные в программе. По переполнению таймера проверять сколько циклов натикало и если хватит, обнуляться и пускать сигнал заново.

А можно и не парить мозг, а оставить этот режим для того, для чего он и предназначен. Т.е. генерировать ШИМ для управления, например, коллекторным двигателем.

msv:

А что собственно за девайс изобретаете?

Да пока просто разобраться хочу что такое микроконтроллер, что он может и что я на нем могу. Вообще хочется научиться брать любой сигнал, обрабатывать программно и генерировать свой сигнал. Ну а в частности - написать приблуду для автоматического управления комнатной автомашинкой, чтобы при попадании в препятствие давала задний ход, разворачивлась и т.п. Лампочками моргала и сиреной гудела. И о разряде липолек информировала. И каналы управления инвертировала если ее перевернуть вверх ногами. Сына веселить.

Еще хочу сделать вольтметр и амперметр на базе атмеги с цифровой индикацией.

Еще хочу брать NMEA с GPS, углы с гироскопов, высоту с бародатчиков и обороты с винта. И фигачить все это по радиоканалу в цифровом виде на землю. На земле принимать и выдавать на ноутбук в красивой графической форме в виде авиационных приборов.

И чтобы если стемнело, то включалась поисковая фотовспышка хотя бы раз в минуту.

Еще много чего хочу 😃 Вопрос, в какой момент это надоест или когда снова начнется работа…

sht0p0r

msv , а вы попробуйте и узнайте с какими проблемами столкнетесь, при програмном увеличении разрядности таймера.

Pavel_E:

А вот вопрос. Под “поднятием флага”…

да

Pavel_E:

А как оно будет работать, если программа сложная и быстродействия не хватит, чтобы успевать между импульсами (20мс)?

просто не обработаете управляющий импульс.
добавте проверку флага в прерывании int(0,1) если не сброшен то return из прерывания.
ног там более чем достаточно что-то вы включаете не рационально. повесте вашу схемку, думаю ее можно опримизировать.
что мешает гнерировать 16 битным таймером pwm и паралельно брать со счетчика значения?
что мешает програмно, по прерыванию генерировать pwm на нескольких ногах процессора?
включаете прерывание по переполнению таймера, в преравании поднимаете флаг, в основной программе генерируете импульс(ы) задонной длительности с периудом переполнений таймера.во время генерации импульса можно с пользой для дела использовать время процессора (например вывести на индикатор, что нибудь).
активней пользуйтесь аппаратной частью процессора тогда и программа будет обрабатываться быстро.

все уже сделано до вас 😃 www.dmd.es/osd.htm

msv

Если программно наращивать таймер именно для получения timestamp, сложностей никаких быть не может.

что мешает програмно, по прерыванию генерировать pwm на нескольких ногах процессора?
включаете прерывание по переполнению таймера, в преравании поднимаете флаг, в основной программе генерируете импульс(ы) задонной длительности с периудом переполнений таймера.во время генерации импульса можно с пользой для дела использовать время процессора

Мне показалось, что Pavel_E делает декодер, и поэтому не понял, как это можно решить (по многочисленным советам) именно на чисто аппаратном pwm.
Хотя с вышеописанным алгоритмом тоже непонятка. Ведь есть 8-каналов (8 ног) с разным коэфф. заполнения и одинаковым периодом. Время от установки флагов до их обработки непредсказуемое, а значит качественный шим уже не получится.
Вообщем-то у меня вопросов то нет, что-нибудь наваяю, но вероятно и программные задержки ( с запрещенными в эти моменты прерываниями) использовать прийдется.
А в принципе (для абстрактной задачи) с советами по возможности для решения реал-тайм задач использовать прерывания и аппаратные возможности, а в фоновом цикле выполнять фоновые задачи, конечно трудно не согласиться… 😃