Оглавление:

Параллельное программирование Attiny85 или тыква с разноцветными глазами: 7 шагов
Параллельное программирование Attiny85 или тыква с разноцветными глазами: 7 шагов

Видео: Параллельное программирование Attiny85 или тыква с разноцветными глазами: 7 шагов

Видео: Параллельное программирование Attiny85 или тыква с разноцветными глазами: 7 шагов
Видео: Как я убил Atmega 128A. Параллельное программирование, какую схему выбрать? 2024, Июль
Anonim

Подписаться Еще от автора:

Крик
Крик
Крик
Крик
Замена никель-кадмиевой батареи на внешний источник питания
Замена никель-кадмиевой батареи на внешний источник питания
Замена никель-кадмиевой батареи на внешний источник питания
Замена никель-кадмиевой батареи на внешний источник питания
Ручка цифровой камеры
Ручка цифровой камеры
Ручка цифровой камеры
Ручка цифровой камеры

О себе: Я работаю инженером-программистом в одной из компаний Bay Area (Калифорния). Всякий раз, когда у меня есть время, я люблю программировать микроконтроллеры, строить механические игрушки и делать какие-то проекты по благоустройству дома. Подробнее о jumbleview »

В этом проекте показано, как управлять двумя 10-миллиметровыми трехцветными светодиодами с общим анодом (разноцветные глаза тыквенного блеска Хэллоуина) с помощью чипа Attiny85. Цель проекта - познакомить читателя с искусством параллельного программирования и с использованием библиотеки протопотоков Адама Данкелса. Этот проект предполагает, что читатель знает о 8-битных контроллерах AVR, может написать некоторую программу на языке C и имеет некоторый опыт работы со студией Atmel.

Код проекта опубликован на GitHub:

Запасы

Перед программированием еще нужно построить схему. Вот компоненты:

  • Контроллер Attiny85 (любой поставщик электроники).
  • Два трехцветных светодиода диаметром 10 мм с общим анодом. Светодиоды Adafruit
  • Резисторы 100 Ом, 120 Ом, 150 Ом 0,125 или 0,250 Вт (любой поставщик электроники).
  • Шестиконтактный заголовок для интерфейса AVR ISP. Можно сделать из этого заголовка Adafruit
  • Какой-нибудь макет или печатный шаблон. Я использовал этот
  • Интерфейс AVR ISP MKII и Atmel Studio 6.1 (более поздняя версия также должна работать).

Шаг 1: Обрезка

Circut
Circut

В конструкции используются пять выводов микросхемы:

  • Два контакта используются для управления анодами: каждый анод светодиода прикреплен к соответствующему контакту.
  • Три контакта, прикрепленные (через резисторы) к катодам светодиодов (катод одного цвета для каждого светодиода, прикрепленный к одному и тому же контакту)

Можно спросить: почему бы не использовать все шесть входных / выходных контактов микросхемы, чтобы аноды светодиодов были подключены напрямую к +5 В, а каждый катод имел свой выделенный контакт? Это упростит программирование. Увы, вот в чем проблема: вывод PB5 (RESET) - это слабый вывод, способный выдавать всего ~ 2 мА тока, при этом необходимо иметь ~ 20 мА.

Конечно, для этого слабого вывода можно построить транзисторный усилитель, но я сам по возможности предпочитаю решать проблему с помощью кода.

Шаг 2: Временная диаграмма

Временная диаграмма
Временная диаграмма

Временная диаграмма помогает нам понять, что нам нужно программировать.

В двух верхних строках диаграммы показано изменение напряжения на анодах светодиодов. Напряжение на выводах, подключенных к анодам светодиодов, колеблется с частотой ~ 250 Гц. Это колебание напряжения для левого светодиода противоположно колебаниям правого светодиода. Когда напряжение на аноде высокое, соответствующий светодиод может светиться. Когда он низкий, соответствующий светодиод не горит. Это означает, что каждый светодиод может быть ярким в течение 2 миллисекунд и темным еще в течение 2 миллисекунд. Поскольку человеческий глаз имеет некоторую инерцию, мигание 250 Гц не заметно для наблюдателя. Три нижних ряда на диаграмме показывают изменение напряжения на контактах, подключенных к катодам светодиодов. Посмотрим на первый столбец диаграммы. Он показывает случай, когда левый светодиод горит красным цветом, а правый - зеленым. Здесь КРАСНЫЙ катод остается на низком уровне, в то время как левый анод находится на высоком уровне, ЗЕЛЕНЫЙ катод остается на низком уровне, а правый анод на высоком уровне, а СИНИЙ катод остается на низком уровне все время. В других столбцах диаграммы показаны комбинации катодного и анодного напряжения для различных цветов.

Как мы видим, существует взаимозависимость от состояния контактов. Без каких-либо рамок решить эту проблему было бы непросто. И здесь пригодится библиотека protothread.

Шаг 3: Программирование. Макросы и определения

Программирование. Макросы и определения
Программирование. Макросы и определения

Пример в шагах программирования представляет собой немного упрощенную версию. Программа сокращена, а некоторые символические определения заменены явными константами.

Начнем с самого начала. Программа включает файлы, идущие с Atmel Studio, а также заголовок библиотеки protothread. Далее идут два макроса для управления уровнями выводов и некоторые определения для присвоения логических имен сигналам выводов. Пока ничего особенного.

Шаг 4: Программирование. Основной цикл

Программирование. Основной цикл
Программирование. Основной цикл

Затем давайте посмотрим в конец, чтобы увидеть, что содержит основная процедура.

