Трёхканальный UART АЦП на ATtiny13



    Привет хабр. Я уже давно вынашивал сделать UART Аналогового-Цифрового Преобразователя на ATtiny13, зачем делать именно на ATtiny13 ведь есть, к примеру, ATmega8 имеет аж 6 (для DIP корпуса) портов на которых, при помощи мультиплексора, можно проводить измерение АЦП?
    Причин несколько:

    — ATtiny13 стоит дешевле;
    — В ATtiny13 более оптимально используются ресурсы микроконтроллера;
    — Размеры;
    — Энергопотребление;
    — Просто мне так захотелось.

    Конечно на мои аргументы можно найти множество контраргументов, например ATmega8 при использовании V-USB может превратится в плату ввода/вывода которой не нужен переходник с UART на USB, правда кроме последнего, и с этим пожалуй не поспоришь.

    Поставил себе за цель получить опыт работы с программный UART'ом именно на ATtiny13, а опыт как говорится, бесценный. По-любому пригодится для будущих проектов.
    Ну ладно, не буду тянуть и покажу, как работает в железе:



    Пару слов по схеме, кстати, вот она:

    Схема в Proteus


    Скажу сразу, что не плохо бы уделить внимание фильтру питания, у меня это два конденсатора C1 — желательно «керамика» и как можно ближе к ножкам МК, ну и C2 — электролитический, второй можно поставить на 100 мкФ но у меня такого не оказалось под рукой, нашёл на 470 мкФ 10 В. Так же было бы не плохо по конденсатору на каждый порт АЦП, и как можно ближе к МК. R1 не принципиален, но по правилах «хорошего тона» — должен присутствовать.

    Данные, как Вы могли видеть, приходят в формате 1023,666,10, ну хоть бери и сохраняй в формате CSV на компе или же другом устройстве, которое будет принимать эти данные.
    Кстати принимает данные в моём случае недорогой преобразователь USB — UART основан на микросхеме PL2303HX. Пробовал питать ATtiny13 от бортовых 3.3 В что на преобразователе, по мультиметру к стати 3.4 В, работает, я поначалу думал что изменение питания на такое высокое значение как-то скажется на отправке данных, я где-то читал страшилку мол, нагрей на пару градусов, охлади и всё, прощай адекватные данные… Ничего подобного, охлаждал льдом, слегка грел зажигалкой(без фанатизма) — всё работает нормально, потерь не наблюдал.

    Пару слов про код — код написан в среде BASCOM-AVR на Basic'е, вот предлагаю Вашему вниманию мой код на написание я потратил около чем 4-5 часов, так как я раньше не встречался с Basic'ом, но это время было потрачено не только на написание кода но и на то, чтобы разобраться с особенностями BASCOM-AVR, отладка и всякое такое.

    Код
    Samples Alias 64                                            ' Аналог директивы #define на Си
                                                                            ' Количество выборок АЦП 
    $regfile = "attiny13.dat"                                   ' Конфигурации по умолчанию
    $crystal = 1200000
    $hwstack = 16
    $swstack = 16
    $framesize = 16
    '$noramclear
    
    Open "comb.0:9600,8,n,1" For Output As #1                   ' Настройка программного UART, скорость 9600 бод
                                                                  ' Ножка PB0 будет как TXD, подключаем к RXD преобразователя
    
    Config Adc = Single , Prescaler = Auto , Reference = Avcc   'Конфигурирование  АЦП, измерение относительно Vcc
    Start Adc                                                   ' Запускаем преобразование
    
    ' Здесь Adc - режим считывания значения: Single - единичное считывание,
    ' также может быть Free (режим постоянной работы преобразователя)
    ' Prescaler = 128 - выбираем частоту дискретизации путем деления
    ' частоты кварца на определенное число (также может быть 2,4,8,16,32,64 или Auto).
    ' Если выбрать Auto, то компилятор сам выберет подходящую частоту работы АЦП
    ' Reference – выбор источника опорного напряжения. Aref – внешний источник,
    ' Avcc – напряжение питания схемы, Internal – внутренний ИОН на 1,1 в.
    
    Declare Function Adc_get(byval Adc_port As Byte) As Word    ' Объявим переменную которая принимает номер нужного порта АЦП
                                                                  ' И возвращает усреднённое от "Samples" количество выборок АЦП
    
    Do                                                          ' Тут начинается вечный цикл
    
       Print #1 , Adc_get(1) ; "," ; Adc_get(2) ; "," ; Adc_get(3)       ' Выводим данные в формате *,*,*
    
    Loop                                                        ' Тут кончается
    
    Function Adc_get(byval Adc_port As Byte ) As Word           ' Переменная типа Word может принимать знач. до 65535
    
       Dim Temp_result As Word                                  ' Создадим переменную для буфера
       Dim Adc_cycles As Byte                                   ' И счётчик выборок АЦП
    
       Temp_result = 0
    
       For Adc_cycles = 1 To Samples
    
          Temp_result = Temp_result + Getadc(adc_port)
    
       Next
    
       Temp_result = Temp_result / Samples
    
       Adc_get = Temp_result                                    ' Эта функция возвращает Temp_result
    
    End Function
    
    

    Что делает данные код — по началу создаётся программный UART, тут это делается очень просто, задаём нужные параметры, порт, скорость и прочее, потом осуществляется конфигурация АЦП, объявление функции, ну это понятно, потом формируется строчка и результатами усреднённого числа от Samples выборок АЦП. Почему я выбрал именно 64 а не к примеру 42 или 108? Ну потому что 1023 * 64 это равно 65 472, а для типа Word, который я использовал для буфера максимальное значение которое переменная может принять — 65 535, это число является наибольшим числом, представимом в виде двухбайтного слова без знака, если добавить ещё одну выборку переменная попросту обнулится если АЦП возвратит 1023. С типом Long почему-то возникали проблемы, да лично мне и 64 выборки хватает, ниже я покажу как это работает на графике. Ну и потом в UART выводятся результаты.



    Как Вы можете видеть шум конечно присутствует, даже не смотря на то что выводится усреднённое значение из 64 выборок, судя по даташиту шум в ± 2 LSB — норма, у меня же шум 1 LSB.

    Скрин софта


    Как Вы можете видеть, ATtiny13 отправляет значения 15-16 раз за секунду, что я считаю не плохо учитывая что это программный UART да и тиня делает по 64 измерения на порт, а их причём три.

    МК потребляет следующий ток:

    Питание 5 В — 2.71 мА
    Питание 3.3 В 1.75 мА

    Пару слов о программированию — как я сказал на видео, частота МК 1.2 МГц, все фьюзы по умолчанию, как в моём предыдущем топике Музыкальный дверной звонок в стиле Star Wars.
    Вот фьюзы из калькулятора фьюзов:

    Фьюзы
    image


    Ну и под конец пару фоток из разных ракурсов:

    Небольшая фотосессия





    Ссылки:

    Альтернатива Wiring для Arduino — BASCOM-AVR
    Софт которым делал графики — Serial oscilloscope
    Архив с исходником, хекс-файлом и схемой в Proteus 7 Professional
    Все мои публикации.
    Share post

    Comments 14

      0
      Аргументы в пользу выбора контролера в статье присутствуют.
      А почему basic то?
        +2
        Простота и скорость написания, нет?
          +1
          Так я вот и спросил, чтобы понять зачем люди при программировании микроконтроллеров связываются с бейсиком.
          где же тут простота и скорость написания если на два цикла было потрачено 5 часов.
          Я уверен, что автор эти десять строк за такое же время и на С осилил бы.
            +1
            5 часов было потрачено не только на написание кода но и на то чтобы разобраться с особенностями BASCOM-AVR, отладка и всякое такое.
            Маленько стало для меня проблемой отсутствие адекватной документации на русским языке.

            А вот насчёт простоты согласен, а ещё если Вы раньше работали с бейсиком то вообще класс.
        +2
        Хм. Какая-то новая интересная программа… никогда не видел такого визуализатора.
        Всё что я пробовал до этого — безбожно глючило на ровном месте.

        16 выборок/сек это не из-за программного UART-а а из-за усреднения.
        А вообще, усреднение по методу среднего это фигня полная — на выходе шум не давится до конца, необходимо очень много выборок чтобы задавить его в конец.
        Более выгодным является усреднение по методу окна, когда берутся именно N последних выборок и усредняются. Не просто N выборок, а именно N последних из потока данных. При этом приходится каждое выполненное измерение пересчитывать среднее значение, но при N=8 уже получается отличный результат.
        А чтобы не задерживать процесс, можно запустить преобразование для следующего канала и только потом высчитывать среднее значение для текущего.

        Да, и вам крупно повезло! встроенный RC-генератор не обладает точностью установки частоты а для UART необходима разность скорости передачи менее 2% для успешной работы. Иначе надо калибровать встроенный RC-генератор, а процедура эта не очень тривиальная. Частота эта сильно плывёт от температуры и т.д. Я бы вывел на свободный вывод(если остался?) частоту с заранее рассчитанным значением(меандр на таймере с максимальным коэффициентом деления) и сверил бы её по частотомеру/осциллогарфу с номиналом.

        от конвертора на PL2303 остались только негативный опыт — задержки слишком большие(для диалогового режима работы это критично) и драйвер может вызывать синий экран смерти… который гарантированно ловится при непрерывной работе в течении нескольких суток.
          –1
          Да, еще что хотел сказать… не рисуйте схемы в протеусе, выглядят они там просто ужасно и очень некрасиво. Сложно по таким схемам что-либо понять. Старайтесь оформить схему так, чтобы с первого разу было понятно где там что(как правило входы — слева, выходы — справа) и как работает. Протеус годится только для симуляций, схемный рисовальщик из него никакой. Если не знаете чем лучше рисовать — подскажу: это программа Splan. Там всегда можно нарисовать своё расположение выводов с имеющегося образца.
            0
            Спасибо, попробую.
              +1
              Хотя в данном случае схема в протеусе предпочтительнее, сразу видно что я добавляю файлы протеуса и можно поиграться с схемой даже не собирая на макетке.
              Лично я, если вижу что к какой-то схемке есть файлики протеуса, сразу стараюсь помучить платку виртуально.
                0
                Она должна быть в дополнение к нормальной схеме, объясняющей работу устройства. Протеус, к примеру, скрывает некоторые выводы — для тех кто не знаком ни с контроллерами ни с такой особенностью протеуса это будет выглядеть как магия — схема работает с незапитанным контроллером, и может показаться что так и нужно.
                Кстати это еще не гарантия что у других проект протеуса откроется — проблема совместимости версий…
              0
              Какая реальная точность получилась? Потому как, скажем, 12-битный АЦП STM32F103 выдает в реале ~10 бит. Для приличной точности измерения пришлось брать внешний 24-битный, который честные 15-16 бит выдает (думаю, при дополнительных защитных мерах можно и больше выжать).
                +2
                Точность, или разрешающая способность? Точность определяется не только шумом, но еще и линейностью шкалы и сдвигом. Сомневаюсь что на ATTINY13 можно собрать измерительный прибор классом точности лучше чем 1%, показометр на 0.1% — пожалуйста.
                И конечно же всегда нужно думать о правильной разводке сигнальных и силовых линий, порой 5мм неудачно разведенного проводка могут угробить всю точность АЦП, особенно 24-битного.
                С достаточно сильной фильтрацией шума(когда есть возможность усреднять измерения) уровень влияния шума на точность измерения можно свести вплоть до 0.5 минимального разряда. Дальше идет линеаризация шкалы, смещение уровня и разводка.
                  0
                  Именно точность. Т.е. воспроизводимость.
                  А шумы — да, даже рукой проведешь рядом с 24-битным АЦП, как шумы ползут.
                    +1
                    Все-таки это несколько разные понятия.
                  0
                  Как видно на видео шумы незначительны, то есть точность предположу что должно быть 9 бит как минимум.

                Only users with full accounts can post comments. Log in, please.