7-сегментный индикатор хорошо подходит для вывода цифровых значений - он компактен, эстетичен, потребляет мало тока, хорошо виден издалека и при ярком освещении. Каждый сегмент индикатора представляет собой светодиод. Зажигаясь, сегменты образуют цифру или символ.
Недостатком таких индикаторов является то, что для управления каждым сегментом нужен отдельный вывод.
Драйвер MAX7219 решает эту проблему. К 1 чипу MAX7219 можно подключить до 8 семисегментных светодиодных индикаторов, управлять которыми можно по интерфейсу SPI.
В этой статье мы рассмотрим модуль из 8-ми индикаторов, которыми управляет MAX7219 (http://smartelectronika.com/viewproduct/82/)
У модуля имеются 5 выходов (VCC, GND, DIN, CS, CLK). Подключаем их к Raspberry Pi следующим образом
VCC - 5V
GND - GND
DIN - GPIO10 (MOSI)
CS - GPIO8 (CE0)
CLK - GPIO11 (SCLK)
После подключения модуля приступаем к написанию управляющей программы. Для работы с SPI я использовал библиотеку wiringPi
Сначала модуль должен пройти инициализацию. Инициализация происходит посредством записи значений в управляющие регистры:
1. Для включения модуля записываем 0x01 в регистр Shutdown (адрес 0x07). Соответственно для выключения в этот регистр следует записать 0x00
2. В регистр Scan Limit (адрес 0x0B) записывается значение, соответствующее количеству 7-сегментных индикаторов, подключенных к MAX7219. Для восьми индикаторов это значение будет 0x07
3.Регистр Decode Mode (адрес 0x09) определяет режим работы индикаторов. Для каждого индикатора (а в нашем модуле их восемь) доступно 2 режима работы.
Первый режим - декодер включён. В этом случае на индикаторе загорается цифра или символ, соответствующая записанному в регистр индикатора значению - например, записали в регистр 9, на индикаторе загорается 9.
Второй режим - декодер выключен. Он нужен если требуется управлять каждым из семи сегментов индикатора по отдельности.
Регистр Decode Mode 1-байтный. Каждый бит в регистре соответствует режиму работы соответствующего индикатора. Если в бите стоит 1, то индикатор работает в первом режиме, если 0, то во втором. Соответственно, если нужно чтобы все индикаторы работали в первом режиме то записываем в регистр 11111111 (это 0xFF в шестнадцатиричной системе)
После инициализации, можно выводить значения на индикаторы. Это осуществляется записью значения в регистр индикатора.
Адрес регистров идут по порядку (0x00,0x01,0x02...0x08). Информация о том, какое значение нужно записать, чтобы получить на индикаторе тот или иной символ представлена в этой таблице:
Например, если третий индикатор работает в первом режиме, то для вывода на индикатор цифры "2” необходимо в регистр 0x03 записать 0010 (0x02 в шестнадцатиричной системе). Для того, чтобы после цифры загорелась точка, нужно записать 1 в регистр D7 (для 2. - 10000010). В первом режиме можно выводить на индикатор цифры 0-9, точку, знак минуса, буквы E,H,L,P
При втором режиме работы каждый ненулевой бит в значении управляющего регистра зажигает соответствующий сегмент
Если индикатор работает во втором режиме, то для того, чтобы зажечь сегмент "A" в управляющий регистр записываем 10000000
Данная программа выводит на модуль значение, которое передаётся как аргумент командной строки.
#include
#include
#include
#include
#include
#include
#include
int main (int argc, char *argv[])
{
uint8_t valueToDisplay[2];
uint8_t wCommand_1[2];
uint8_t wCommand_2[2];
uint8_t wCommand_3[2];
wCommand_1[0] = 0x0C; //shutdown register
wCommand_1[1] = 0x01;
wCommand_2[0]= 0x09; //decode mode
wCommand_2[1]= 0xFF;
wCommand_3[0]= 0x0B; //scan limit
wCommand_3[1]= 0x07;
wiringPiSetup () ;
if (wiringPiSPISetup (0, 10000000) < 0)
{
fprintf (stderr, "Unable to open SPI device 0: %s\n", strerror (errno)) ;
exit (1) ;
}
//init commands/
wiringPiSPIDataRW (0,wCommand_1,2);
wiringPiSPIDataRW (0,wCommand_2,2);
wiringPiSPIDataRW (0,wCommand_3,2);
//clear_screen
for ( int i = 1 ; i < 9; i++)
{
valueToDisplay[0]=i;
valueToDisplay[1]=0x0F;
wiringPiSPIDataRW(0,digit_value,2);
}
int cd = 0;
for (int i=0; i
{
char next=argv[1][i+1];
if (next!='.')
{
valueToDisplay[1]=argv[1][i];
}
else
{
valueToDisplay[1]=argv[1][i]+80;
}
if (argv[1][i]!='.' && cd<9)
{
valueToDisplay[0]=8-cd;
cd++;
wiringPiSPIDataRW(0,valueToDisplay,2);
}
}
return 0;
}
Сохраняем исходник в файл indicator.c и компилируем:
gcc -Wall -o indicator indicator.c -lwiringPi -std=c99
Запускаем программу - ./indicator 1.2.3.4.5678
На индикаторе должно высветиться 1.2.3.4.5678, как на фото:
На индикатор можно выводить, например, значение температуры процессора. Для этого я набросал вот такой скрипт:
#!/bin/bash
/home/pi/indicator $(vcgencmd measure_temp | egrep '([0-9]{1,3}\.[0-9]{1,3})' -o)
В следующей статье рассмотрим матричный индикатор на MAX7219
Комментариев: 2
Yuriu
25.08.2016 в 18:16 ответНебольшой вопрос: можно ли на rbp 3 к spi пинам подключить сразу два устройства? Или можно как-нибудь переделать другие gpio в spi
sv-lary
14.01.2022 в 18:41 ответИсходный текст битый... :-( Операторы #include обрезаны, главный цикл тоже оборван. А можно ссылку дать на исходный код в git-е, к примеру?