Сервотестер на ATtiny13 AVR |
Обзоры - Самодельная электроника в моделизме |
Автор: regio |
Создаем сервотестер на микроконтроллере ATtiny13 - (далее МК).
Для этого нам понадобится: 1. Микроконтроллер ATtiny13
2. Программатор SPI (например такой 3. Пластинка текстолитовая для печатных плат и хлорное железо для ее травления. 4. Штырьковые разьемчики (2х-1шт, 3х-2шт, 5х-1шт). 5. Электрокомпоненты: - 2 светодиода - 2 резистора 200Ом - 1 резистор 10КОм - 1 конденсатор керамический 0,1mF - 1 диод 1N4007 (нужен для защиты от переплюсовки) - 1 кнопка 6. Паяльник 30W (если мощней можно перегреть МК при пайке)
Вступление: У ATtiny13 есть порт B и 6 выводов (фактически 5 т.к. последний вывод повешен на лапку RESET и если мы его используем - то больше не сможем программировать МК). Вспомним теорию - МК ATtiny13 имеет на борту один 8битный таймер (это 2 в степени 8 равно 256), то-есть он умеет считать от нуля до 256. И есть возможность на его основе хардварно генерировать две ШИМ (Широко Импульсная Модуляция) на ножках PB0 и PB1 - то-есть частотный сигнал которым мы и будем управлять нашими сервомашинками. Осталось три свободных вывода, их и используем для кнопки и двух светодиодов. Теперь про сервомашинки. Сервомашинки управляются частотным сигналом. Стандартые параметры для машинок 900мкс-крайнее левое положение, 1500 (бывает 1520)мкс - среднее положение, 2100мкс - крайнее правое. Наша задача и сгенерировать этот сигнал с необходимой нам частотой. Изготовление платы: Плата делается по технологии "ЛУТ" - Лазерно-Утюжная-Технология :) Опишу вкратце (в сети информации предостаточно). Берем фотобумагу для струйных принтеров и печатаем на лазерном принтере разведенную схему. На текстолитовую пластинку с медным слоем кладем наш отпечаток и раскаленным утюгом держим 1 минуту. Даем остыть и под кран - смываем бумагу. Тонер очень крепко прилипает к меди. Затем жесткой стирательной резинкой удаляем остатки бумаги и пленки. Кладем в раствор воды и хлорного железа - через минут 40 все что без тонера вытравливается. Моем под краном. Растворителем смываем тонер. Все. Еще можно на меди просто лаковым фломастером дорожки нарисовать и в раствор. А можно и вообще без платы на рассыпухе сделать - только некрасиво получится. Ну и сверлим дырочки (я сверлю для контактов 0,9мм для компонентов 0,7мм) Принципиальная схема:
Пояснения к схеме: Диод D1 нужен для защиты от переплюсовки (можно и не ставить). Резисторы R2 и R3 нужны для светодиодов (ну а как иначе, можно ставить до 5КОм просто тускней гореть будут). Резистор R1 и конденсатор C1 нужны для защиты сброса МК (можно тоже не ставить, но так надежней) Кнопка в разомкнутом состоянии - 1, в замкнутом - 0.
Плата с расположением элементов:
Теперь о коде: Код написан на СИ WINAVR. Написан максимально просто с подробными комментариями. Алгоритм такой: Вначале нам нужно настроить в микроконтроллере ШИМ (смотрим комментарии в коде делитель на 256). Что-бы повернуть серву например в среднее положение (1500мкс=1,5мс) нам нужно в регистр OCR0A записать 6.54. А что же это за число? Вспомним теорию мы используем частоту 50Гц - это 50 колебаний в секунду. Значит одно колебание будет длинной 1000/50=20мс. Для нашей шим мы используем системный делитель частоты процессора. Хорошо подошел делитель 256. Итак 9600000Hz/256=37500Hz это частота на которой будет работать наш ШИМ, то-есть 37500 колебаний в секунду. Соответственно длинна одного колебания(импульса) будет 1000/37500=0,02667мс, что равняется 26,67мкс. Но мы помним что у нас таймер считает до 256. Нужно 256 отнять 26,67=229,33мкс Это и есть длинна одного имульса. Теперь нам просто нужно узнать сколько этих импульсов нам нужно подать чтобы повернуть серву на 1500мкс. Делим 1500 на 229,33 и получаем 6,54 - это число и записываем в OCR0A=6.54; Теперь что-бы повернуть серву на угол в диаппазоне 900-2100мкс нужно это число поделить на 229,33 и записать в OCR0A или OCR0В.
Скачать: Прошивка:
Прошить МК можно например программой
Код программы на СИ: /************************************************ Сервотестер на ATtiny13 - с завода на 9,6 MHz Два ШИМ на 8-битном таймере Два светодиода Нажатие кнопки *************************************************/ #define F_CPU 9600000UL // Частота МК 9,6 MHz нужно для библиотеки задержек #include // Библиотека ввода-вывода "io.h" #include // Библиотека задержек "delay.h" int knopka; //переменная для управления кнопкой int regim = 2; //переменная для смены режимов //функция включения светодиода №1 void LED1_On (void) { PORTB |= _BV(PB3); // установить "1" на линии PB3 порта B (включаем светодиод №1) } //функция выключения светодиода №1 void LED1_Off (void) { PORTB &= ~_BV(PB3); // установить "0" на линии PB3 порта B (выключаем светодиод №1) } //функция включения светодиода №2 void LED2_On (void) { PORTB |= _BV(PB4); // установить "1" на линии PB4 порта B (включаем светодиод №2) } //функция выключения светодиода №2 void LED2_Off (void) { PORTB &= ~_BV(PB4); // установить "0" на линии PB4 порта B (выключаем светодиод №2) } int main(void) // начало основой программы { //Настраиваем ШИМ на микроконтроллере. Страницы 69-73 в даташите на ATtiny13 //COM0A1-Fast PWM Mode - Сброс ОС0А в момент совпадения, установка ОС0А при достижении счетчиком значения ТОР //COM0B1-Fast PWM Mode - Сброс ОС0B в момент совпадения, установка ОС0B при достижении счетчиком значения ТОР //WGM01 - Включаем Fast PWM Mode 3 //WGM00 - Включаем Fast PWM Mode 3 //CS02 - Устанавливаем делитель 256 TCCR0A|=(1 << COM0A1)|(1 << COM0B1)|(1 << WGM01)|(1 << WGM00); //Можно вместо этого еще так TCCR0A=A3; TCCR0B|=(1 << CS02); //Можно вместо этого еще так TCCR0B=04; OCR0A=6.54; //Стартовая-центральная позиция для серв (1500мкс) OCR0B=6.54; //Стартовая-центральная позиция для серв (1500мкс) DDRB = 0x1B; /* выводы PB4,PB3,PB1,PB0 порта B сконфигурировать как выходы, остальные как входы PB5,PB4,PB3,PB2,PB1,PB0-011011*/ PORTB |= _BV(PB2); /*установит "1" (сигнал высокого уровня) на выводе PB2 - включаем подтягивающие резисторы на PB2 для кнопки. Можно еще так PORTB |= 1<<2; отпущена PINB=1 нажата PINB=0*/ while (1) { // Бесконечный цикл //Обработка кнопки menu if ((PINB & (1 << PB2)) == 0) //Фиксирует нажатие { _delay_ms(30); //Устранение "дребезга клавиш" if ((PINB & (1 << PB2)) == 0) //Проверяет нажатие { knopka = 1; // Показываем что нажали кнопку } } if (knopka == 1 && regim == 2) //Если кнопка была нажата и режим-2, то включить режим-1 { LED1_On(); // Зажигаем светодиод LED2_Off(); //Тушим светодиод regim = 1; //Показываем что включили режим 1 knopka = 0; //Обнуляем значение нажатия кнопки OCR0A=4.8; //Поворачиваем сервы в крайнее левое - 1100мкс OCR0B=4.8; _delay_ms(100); // ждем OCR0A=6.54; // Поворачиваем сервы в центр - 1500мкс OCR0B=6.54; _delay_ms(100); // ждем OCR0A=8.28; //Поворачиваем сервы в крайнее правое - 1900мкс OCR0B=8.28; _delay_ms(100); // ждем OCR0A=6.54; //Оставляем сервы в центральной позиции -1500мкс OCR0B=6.54; } else if (knopka == 1 && regim == 1) //Если кнопка была нажата и режим-1, то включить режим-2 { LED1_Off(); //Тушим светодиод LED2_On(); // Зажигаем светодиод regim = 2; // Показываем что включили режим 2 knopka = 0; //Обнуляем значение нажатия кнопки // Тоже самое только сервы поворачиваются на больший угол 900-1500-2100мкс OCR0A=2.62; OCR0B=2.62; _delay_ms(100); // ждем OCR0A=6.54; OCR0B=6.54; _delay_ms(100); // ждем OCR0A=10.47; OCR0B=10.47; _delay_ms(100); // ждем OCR0A=6.54; OCR0B=6.54; } } // закрывающая скобка бесконечного цикла } // закрывающая скобка основной программы
|