Attiny817 - индикатор здоровья - health status/

Тема в разделе "Микроконтроллеры AVR", создана пользователем parovoZZ, 16 апр 2019.

  1. parovoZZ

    parovoZZ Гуру

    Многие видели промышленные изделия, на платах которых присутствует индикатор "здоровья". Т.е такой индикатор, который моргает и частота моргания напрямую зависит от состояния устройства - часто моргает или редко - заболел совсем или частично, не моргает - что-то сыграло в ящик. Ну или забыли в сеть включить).
    Давайте тоже создадим такой индикатор. Но пойдём ещё дальше - моргать наш индикатор будет не однократными, а двухкратными вспышками. На диаграмме логического анализатора это будет выглядеть примерно так:
    timer_health.png
     
  2. b707

    b707 Гуру

    у меня есть такой индикатор в каком-то проекте - выводит не только двойные вспышки - а вообще любые комбинации, например тройные. "2+3", "спартак-чемпион" и тому подобное
    Алгоритм элементарнейший - таймер, прерывание и битовая маска. задающая последовательность вспышек
     
  3. parovoZZ

    parovoZZ Гуру

    Для отмеривания периодов будет использовать таймер типа TCA. TCA - это тип таймера, а не собственно сам таймер, поэтому запись
    Код (C++):
    TCA.xxx.yy
    будет ошибочна. Порядковый номер таймера обозначается цифрой. В нашем случае это таймер TCA0. TCA таймер - это до боли знакомый по atmega таймер - 16 битный счетчик, 3 компаратора, логика счета вверх и вниз. Но есть и новшества - буферные регистры для компараторов и регистра периода.
    Режимов работы у таймера несколько - нормальный режим, режим односкатный ШИМ (счетчик считает вверх до максимума и обнуляется), двускатный ШИМ (счетчик досчитав до максимума начинает отсчет вниз). Для реализации нашей задумки мы как раз-таки и будем использовать последний режим. В этом режиме компараторы работают так, как показано на следующем графике:
    TCA.png
    Идея понятна из графика - при счете вверх и совпадении значений регистров CNT и CMPx выход компаратора очищается, при счете вниз - устанавливается. Мы видим, что если выходы компараторов сложить логически по XOR, то на выходе мы получим именно то, что нужно. Складывать (ксорить) мы будем в блоке CCL - Custom Control Logic/
     
  4. parovoZZ

    parovoZZ Гуру

    Давайте настраивать наш таймер. Но для начала необходимо настроить главный делитель частоты. С помощью фьюза я выставил привычную для меня частоту в 16 МГц.
    timer_health1.png Сразу после ресета, по умолчанию, делитель настраивается на коэффициент 6. Мы это исправим и выставим коэффициент деления 2 не забывая про регистр защиты CCP:
    Код (C++):
    CCP = CCP_IOREG_gc;
    CLKCTRL.MCLKCTRLB = CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm;        // Прескалер главной тактовой частоты
    первый бит - это разрешение работы делителя. Если он равен нулю, то деление частоты не производится и равно 1.
    Переходим к настройке таймера TCA0. У таймера есть два фундаментальных режима работы - нормальный (single) и сдвоенный (split). В сдвоенном режиме 16-ти битный счетчик распадается на два 8-ми битных и каждый тикает независимо. также в этом режиме количество компараторов умножается на два. Но этот режим я сейчас разбирать не буду. Остановимся на нормальном режиме.
    Нормальный режим работы указывается определением SINGLE, как показано ниже. Теперь зададим делитель = 1024 и дадим команду на работу таймера:
    Код (C++):
        TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc |    // Определяем значение прескалера
                TCA_SINGLE_ENABLE_bm;        // и включаем таймер
    Далее необходимо задать режим работы таймера:
    Код (C++):
        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 внутри МК.
    Всё. Таймер у нас настроен и уже тикает. Осталось только наполнить регистры значениями, чтобы тикалось так, как нам хочется. Как обычно, чтобы не искать в коде значения констант, я их выношу в самый вверх в виде определений:
    Код (C++):
    #define    TCA_period        4000
    #define    TCA_cmp0            3000
    #define    TCA_cmp1            2500
    И где-то в коде заполняем регистры:
    Код (C++):
            TCA_Init();
            TCA0.SINGLE.PER = TCA_period;
            TCA0.SINGLE.CMP0 = TCA_cmp0;
            TCA0.SINGLE.CMP1 = TCA_cmp1;
    С таймером на этом всё. Переходим к CCL/
    Enjoy!
     
  5. parovoZZ

    parovoZZ Гуру

    это сложно и это вышло из моды.
     
  6. AlexU

    AlexU Гуру

    Ну в таких терминах правильней назвать -- подъёмно-скатный ШИМ. Всё-таки сначала поднимается, а потом скатывается, а не два раза скатывается.

    Но инженеры почему-то называют этот режим -- ШИМ с корректировкой фазы. Дураки наверно, не понимают ни чего.

    И есть вопрос. Уже не первая тема про ATtiny817.
    Есть ли у этого контроллера перспективы? Сможет ли он стать таким же народным, как, например, ATmega328P или ATmega32U4?

    А то вот тратишь своё время, изучаешь его доки, а будет ли этот багаж знаний в будущем полезен?
     
    Последнее редактирование модератором: 21 апр 2019
  7. Airbus

    Airbus Радиохулиган Модератор

    Пускай аффтар пишет.У него этих Тиней817 как у меня Кт315.Целая трехлитровая банка.Батя стырил еще при СССР.А он видать тоже где то стырил коробку.Походу в Пулково когда там шло строительство.А так МК самый обычный.Станет ли массовым ,народным?Вряд ли.Вот esp8266 стал и массовым и народным за короткое время.А esp32 пока нет.И этот вряд ли.Да возможностей чуть больше но нужны ли они в том виде?Да и ценник не особо.
     
    Последнее редактирование: 17 апр 2019
  8. parovoZZ

    parovoZZ Гуру

    В оригинале это звучит как dual-slope PWM. Хотя по старым документам Phase Correct PWM.
    С другой стороны, если фронты сигнала не меняются, то говорить про модуляцию не совсем корректно.

    По-взрослому её хоббисты не программируют. Единицы только.
     
  9. ИгорьК

    ИгорьК Гуру

    Вот я ее вообще не программирую, даже по-детски. Я из нее просто тучу поделок делаю :)
     
    Airbus нравится это.
  10. AlexU

    AlexU Гуру

    Вот как чё-нить ляпнешь, так ляпнешь.
    Вот при чём тут фронты сигнала и модуляция? Когда речь идёт об изменении фазы PWM при изменении скважности. Поэтому и называют этот режим "с корректировкой фазы".

    Вот тут не совсем очевидно, а действительно ли возможностей больше...

    И ещё вопрос к автору: отладку внутри кристалла пробовал? Её хоть довели до ума или такая же ущербная как и до этого была (после установки точки прерывания необходимо было перезаливать прошивку, что бы эта точка сработала)?
     
    Последнее редактирование модератором: 21 апр 2019
    Airbus нравится это.
  11. parovoZZ

    parovoZZ Гуру

    CCL. Configurable Custom Logic. Чтобы понять суть этого блока, давайте посмотрим на его блок схему.
    Screenshot_2019-04-17 ATtiny417.png
    CCL состояит из двух таблиц истинности (LUT), далле фильтр/синхронизатор, детектор фронта и обе таблицы совими выходами могут быть подключены к Sequental Logic (не знаю, как правильно перевести. Дословно - последовательная логика. Почему? Либо они курят чего, либо я не вытягиваю предмет). Для чего фильтр? Тот, кто работал с логическими схемами в железе (155 серия, ага)), знает, что сигнал от входа к выходу в реальном железе распространяется не мгновенно, а с конечной скоростью. Так вот если даже на входе сигнал изменится одновременно, то внутренняя схема переключается с задержкой и из-за этого возникают иголки на выходе. Иголки по длительности совсем короткие, но весьма способны повлиять на работу дальнейшей схемы. Особенно этому подвержены дешифраторы, сложные логические схемы (про абсолютную помехуНЕустойчивость наших КМОП серий знают, наверное, все). В виду того, что LUT может быть подключен к внешним выводам МК как входами (через систему асинхронных событий), так и выходами, то для исключения таких вот иголок и введен фильтр. Работает просто - изменения сигнала привязываются к тактирующему сигналу. Детектор фронта, как утверждает даташит, детектирует только передний фронт. Если нужна реакция по заднему фронту - переверните логику работы LUT. В даташите так вот и написано. Sequental Logic может быть одним из триггеров: RS, D, и JK. D триггер представлен в двух вариациях - классический с входами Data и Clock и с защелкой (Gate). Если на входе защелки установлен "0", то триггер не при каких обстоятельствах не меняет своего состояния. Но всю эту кухню мы сегодня готовить не будем, а разберем LUT.
    LUT представляет из себя конфигурируемую логику с тремя входами и одним выходом. Реакция выхода на входное воздействие полностью программируется. В нашем случае мы используем всего два входа. Логика работы такая - если на этих двух входах разные состояния, то на выходе "1". В остальных случаях "0". XOR, одним словом.
    timer_health_LUT.png
    Если записать одной строкой с сохранением порядка следования битов, то получим 6 в десятичной системе.
    Так и запишем:
    Код (C++):
    CCL.TRUTH0 = 0x06;
    Реакцию выхода на входное воздействие написали, теперь подключим это входное воздействие. Подключаться будем к выходам компараторов таймера TCA0:
    Код (C++):
            CCL.LUT0CTRLB =    CCL_INSEL0_TCA0_gc  // W0
                    | CCL_INSEL1_TCA0_gc            // WO1;
    Теперь остальные настройки - разрешим работу LUT и разрешим его выход подключить на физическую ножку:
    Код (C++):
            CCL.LUT0CTRLA =    0 << CCL_CLKSRC_bp
                    | 1 << CCL_ENABLE_bp  
                    | 1 << CCL_OUTEN_bp;  
    Бит CLKSRC определяет из какого источника будут тактироваться фильтр и детектор фронта. Здесь мы их не используем, поэтому смело ставим в ноль.
    Ножку выхода LUT также надо настроить на выход, иначе ничего вообще работать не будет (в буквальном смысле):
    Код (C++):
    PORTC.DIR |= PIN0_bm;
    Работу LUT разрешили, теперь надо разрешить работу самого блока CCL:
    Код (C++):
            CCL.CTRLA =    1 << CCL_ENABLE_bp  
                    | 0 << CCL_RUNSTDBY_bp;
    Последний бит определяет - будет ли блок работать в режиме StandBy или нет. Это напрямую влияет на энергопотребление, поэтому изначально все модули выключены (в серии atmega наоборот ((____ ).
    Ну вот и всё. Осталось написать самый главный код в самом главном цикле и запустить программу в свободное выполнение:
    Код (C++):
        while (1)
        {
              //Please insert govnocode here
            }
    Мммдя.
    Прошиваем МК и смотрим на подключенный к выводу PC0 светодиод. Т.к. его вы не видите, то специально для вас я подключил ЛА и выложил картинку в первом сообщении.
    ENJOY!

    Впереди у нас весьма обновленный SPI, навороченный АЦП, система событий....
     
    Последнее редактирование: 18 апр 2019
  12. parovoZZ

    parovoZZ Гуру

    Да. Работает. Реакция не мгновенная. Во взрослых atmega нормальная отладка, это ж в атиньках изврат был. DebugWire или как там.
    Здесь есть в регистрах секция Debug - разрешаем модулю продолжать тактироваться ,когда мы останавливаем работу МК, или нет.

    Почему нет? На хобби сообщество никто не ориентируется. А микрочип уже готовит atmega нулевой серии. Бытует также мнение, что микрочип не будет аврки делать круче своих пиков. Но у пиков та же проблема, что и у всех остальных - куча МК внутри серии. Для промышленности такой вариант идеален, но вот для хоббистов это целая головная боль. Подобрал себе МК, а продается он только от катушки. Приходится брать модель уровнем выше. Впрочем, у атмела последний случай, но хотя бы нет такого зоопарка МК. Не знаю как у ПИКов и прочих, а в TI поступили грамотно - к МК идет даташит только с изменениями относительно серии. Полистал с десяток страниц и определился - покроет задачу или не покроет.

    Самая печаль и боль - это программаторы. Пусть МК и совсем тухлый, но если его можно запрограммировать обычным ржавым гвоздем - он пойдет в хобби сообщество.

    Не меняем мы в сигнале НИЧЕГО. Какая при этом модуляция? Вот меандр - модулирован или нет? А если скважность иная, чем в меандре - это модуляция или нет? Плохая погода на Марсе и осциллятор генерирует одни иголки - это модуляция или нет? Бесспорно, если мы корректируем фазу, крутим скважность - это ШИМ или ЧИМ по принадлежности. Но когда всего этого нет, то как назвать?
     
  13. AlexU

    AlexU Гуру

    Ну не во всех. И дело не только в DebugWire. А в том, что аппаратные точки останова не поддерживаются. Вот захотел ты поставить точку останова, что сделает отладчик? -- Он в нужное место в прошивке вставит специальную инструкцию и, чтобы эта точка останова сработала, эту прошивку со специальной инструкцией зашьёт в МК. Захотел новую точку останова, отладчик заново соберёт прошивку с новой точкой и опять зашьет её в МК. Ты сидя в Atmel Studio всего этого не увидишь, тебе будет казаться, что точки останова работают как надо. Но ресурс по количеству перезаписи flash памяти при этом расходуется с немалой скоростью -- ещё бы для каждой новой точки останова нужно перепрошивать контроллер.
    Вот и встал вопрос, а как в новых тиньках это реализовано? Есть аппаратные точки останова или нет?
     
  14. parovoZZ

    parovoZZ Гуру

    ну, инструмента для отладки atmega у меня нет - нахаляву взять негде, а покупать дорого.

    По UPDI прошивка заливается долго, поэтому я бы увидел это. Если скажешь алгоритм, как точно это проверить - сделаю. Секцию в даташите про это дело что-то лень изучать))0
     
  15. AlexU

    AlexU Гуру

    Столько вопросов и для чего все эти вопросы? Вот зачем ты сюда приплетаешь модуляцию? Или услышал фразу -- "изменение фазы" -- так сразу это модуляция?
    Забудь про модуляцию. Особенность, используемого тобой режима PWM, состоит в том, что фаза сигнала зависит от скважности. Всё. Нет тут ни какой модуляции.
    В режиме "односкатного" PWM фаза всегда равна нулю, в режиме "двускатного" -- фаза зависит от скважности (диапазон -- 0 < фаза < 180 градусов).

    Вот поэтому грамотные инженеры Atmel и назвали этот режим Phase Correct PWM, а "бумагоморатели" из Microchip -- Daul Slope PWM.

    В документации должно быть написано.
    Ну тогда забудь про этот вопрос.
     
    Последнее редактирование модератором: 21 апр 2019
    Airbus нравится это.
  16. Airbus

    Airbus Радиохулиган Модератор

    Согласен.Гора родила мышь.После поглощения Атмел Микрочипом ничего путного так и не вышло.
     
  17. parovoZZ

    parovoZZ Гуру

    что фаза меняется одновременно по всем выходам))
    Лан, проехали.
    будет время - посмотрю.

    Только 2 штуки.
     
    Последнее редактирование модератором: 21 апр 2019