MAX 7219. Управление светодиодными индикаторами. Часть 3 (Arduino).

В предыдущей статье мы подробно разобрали как управлять микросхемой MAX7219, хотя и только в теории, затем мы разобрали как это делается на языке Си в для микроконтроллеров AVR (на примере ATMEGA8). А в данном материале я приведу подробный пример, как это сделать на Arduino. По сути эта та же статья про программирование на Си для AVR, но с кодом «переведенным» на «ардуинский язык».

Как отмечалось в статье MAX 7219. Управление светодиодными индикаторами. Часть 1 (Теория)., управление сводится к записи в определенные регистры MAX 7219 различных значений. Соответственно, первое, что нам надо сделать это научиться записывать в в нужные регистры нужные данные. Напишем соответствующую подпрограмму для Arduino по аналогии с ATMEGA8.

//ВЕРСИЯ ДЛЯ Arduino
#define DIN 2 //определяем пины к которым мы присоединим нашу MAX7219, это будут цифровые пины 2,3 и 4
#define CLK 3
#define CS 4
void Transfer7219(byte adr,byte data)
{
byte i=0;//просто переменная-счетчик
digitalWrite (CS,LOW);//выводим «0» на лапку CS, чтобы начать передачу команды
asm(«nop»);//коротенькая пауза длиной в 1 тактfor(i=0;i<8;i++)//выгружаем байт адреса
{
if((adr & 0x80)==0x80)// определяем, что выводить
{
digitalWrite (DIN,HIGH);// единицу
}
else
{
digitalWrite (DIN,LOW); // или ноль
}

asm(«nop»); //создаем тактовый импульс, посылая сначала 1, а затем спустя короткое время 0 на лапку CLK
digitalWrite (CLK,HIGH);
asm(«nop»);
digitalWrite (CLK,LOW);
adr <<= 1;
}

for(i=0;i<8;i++) //выводим байт данных
{//тут всё то же самое, что и при выводе адреса. Если хотите, то можно вынести этот кусок кода в отдельную функцию
if((data & 0x80)==0x80)
{
digitalWrite (DIN,HIGH);// единицу
}
else
{
digitalWrite (DIN,LOW); // или ноль
}

asm(«nop»); //создаем тактовый импульс, посылая сначала 1, а затем спустя короткое время 0 на лапку CLK
digitalWrite (CLK,HIGH);
asm(«nop»);
digitalWrite (CLK,LOW);
data <<= 1;
}
digitalWrite (CS,HIGH);//выводим 1 на CS, завершая таким образом процесс передачи команды
}

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

//общий кусочек кода для инициализации
//при использовании данного кода нужно отдавать себе отчет в том, что нужные лапки порта сконфигурированы на выход
//иначе говоря, если мы используем порт PORTD, то где нибудь перед функцией инициализации должна присутствовать такая запись
pinMode (DIN,OUTPUT);//конфигурируем нужные лапки на выход
pinMode (CLK,OUTPUT);
pinMode (CS,OUTPUT);
//********************* собственно функция инициализации *****************
void setup_7219()
{
Transfer7219(0x0F,0);//очищаем регистр DisplayTest, для перехода в нормальный режим работы
Transfer7219(0x0C,1);//записываем «1» в регистр MAX7219, тем самым выводя микросхему из режима Shutdown, обычно ей требуется 250 мкс на включение, но это не мешает принимать команды
Transfer7219(0x0A,1);//записываем значение яркости дисплея, в данном случае — «1», почти минимальное значение
Transfer7219(0x0B,7);//записываем в ScanLimit максимальное значение «7», что позволяет отображать содержимое всех регистров дисплея от Digit 0 до Digit 7
Transfer7219(0x09,0);//ну и наконец отключаем дешифратор, путем записи 0 в регистр Decode Mode
}

