Логотип

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

Программирование микроконтроллеров. Урок 14
Продолжаем изучать массивы. Подключение светодиодного кубика 3x3x3.

Урок 14 (Продолжаем изучать массивы. Подключение светодиодного кубика 3x3x3.)

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

Если вы не смогли сделать домашнее задание к 13-тому уроку, то мою версию таймера можно посмотреть и разобрать в прилагаемых файлах, находящихся в папке «leson_13_1».


И так начнем работу с кубиком. Сперва нам надо подключить его к микроконтроллеру. Ничего сложного в этом нет. Всё как на прошлом занятии за исключением того, что для подключения потребуется не 8, а 9 сигнальных линий.

Схема подключения светодиодного куба

Схема подключения светодиодного куба

Обратите внимание на то, что эта схема имеет ряд отличий от той, которую вы собирали на прошлом занятии. Их необходимо учесть. Во-первых, питание не 3.3, а 5 вольт. Во-вторых, управляющие транзисторы не кт814, а кт815. Они другой проводимости (npn), а значит их эмиттеры нужно подключать на общую шину питания. Ну и как было сказано выше для отображения девятого сегмента нам потребуется дополнительная линия РВ0 порта «В». У меня получилось вот так.

Монтажная плата 1 Монтажная плата 2 Монтажная плата 3

Монтажная плата 1

Монтажная плата 2

Монтажная плата 3

После того как схема собрана необходимо убедится в ее правильной работе. Для этого можно заполнить единицами порт «D», подать единицу на выход PB0 и поочередно подать питание на управление транзисторами (выходы МК РВ6, РВ7 и РВ1). При этом должны загораться все светодиоды выбранной секции. Но также можно проявить толику творчества и написать маленькую программку, которая будет по очереди зажигать нам все светодиоды.

Вот слегка упрощенная блок-схема этой программы, которую я предлагаю вам написать самостоятельно.

Блок схема тестовой программы

Блок схема тестовой программы

Для работы программы потребуются три переменные, а также настроить порты «D» и «B» как выходные. При входе в основной цикл происходит проверка нуля счетчика паузы (pausa), который будет осуществлять общую задержку и регулировать скорость переключения светодиодов. После счетчика паузы, в начале каждой итерации переключения, проверяется обнуление счетчика светодиодов (c_led). Если все светодиоды были поочередно включены и счетчик обнулен, то происходит переключение рабочей секции (c_plate), задается номер следующей и происходит проверка по превышению номера секции, после чего выставляется максимальное значение счетчика светодиодов, которое указывает на девятый светодиод. Если же счетчик светодиодов не обнулен, то включается следующий светодиод, а счетчик светодиодов декремируется. После всех изменений выставляется максимальная пауза и цикл повторяется.

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

Вот что у вас должно получиться в итоге.

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

Помедитировав на «бегающий» светодиод и получив свою долю удовольствия будем двигаться дальше.

Если особо не заморачиваться с ШИМ, то работу светодиода в пределе можно представить, как «горит» - 1 «не горит» - 0. Посему очевидно то, что нам нужен массив данных равный количеству светодиодов в ячейки которого мы будем заносить эти самые нули и единицы. Т.к. у нас три плоскости по 9 светодиодов в каждой то логичным будет использовать массив 3х9.

Но перед тем как мы начнем писать программу необходимо вспомнить о том, что, во-первых, массивы могут хранить несколько элементов, но все они должны быть одного типа. Во-вторых, нумерация элементов массива начинается с нуля «0», а не с единицы. В-третьих, при объявлении массива с заданным количеством элементов указывается количество его ячеек, а не номер последней ячейки.

Синтаксис объявления массива будет таким:

Тип_данных имя_массива [количество_элементов]; 

Например,

unsigned char m_cub [3] [9]; //массив данных для кубика 

Чтобы передать массив в подпрограмму необходимо проследить чтобы реципиент имел одинаковую структуру с донором.

//Объявление подпрограмм
    void show (unsigned char m_show [3][9]); //подпрограмма отображения

А синтаксис передачи всего массива в подпрограмму очень прост.

show (m_cub);

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

Блок схема программы обработчика

Блок схема программы обработчика

