Jump to content

parovoZZ

Members
  • Posts

    169
  • Joined

  • Last visited

About parovoZZ

  • Birthday February 12

Информация

  • Пол
    Мужчина
  • Город
    ЛЕНИНГРАД

Электроника

  • Стаж в электронике
    Более 20 лет

Recent Profile Visitors

1564 profile views

parovoZZ's Achievements

Contributor

Contributor (5/14)

  • Collaborator
  • Week One Done
  • One Month Later
  • One Year In

Recent Badges

11

Reputation

  1. Казалось бы, ведь этого добра навалом? Какие задачи ставились при проектировании диммера: 1. Компактный настолько, насколько это возможно. Должен влезать в монтажную коробку. 2. Блок питания простой настолько, насколько это возможно 3. Пружинные клеммники 4. Конечно же, радиоинтерфейс 5. Проводное управление. Зачем? Пусть будет. 6. Полноценное подключение к сети. Двухпроводка не планировалась изначально. Устройство собрано на МК, а это значит, что можно организовать абсолютно любую функциональность устройства. Например, таймер работы - забыли выключить свет и он выключился через заданный промежуток времени самостоятельно. Плавное включение и выключение. Задержка выключения после подачи команды на выключение - не интересно же уходить в потёмках? Обратная связь в виде изменения яркости свечения на одну ступень. Ну и прочие эффекты. Схема здесь: https://easyeda.com/Parovozz/dimmer-v1-1-841 Схема не по ГОСТ. Нарисована хрен знает когда. Так что звиняйте. Блок питания - классический конденсаторный. Такое решение крайне надёжное (применён X/Y конденсатор), но есть у него недостаток: заряд накопительного конденсатора в фильтре выпрямителя происходит только в отрицательный полупериод сети. При положительном периоде заряда нет и питаемся мы только той энергией, которая есть в этом конденсаторе. Есть и положительный момент - заряд и подпитка конденсатора происходит в течение всего отрицательного периода, пока напряжение в сети выше напряжения на конденсаторе. В классическом выпрямителе не так - заряд происходит только в пике полуволны. Емкость балластного конденсатора выбрана не слишком большой, чтобы удовлетворить требованиям по габариту решения. Поэтому и ток в цепи не высок - всего 40 мА. Такое решение накладывает сильные ограничения на потребляемый ток. Поэтому микроконтроллер всегда спит, когда ему делать нечего. Симистор открывается коротким импульсом, не превышающим 50 мкс. Но основной потребитель энергии - это, конечно же, радиотрансивер. В качестве него применяется набивший оскомину nrf24l01+. Он не позволяет задавать длительность преамбулы радиопакета сколь угодно длинной - всего 5 байт. Поэтому фокусы с его периодическим отключением (для сохранения энергии) не проходят. Обязательно наличие предохранителей. Это системный предохранитель в виде PTC с начальным сопротивлением около 50 Ом, а также предохранитель цепи питания лампы - классический 5х20. Детектор нуля - резисторный. Количество резисторов и их типоразмер подобран из условия номинального напряжения на них. Обязательно включён вачдог с периодом 250 мс, обязательно включен монитор питания. Уровень напряжения монитора питания согласован с минимальным уровнем питания радиотрансивера. Нам не зачем работать, если радиотрансивер "отвалился" по питанию. Радиотрансивер же каждые 5 секунд проходит полную переинициализацию вне зависимости ни от чего. Большую головную боль доставили клеммники. Они должны быть пружинными, компактными и на 250 вольт. Такие нашёл (выводы у них расположены по диагонали, что и дало 250 вольт), но только под провод 1.5 мм2. Высота клеммников всего 12 мм и они отлично согласуются с высотой остальных компонентов, которые подбирались очень тщательно. Итоговые размеры 45х50. Скошенные края для удобства укладки проводов. Design =) Симистор в планарном исполнении, охлаждение с помощью полигона на плате. Устройство изначально планировалось под 1 ампер тока в нагрузке, но LED лампы гораздо скромнее в своих аппетитах... Симистор подобран чувствительным - ток управления всего 5-10 мА. Управление непосредственно с ноги МК через ограничительный резистор. TVS диод для снижения уровня импульсов, проникающих через емкость симистора. Устройство собрано на двух платах: одна плата силовая, вторая плата с МК и трансивером. МК - Attiny441/841. Платы крепятся друг к другу перпендикулярно. Монтаж преимущественно планарный, двухсторонний. По итогу эксплуатации выяснилось следующее. Каждая светодиодная лампа диммируется по-своему. Лампы из икеа (ледаре) разных лет выпуска так же работают по-разному. Более старшая не хочет зажигаться, если фаза напряжения диммирования начинается не со 180 градусов. А если открывать симистор сразу после перехода через ноль, то загорается сразу. Диммирование "вниз" - нет никаких проблем. Правда, на момент покупки (более 7 лет назад) она не позиционировалась как диммируемая. Новая ледаре не имеет таких проблем, она легче по весу, и...гудит. Очень понравились филаментные лампы. При диммировании ведут они себя как лампы накаливания. Итог такой - под каждую конкретную лампу необходимо подстраивать параметры. *провода для отладки.
  2. Многие видели промышленные изделия, на платах которых присутствует индикатор "здоровья". Т.е такой индикатор, который моргает и частота моргания напрямую зависит от состояния устройства - часто моргает или редко - заболел совсем или частично, не моргает - что-то сыграло в ящик. Ну или забыли в сеть включить). Давайте тоже создадим такой индикатор. Но пойдём ещё дальше - моргать наш индикатор будет не однократными, а двухкратными вспышками. На диаграмме логического анализатора это будет выглядеть примерно так: Для измерения периодов будет использовать таймер типа TCA. TCA - это тип таймера, а не собственно сам таймер, поэтому запись TCA.xxx.yy будет ошибочна. Порядковый номер таймера обозначается цифрой. В нашем случае это таймер TCA0. TCA таймер - это до боли знакомый по atmega таймер - 16 битный счетчик, 3 компаратора, логика счета вверх и вниз. Но есть и новшества - буферные регистры для компараторов и регистра периода. Режимов работы у таймера несколько - нормальный режим, режим односкатный ШИМ (счетчик считает вверх до максимума и обнуляется), двускатный ШИМ (счетчик досчитав до максимума начинает отсчет вниз). Для реализации нашей задумки мы как раз-таки и будем использовать последний режим. В этом режиме компараторы работают так, как показано на следующем графике: Идея понятна из графика - при счете вверх и совпадении значений регистров CNT и CMPx выход компаратора очищается, при счете вниз - устанавливается. Мы видим, что если выходы компараторов сложить логически по XOR, то на выходе мы получим именно то, что нужно. Складывать (ксорить) мы будем в блоке CCL - Custom Control Logic/ Давайте настраивать наш таймер. Но для начала необходимо настроить главный делитель частоты. С помощью фьюза я выставил привычную для меня частоту в 16 МГц. Сразу после ресета, по умолчанию, делитель настраивается на коэффициент 6. Мы это исправим и выставим коэффициент деления 2 не забывая про регистр защиты CCP: CCP = CCP_IOREG_gc; CLKCTRL.MCLKCTRLB = CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm; // Прескалер главной тактовой частоты первый бит - это разрешение работы делителя. Если он равен нулю, то деление частоты не производится и равно 1. Переходим к настройке таймера TCA0. У таймера есть два фундаментальных режима работы - нормальный (single) и сдвоенный (split). В сдвоенном режиме 16-ти битный счетчик распадается на два 8-ми битных и каждый тикает независимо. также в этом режиме количество компараторов умножается на два. Но этот режим я сейчас разбирать не буду. Остановимся на нормальном режиме. Нормальный режим работы указывается определением SINGLE, как показано ниже. Теперь зададим делитель = 1024 и дадим команду на работу таймера: TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc | // Определяем значение прескалера TCA_SINGLE_ENABLE_bm; // и включаем таймер Далее необходимо задать режим работы таймера: TCA0.SINGLE.CTRLB = 1<<TCA_SINGLE_ALUPD_bp | // Установим бит автоматической блокировки обнолвения регистров компаратора (0 << TCA_SINGLE_CMP0EN_bp) | (0 << TCA_SINGLE_CMP1EN_bp) | (0 << TCA_SINGLE_CMP2EN_bp) | // пины выводов компараторов не включаем TCA_SINGLE_WGMODE_DSTOP_gc; // Режим работы таймера - двухскатный ШИМ с прерыванием OVF в вершине счета В нашем случае это двухскатный ШИМ с переполнением в максимуме. Бит ALUPD блокирует обновление регистров периода и компараторов тогда, когда это может вызвать уход таймера из под контроля. Т.е. если значение в регистре-буфере периода меньше, чем текущее значение таймера, то регистр периода обновится только тогда, когда значение счетчика станет меньше значения регистра-буфера периода. Также и с регистрами компаратора. Биты CMPхEN разрешают сопоставить свои выходы с физическими выходами МК. Но для физического появления сигнала на выводах, эти выводы необходимо определить на выход. Сопоставление выходов компараторов с физическими ногами задано жестко, но у МК многоножек (таких, как Attiny817) есть также и альтернативные ноги. У attinyxx14 таких альтернативных ног нет. Но свободное назначение не предусмотрено. Мы же записываем в эти биты нули, ибо выходы компараторов у нас будут соединены с модулем CCL внутри МК. Всё. Таймер у нас настроен и уже тикает. Осталось только наполнить регистры значениями, чтобы тикалось так, как нам хочется. Как обычно, чтобы не искать в коде значения констант, я их выношу в самый вверх в виде определений: #define TCA_period 4000 #define TCA_cmp0 3000 #define TCA_cmp1 2500 И где-то в коде заполняем регистры: TCA_Init(); TCA0.SINGLE.PER = TCA_period; TCA0.SINGLE.CMP0 = TCA_cmp0; TCA0.SINGLE.CMP1 = TCA_cmp1; С таймером на этом всё. Переходим к CCL/ CCL. Configurable Custom Logic. Чтобы понять суть этого блока, давайте посмотрим на его блок схему. CCL состояит из двух таблиц истинности (LUT), далле фильтр/синхронизатор, детектор фронта и обе таблицы совими выходами могут быть подключены к Sequental Logic (не знаю, как правильно перевести. Дословно - последовательная логика. Почему? Либо они курят чего, либо я не вытягиваю предмет). Для чего фильтр? Тот, кто работал с логическими схемами в железе (155 серия, ага)), знает, что сигнал от входа к выходу в реальном железе распространяется не мгновенно, а с конечной скоростью. Так вот если даже на входе сигнал изменится одновременно, то внутренняя схема переключается с задержкой и из-за этого возникают иголки на выходе. Иголки по длительности совсем короткие, но весьма способны повлиять на работу дальнейшей схемы. Особенно этому подвержены дешифраторы, сложные логические схемы (про абсолютную помехуНЕустойчивость наших КМОП серий знают, наверное, все). В виду того, что LUT может быть подключен к внешним выводам МК как входами (через систему асинхронных событий), так и выходами, то для исключения таких вот иголок и введен фильтр. Работает просто - изменения сигнала привязываются к тактирующему сигналу. Детектор фронта, как утверждает даташит, детектирует только передний фронт. Если нужна реакция по заднему фронту - переверните логику работы LUT. В даташите так вот и написано. Sequental Logic может быть одним из триггеров: RS, D, и JK. D триггер представлен в двух вариациях - классический с входами Data и Clock и с защелкой (Gate). Если на входе защелки установлен "0", то триггер не при каких обстоятельствах не меняет своего состояния. Но всю эту кухню мы сегодня готовить не будем, а разберем LUT. LUT представляет из себя конфигурируемую логику с тремя входами и одним выходом. Реакция выхода на входное воздействие полностью программируется. В нашем случае мы используем всего два входа. Логика работы такая - если на этих двух входах разные состояния, то на выходе "1". В остальных случаях "0". XOR, одним словом. Реакцию выхода на входное воздействие написали, теперь подключим это входное воздействие. Подключаться будем к выходам компараторов таймера TCA0: CCL.LUT0CTRLB = CCL_INSEL0_TCA0_gc // W0 | CCL_INSEL1_TCA0_gc // WO1; Теперь остальные настройки - разрешим работу LUT и разрешим его выход подключить на физическую ножку: CCL.LUT0CTRLA = 0 << CCL_CLKSRC_bp | 1 << CCL_ENABLE_bp | 1 << CCL_OUTEN_bp; Бит CLKSRC определяет из какого источника будут тактироваться фильтр и детектор фронта. Здесь мы их не используем, поэтому смело ставим в ноль. Ножку выхода LUT также надо настроить на выход, иначе ничего вообще работать не будет (в буквальном смысле): PORTC.DIR |= PIN0_bm; Работу LUT разрешили, теперь надо разрешить работу самого блока CCL: CCL.CTRLA = 1 << CCL_ENABLE_bp | 0 << CCL_RUNSTDBY_bp; Последний бит определяет - будет ли блок работать в режиме StandBy или нет. Это напрямую влияет на энергопотребление, поэтому изначально все модули выключены (в серии atmega наоборот ((____ ). Ну вот и всё. Осталось написать самый главный код в самом главном цикле и запустить программу в свободное выполнение: while (1) { } Прошиваем МК и смотрим на подключенный к выводу PC0 светодиод. Т.к. его вы не видите, то специально для вас я подключил ЛА и выложил картинку в первом сообщении. ENJOY!
×
×
  • Create New...