Pull to refresh

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

DIY


Привет хабр. Я уже давно вынашивал сделать 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
Все мои публикации.
Tags:
Hubs:
Total votes 28: ↑22 and ↓6 +16
Views 27K
Comments Comments 14