При входе в подпрограмму мы объявляем необходимые переменные, затем выключаем все светодиоды и закрываем транзисторы обнулив оба порта. После чего подпрограмма переходит в блок ротации отображаемых плоскостей. Приращение номера отображаемой плоскости, проверка номера на максимальное значение и выставление нулевого значения в случае выхода за пределы. Затем программа переходит к блоку выведения информации из массива для отображения. Запускается цикл для пересчета всех ячеек выбранной плоскости (от 0 до 8) и т.к. у нас девятый светодиод подключен к другому порту, нежели первые 8, то нам необходимо контролировать счетчик светодиодов и обработать девятый светодиод отдельно. Проверка заключается в том, что если в проверяемой ячейки массива не ноль, то в нужный разряд порта мы записываем единицу, а если в ячейки ноль, то переходим к следующей итерации.

if (m_show_3_9[c_plane][c_leds]){
	if (c_leds < (MAX_LED-1)) PORTD |= (ON<<c_leds);
	else PORTB |= (ON<<LAST_LED);
};

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

Например:

m_cub [2][5] = 1;
show (m_cub);

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

Если я криво объяснил или у вас почему-то не получается, программу можно посмотреть в прилагаемых файлах. Но я всё-таки надеюсь на то, что вы всё сделаете сами как надо и получили кайф от проделанной работы.

После того как мы написали подпрограмму вывода информации на «объемный индикатор», нам необходимо научиться «жонглировать» единицами в массиве, чтобы получать интересные эффекты. Для этого мы должны в основном цикле написать программу, которая в процессе работы будет менять данные нашего массива.

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

Программа действительно не сложная и, на мой взгляд, проста в понимании. Вот блок схема программы.

Блок схема программы

Блок схема программы

Все как обычно. Объявляем переменные, инициализируем порты «D» «B» как выходные. Затем войдя в основной цикл проверяем задержку и если она обнулена, то создаем вложенный цикл и полностью очищаем массив. После чего увеличиваем переменную положения светодиода на единицу и проверяем на максимальное значение. Т.к. для «бега по кругу» мы не задействуем девятый светодиод, то крайним будет светодиод под номером восемь, данные которого лежат в седьмой ячейке. После чего записываем единицы в новые ячейки. Конечно для записи можно организовать цикл, но я решил не париться и просто записал три почти одинаковых строчки. После того как новые данные записаны в массив выставляется максимальная задержка и весь массив передается подпрограмме индикации show (m_cub);. Затем цикл повторяется.

Вот вроде ничего сложного. Я надеюсь, что все программы вы напишите сами.


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

Или сделать мерцающие звезды. Вот так.

Или капающие с «потолка» капли.

Или сделать программу для вывода еще каких-нибудь причудливых узоров. Да. Необходимо сказать о том, что для программы «мерцающие звезды» и «капли» я использовал процедуру генератора «случайных» чисел, которая имеется в стандартной библиотеке. Для этого необходимо подключить файл stdlib.h. А чтобы это сделать необходимо вспомнить шестой урок и почитать:
   М.Б. Лебедева «CodeVisionAVR пособие для начинающих» 2008г. Страницы 266…268.

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

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


Ну вот. Мы закончили с изучением основ языка «Си» для МК. В последующих уроках я собираюсь рассмотреть имеющиеся на борту микроконтроллера разные периферийные устройства, а также работу с прерываниями.

На сон, грядущий необходимо почитать о тактировании МК, режимах работы и возможностях сброса контроллера в разных ситуациях:
   Евставфьев А.В. «Микроконтроллеры AVR семейства Tiny и Mega фирмы Atmel» 2008г. Страницы 200…229.
   Ю.А. Шпак «Программирование на языке С для AVR и PIC микроконтроллеров» 2006. Страницы 35…37.


Т.к. у Евстифеева описывается все семейство «Mega», то вам для изучения необходимо выбирать из текста только описание, относящееся к микроконтроллеру «Mega-8».

На следующем занятии мы просто изменим тактовую частоту нашего МК с 1 МГц на 8 МГц и проконтролируем наше изменение по морганию светодиода. Для этого понадобится один светодиод и резистор на 300 Ом.


А на сегодня всё. Удачи.


03.01.19



Если вдруг найдете в статье неточности или заблуждения. Напишите мне об этом. Я подправлю.



Приложение:
Схема и проект CV_AVR.