Функция main после выполнения некоторой инициализации остается в цикле навсегда. В этом цикле он выполняет следующие шаги:

  • Вызывает подпрограмму протопотока для левого светодиода. Изменяет напряжение на некоторых контактах.
  • Сделайте задержку в две миллисекунды. Напряжение на контактах не меняется.
  • Вызывает протопоток для правого светодиода. Он изменяет напряжение на выводах.
  • Сделайте задержку 2 мс. Напряжение на контактах не меняется.

Шаг 5: Программирование. Вспомогательные функции

Программирование. Вспомогательные функции
Программирование. Вспомогательные функции

Прежде чем мы начнем обсуждать протопотоки, нам нужно взглянуть на некоторые вспомогательные функции. Сначала есть функции для установки определенного цвета. Они прямолинейны. Таких функций столько же, как количество поддерживаемых цветов (семь) и еще одна функция для настройки темноты светодиода (NoColor).

И есть еще одна функция, которая будет напрямую вызвана подпрограммой protothread. Его имя - DoAndCountdown ().

Технически использование такой функции не является обязательным, но мне это показалось удобным. У него есть три аргумента:

  • Указатель на функцию, устанавливающую цвет светодиода (например, RedColor или GreenColor и т. Д.)
  • Начальное значение обратного счетчика: сколько раз эта функция должна быть вызвана на конкретном этапе протопотока.
  • Указатель на обратный счетчик. Предполагается, что при изменении цвета обратный счетчик равен 0, поэтому сначала код итерации присвоит этому счетчику начальное значение. После каждой итерации счетчик уменьшается.

Функция DoAndCountdown () возвращает значение обратного счетчика.

Шаг 6: Программирование. Процедуры Protothread

Программирование. Процедуры Protothread
Программирование. Процедуры Protothread

А вот ядро фреймворка: процедура protothread. Для простоты пример ограничен только тремя шагами: для изменения цвета на КРАСНЫЙ, ЗЕЛЕНЫЙ и СИНИЙ.

Функция вызывается с двумя аргументами:

  • Указатель на структуру протопотока. Эта структура была инициализирована main перед запуском основного цикла.
  • Указатель на обратный счетчик. Перед запуском основного цикла он был установлен в 0.

Функция устанавливает напряжения, чтобы активировать левый светодиод, а затем запускает сегмент протонити. Этот сегмент находится между макросами PT_BEGIN и PT_END. Внутри есть код, который в нашем случае только повторяет макросы PT_WAIT_UNTIL. Этот макрос выполняет следующие действия:

  • Вызов функции DoAndCountdown. Это устанавливает напряжение на катодах светодиодов, чтобы излучать определенный цвет.
  • Возвращенный результат сравнивается с 0. Если условие 'false', функция protothread немедленно возвращает и передает управление основному циклу.
  • Когда protothread вызывается в следующий раз, он снова выполняет код перед PT_BEGIN, а затем переходит непосредственно внутрь макроса PT_WAIT_UNTIL, из которого он возвращался в прошлый раз.
  • Такие действия повторяются до тех пор, пока результат DoAndCountdown не станет 0. В этом случае возврата нет, программа остается в протопотоке и выполняет следующую строку кода. В нашем случае это следующий PT_WAIT_UNTIL, но, вообще говоря, это может быть почти любой код C.
  • При первоначальном выполнении второго обратного счетчика PT_WAIT_UNTIL значение 0, поэтому процедура DoAndCountdown () устанавливает его на начальное значение. Второй макрос снова будет выполнен 250 раз, пока счетчик реверсирования не достигнет 0.
  • Состояние struct pt сбрасывается, как только управление достигает макроса PT_END. Когда функция protothread вызывается в следующий раз, когда сегмент protothread начинает выполнение строки кода сразу после PT_BEGIN.

Для правого светодиода существует аналогичная процедура протонити. В нашем примере это просто обеспечивает другой порядок цветов, но если мы можем сделать это совершенно по-другому: нет тесной связи между процедурами левого и правого светодиода.

Шаг 7: внутренности

Внутренности
Внутренности

Вся программа занимает менее 200 строк кода (с комментариями и пустыми строками) и занимает менее 20% памяти кода Attiny85. При необходимости здесь можно использовать еще несколько подпрограмм протопотока и назначить им гораздо более сложную логику.

Библиотека Protothreads - это простейшая форма компьютерного параллельного программирования. Параллельное программирование - это подход, позволяющий разделить программу на логические части: иногда они называются сопрограммами, иногда потоками, иногда задачами. Принцип заключается в том, что каждая такая задача может использовать одну и ту же мощность процессора, сохраняя при этом код более или менее линейным и независимым от других частей. Задачи с логической точки зрения могут выполняться одновременно.

Для расширенных систем управление такими задачами выполняется либо ядром операционной системы, либо языковой средой выполнения, встроенной в исполняемый файл компилятором. Но в случае протопотоков прикладной программист управляет им вручную, используя библиотеку макросов protothreads в подпрограммах задач и вызывая такие подпрограммы (обычно вне основного цикла).

Вы, наверное, хотите знать, как на самом деле работает protothread? Где спрятана магия? Протопотоки полагаются на особую функцию языка C: тот факт, что оператор C switch case может быть встроен в if или какой-либо другой блок (например, while или for). Подробности вы можете найти на сайте Адама Данкелса

Внутреннее устройство электроники этого проекта очень простое. Фотография выше дает вам некоторую подсказку. Я уверен, что у тебя получится лучше.

Рекомендуемые: