Шапка сайта

Меню

Главная
Полезные программы
Справочник
Карта сайта

Управление драйвером семисегментных индикаторов MAX7219

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

В общем то управление драйвером простое, как сдвиговым регистром по трехпроводной схеме (3-Wire). Вернее он и имеет как раз в своем составе сдвиговый регистр. Алгоритм управления такой. Низким уровнем на входе CS разрешаем принимать данные. Данные отсылаются по 16 бит, старшим битом вперед. Биты с 15 по 8 это или адрес знакоместа (значения от 1 до 8), или служебная команда (значения от 9 до 15). Биты с 7 по 0 это данные, либо для инструкции, либо образ (маска) символа. Каждый выставленный бит на входе DIN записывается в регистр по фронту тактового импульса на входе CLK. После того как все биты переданы, "защелкиваем" их, выставив единичку на входе CS.

Управляет драйвер восемью светодиодными семисегментными индикаторами с общим катодом. Это означает, что чтобы погасить все сегменты индикатора, надо прописать в него 0, а что бы зажечь, нужно прописать 255. Каждый из разрядов индикатора имеет независимую адресацию и его содержимое может быть обновлено без необходимости перезаписи всего индикатора.

Внешний вид модуля MAX7219.

внешний вид модуля MAX7219

Сама плата выполнена качественно, а вот индикаторы на ней припаяны кривовато. Подключение индикаторов странное. Ожидалось, что под номером 1 будет индикатор расположенный слева, но как видим слева идут 8, 7, 6 и т. д.. Почему-то распаяны они именно так, хоть это и не критично, и легко корректируется в коде программы.

знакоместа идут справа налево

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

вид модуля через светофильтр

А так индикаторы смотрятся через светофильтр. Яркость свечения не уменьшилась, а вот незасвеченные сегменты уже не видно.

Код "демки" на языке Си.

/**************************************************************/
/*** Управление драйвером семисегментных индикаторов MAX7219 **/
/************** нагруженным на восемь индикаторов. ************/
/************ Микроконтроллер: PIC16F628A *********************/
/************ Среда разработки MPLAB IDE v8.89 - язык C *******/
#include pic.h // нужен для HI-TECH C компилятора
#include htc.h // для работы с функцией задержки
#define _XTAL_FREQ 4000000 // прописываем частоту генератора
/************* прописали выводы микроконтроллера **************/
#define knopkaup RA0 // кнопка больше
#define knopkadown RA1 // кнопка меньше
#define DIN RB0 // определение ввод данных
#define CLK RB1 // определение тактирующего сигнала
#define CS RB2 // определение выбор устройства
#define DIN_OFF() DIN = 0; // данные в ноль
#define DIN_ON() DIN = 1; // данные в еденичку
#define STR_OFF() CLK = 0; // Строб в ноль
#define STR_ON() CLK = 1; // Строб в еденичку
#define WR_OFF() CS = 0; // начало передачи
#define WR_ON() CS = 1; // завершение передачи
/******************* логические операции **********************/
#define TestBit(x,y) (x & (1 << y)) // проверка бита
/********************** конфигурация **************************/
__CONFIG // Биты конфигурации
(INTIO // Внутренний генератор 4 мГц
& UNPROTECT // off защиту памяти
& BOREN // on контроль питания
& MCLRDIS // off вывод начальной установки
& PWRTEN // on таймер задержки запуска
& WDTDIS // off сторожевой таймер
& LVPDIS ); // off низковольтное программирование
/************************ переменные **************************/
unsigned char const cifra[11] = {0b01111110, 0b00110000,
0b01101101, 0b01111001, 0b00110011, 0b01011011, 0b01011111,
0b01110000, 0b01111111, 0b01111011, 0b00000000};
unsigned char const segment[6] = {0b01000000, 0b00100000,
0b00010000, 0b00001000, 0b00000100, 0b00000010};
unsigned char i, c, bright_indik, hg1, hg2, hhg1, hhg2;
/************************* функции ****************************/
void podgot(void)
{
TRISA = 0b00000011; // направление работы ножек порта А
TRISB = 0b00000000; // направление работы ножек порта В
CMCON = 0x07; // отключение компараторов
PORTB = 0xff; // очищаем порт B
RBPU = 0x01; // подтягивающие R (0-вкл, 1-выкл)
}
void w3_write(unsigned char adres, unsigned char data)
{
char i;
WR_OFF(); // начало передачи
for(i = 8; i > 0;i --)
{
if(TestBit(adres, i - 1))
{
DIN_ON(); // выставили единичку
}
else
{
DIN_OFF(); // выставили нолик
}
STR_ON(); // такт в единичку
__delay_us(5); // длительность строба
STR_OFF(); // такт в ноль
}
for(i = 8; i > 0; i --)
{
if(TestBit(data, i - 1))
{
DIN_ON(); // выставили единичку
}
else
{
DIN_OFF(); // выставили нолик
}
STR_ON(); // такт в единичку
__delay_us(5);
STR_OFF(); // такт в ноль
}
WR_ON(); // завершение передачи
}
void clear(void)
{
char i;
for(i = 8; i > 0; i --)
{
w3_write(i, cifra[10]); // гасим все индикаторы
}
}
void inic7219(void)
{
w3_write(0x0F, 0x00); // тест выключен
w3_write(0x0C, 0x01); // нормальный режим
w3_write(0x0B, 0x07); // кол-во знаков 8
w3_write(0x09, 0x00); // дешифраторы отключены
w3_write(0x0A, bright_indik); // яркость свечения
clear();
}
void klava(void)
{
if(knopkaup == 0 && bright_indik != 15)
{
bright_indik ++; clear();
w3_write(0x0A, bright_indik); // яркость свечения
hg1 = bright_indik / 10; // значение первой цифры
hg2 = bright_indik % 10; // значение второй цифры
hhg1 = cifra[hg1]; // маска первой цифры
hhg2 = cifra[hg2]; // маска второй цифры
w3_write(5, hhg1); // прописали первую цифру
w3_write(4, hhg2); // прописали вторую цифру
__delay_ms(1500); clear();
return;
}
if(knopkadown == 0 && bright_indik != 0)
{
bright_indik --; clear();
w3_write(0x0A, bright_indik);
hg1 = bright_indik / 10;
hg2 = bright_indik % 10;
hhg1 = cifra[hg1];
hhg2 = cifra[hg2];
w3_write(5, hhg1);
w3_write(4, hhg2);
__delay_ms(1500); clear();
}
}
/******************* основная программа ***********************/
void main(void)
{
podgot();
bright_indik = 8; // яркость по умолчанию
inic7219();
__delay_ms(500);
while(1)
{
for(c = 0; c < 3; c ++)
{
for(i = 0; i < 6; i ++)
{
w3_write(8, segment[i]);
w3_write(7, segment[i]);
w3_write(6, segment[i]);
w3_write(5, segment[i]);
w3_write(4, segment[i]);
w3_write(3, segment[i]);
w3_write(2, segment[i]);
w3_write(1, segment[i]);
__delay_ms(80);
}
}
__delay_ms(500);
clear(); klava();
for(i = 8; i > 0; i --)
{
w3_write(i, cifra[i]);
__delay_ms(500);
}
__delay_ms(500);
clear(); klava();
}
}

Теперь о коде. Главная здесь функция w3_write(), на ней все построено. При вызове функция получает два аргумента, adres и data и засылает их в регистр. Сначала восемь бит адреса или инструкции, затем восемь бит данных. Как уже было сказано, старшим битом вперед. После подачи питания и конфигурирования микроконтроллера вызывается подпрограмма inic7219(), которая прописывает в микросхему некоторую последовательность команд, после которой микросхема начинает нормально работать. Без инициализации микросхема ничего высвечивать не будет.

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

О соответствии битов data и сегментов индикаторов. Старший, седьмой бит управляет точкой (DP), биты с шестого по нулевой сегменты A,B,C,D,E,F и G соответственно. В принципе образы всех цифр уже прописаны в массиве cifra[]. Но если возникнет надобность закодировать какой-то иной символ, то можно воспользоваться онлайн-генератором здесь на сайте. В нем можно задать любую последовательность сегментов.

naladchikkip.ru © 2021–. Все права защищены