А после инициал7219изации можно чего-нибудь и вывести на дисплей. В данном случае наглядней будет вывести какую-нибудь пиктограммку на дисплей 8х8. Давайте запишем в регистры 0x01 и 0x08 значения 0x81. В двоичном виде это значение будет выглядеть так — 0b10000001. То есть мы записываем в крайние два регистра значения зажигающие два крайних светодиода. Результатом исполнения двух строчек ниже должны стать четыре горящие точки по краям дисплея.

Transfer7219(0x01,0x81);
Transfer7219(0x08,0x81);

а для пущей наглядности давайте вообще заполоним всё поле дисплея точками в шахматном порядке:

Transfer7219(0x01,0xAA);
Transfer7219(0x02,0x55);
Transfer7219(0x03,0xAA);
Transfer7219(0x04,0x55);
Transfer7219(0x05,0xAA);
Transfer7219(0x06,0x55);
Transfer7219(0x07,0xAA);
Transfer7219(0x08,0x55);

7segПолагаю, что приведенных примеров для понимания, как управлять матрицей 8х8 с помощью MAX7219, вполне достаточно. Давайте перейдем к управлению семисегментным индикатором. Возьмем промышленно изготовленный образец с одной MAX7219 и восемью индикаторами с десятичными точками, изображенный на фотографии. О соответствии разрядов байта индицируемым сегментам можно почитать в моей статье о микросхеме TM1637. Итак, данный модуль управляется ровно также как и вышеописанная матрица 8х8 и светодиодов в данном модуле тоже 64, но уже по внешнему виду понятно, что результат работы одной и той же программы для этих дисплеев будет разным. Вот для примера небольшое видео работы демонстрационной программы. Оба модуля показанные на видео подключены к одним и тем же выводам Arduino Nano и в обоих случая мы видим постепенное заполнение дисплея загорающимися светодиодами. Программа взята из примера к библиотеки для Arduino.

Для отображения чисел в режиме прямого управления необходимо использовать программный дешифратор, преобразующий код цифры в код прямого управления сегментами. Например для того, чтобы отобразить цифру «1», необходимо зажечь два сегмента B и C, которые соответствуют второму и третьему разряду в байте. Иначе говоря, в регистр нужного нам знакоместа нужно записать число 00000110 в двоичной системе или 6 в десятичной. И так далее. Но в самой микросхеме MAX7219 уже имеется встроенный дешифратор и о принципе его действия я подробно рассказывал в теоретической части. Теперь к практике: вывести цифру на определенное место проще простого, особенно если речь идет о десятичной системе счисления, то есть о символах от «0» до «9». Мы просто записываем нужную нам цифру в соответствующий регистр. Например, если нам нужно вывести на ранее упомянутый нами 8-разрядный дисплей цифры от 1 до 8, то уместен будет такой простой код:

void display12345678()
{
for (byte i = 1;i<=8,i++)
{
Transfer7219(i,i); //мы просто вносим в каждый регистр, отвечающий за хранение отображаемой информации, его номер. Вуаля!
}
}

Ну вот вроде и всё, что касается взаимодействия MAX7219 c Arduino. Все остальные фишки, такие как вывод чисел и значений переменных на цифровой дисплей, рисование пиктограмм и букв на матрице 8х8, непосредственно к программированию MAX7219 не относятся. Но мне совершенно не жалко поделиться своими наработками в этой области и в дальнейшем я обязательно напишу статью и выложу примеры прикладного кода. На матрицах 8х8 я делал бегущую строку, дисплей часов и простую анимацию. Опыта практического применения 8-ми разрядного семисегментного дисплея у меня еще не было, но в качестве примера можно будет чего-нибудь придумать. Часы, те же самые, термометр или любой другой прибор, отображающий информацию.
Кстати, если Вам показалось это сложным, то Вы можете использовать уже упомянутую специальную библиотеку для плат Arduino.

Как всегда ссылки на скачивание для ленивых:
MAX7219 datasheet
Библиотека MAX7219 для Arduino