MAX7219 – драйвер восьми разрядного индикатора с последовательным интерфейсом. Драйвер может управлять восемью семисегментными индикаторами с точкой, либо отдельно 64 светодиодами в LED панелях с общим катодом.
Драйвер MAX7219 управляется по трехпроводной последовательной шине Microwire (3-Wire). Каждый из разрядов индикатора имеет независимую адресацию и его содержимое может быть обновлен без необходимости перезаписи всего индикатора.
Основные характеристики:
- Частота тактирования интерфейса SPI … 10 МГц
- Напряжение питания … 4…5,5 В
- Потребление по шине +5 В в спящем режиме … 150 мкА
- Ток через один сегмент в импульсе … до 320 мА
- Средний ток через один сегмент … до 40 мА
- Частота следования импульсов включения символов … 500 Гц
- Задержка вывода на индикатор … 2,2 мс
Управляется MAX7219 через 16 битные регистры, старшим битом вперёд. В регистре первые 8 бит отводится под адрес регистра (фактически используются только 4-е младшие бита), остальные под 8 бит под данные.
Регистры управления драйвером MAX7219
Описание регистров:
- 0х00 — не используется
- 0х01 … 0х08 — регистры знакомест (вывод данных на индикаторы, в таблице слева указаны биты в режиме декодирования, справа показаны биты при отключенном режиме декодирования)
- 0х09 — режим декодирования (0х00 — отключен режим декодирования, 0xFF — режим декодирования активен)
- 0х0А — интенсивность свечения (яркость 16 значений)
- 0х0B — выбор кол-ва отображаемых знакомест
- 0x0C — спящий режим (0 — OFF, 1 — ON)
- 0x0F — тест
Для активации работы драйвера MAX7219 необходимо в регистрах указать следующие данные:
- адрес 0x0F, данные 0x00 – тест выключен
- адрес 0x0С, данные 0x01 – выйти из сна
- адрес 0x0B, данные 0x07 – кол-во знакомест 8
- адрес 0x09, данные 0xFF – дешифратор активирован
- адрес 0x0A, данные 0x04 – яркость уровень 4 из 16
Плата MAX7219 с индикаторами помимо питания имеет три контакта: DIN, CS, CLK
При логической единице на входе CS драйвер MAX7219 начинает воспринимать команды, на вход CLK подаются синхроимпульсы, а на вход DIN биты данных, которые считываются при нарастающем фронте синхроимпульса.
Для работы с модулем индикации на основе драйвера MAX7219 под управлением Arduino существуют несколько библиотек, но при использовании микроконтроллера ATtiny2313 использование библиотек не целесообразно из-за малого объема памяти (2 кБ). Поэтому я написал несколько функций реализующих управление трехпроводной последовательной шине Microwire (3-Wire) и вывод числового значения (long) на индикаторы.
Перед загрузкой скетча рекомендую ознакомится со статьей — ATtiny2313 + Arduino IDE
#define DIN PD2 #define CS PD3 #define CLK PD4 void setup() { DDRD |= (1 << DIN) | (1 << CS) | (1 << CLK); PORTD |= (1 << CS); PORTD &= ~(1 << CLK) | (1 << DIN); WriteBit16(0x0F,0x00); // тест выкл. WriteBit16(0x0C,0x01); // вкл. индик. WriteBit16(0x0B,0x07); // кол-во разрядов WriteBit16(0x09,0xFF); // дешифраторы вкл. WriteBit16(0x0A,0x04); // яркость } void loop() { dec(12345678); } void dec(long decimal){ WriteBit16(0x08,decimal/10000000); WriteBit16(0x07,decimal/1000000%10); WriteBit16(0x06,decimal/100000%10); WriteBit16(0x05,decimal/10000%10); WriteBit16(0x04,decimal/1000%10); WriteBit16(0x03,decimal/100%10); WriteBit16(0x02,decimal/10%10); WriteBit16(0x01,decimal%10); } void WriteBit16(byte reg, byte data){ PORTD &= ~(1 << CLK);PORTD &= ~(1 << CS); for(int i = 7; i >= 0; i--){ if(((reg >> i) & 1) == 1){PORTD |= (1 << DIN);}else{PORTD &= ~(1 << DIN);} PORTD |=(1 << CLK);PORTD &= ~(1 << CLK); } for(int i = 7; i >= 0; i--){ if(((data >> i) & 1) == 1){PORTD |= (1 << DIN);}else{PORTD &= ~(1 << DIN);} PORTD |=(1 << CLK);PORTD &= ~(1 << CLK); } PORTD |=(1 << CS);PORTD &= ~(1 << CLK);PORTD &= ~(1 << DIN); }
Скетч использует 430 байт (20%) памяти устройства. Всего доступно 2048 байт.
Глобальные переменные используют 9 байт (7%) динамической памяти, оставляя 119 байт для локальных переменных. Максимум: 128 байт.
Для примера использования платы восьми разрядного семисегментного индикатора на базе драйвера MAX7219 можно собрать простой частотомер (вход уровень TTL), с максимальной частотой измерения 9 МГц.
#define DIN PD2 #define CS PD3 #define CLK PD4 #define T1 PD5 volatile int x; unsigned int timer0; float f; float pop_k = 0.996237; void setup() { DDRD |= (1 << DIN) | (1 << CS) | (1 << CLK); PORTD |= (1 << CS); PORTD &= ~(1 << CLK) | (1 << DIN); PORTD |= (1 << T1); WriteBit16(0x0F,0x00); // Тест выкл. WriteBit16(0x0C,0x01); // Вкл. индик. WriteBit16(0x0B,0x07); // кол-во разрядов WriteBit16(0x09,0xFF); // Дешифраторы вкл. WriteBit16(0x0A,0x04); // яркость cli(); // TIMER1 TCCR1A = 0; TCCR1B = 0; TCCR1B = (1 << CS12)|(1 << CS11)|(1 << CS10); TIMSK |= (1 << TOIE1); // TIMER0 TCCR0A = 0; TCCR0B = 0; OCR0A = 250; TCCR0A |= (1 << WGM01); TCCR0B |= (1 << CS01); TIMSK |= (1 << OCIE0A); sei(); } void loop() {} void dec(long decimal){ WriteBit16(0x08,15); WriteBit16(0x07,decimal/1000000%10+0x80); WriteBit16(0x06,decimal/100000%10); WriteBit16(0x05,decimal/10000%10); WriteBit16(0x04,decimal/1000%10+0x80); WriteBit16(0x03,decimal/100%10); WriteBit16(0x02,decimal/10%10); WriteBit16(0x01,decimal%10); } void WriteBit16(byte reg, byte data){ PORTD &= ~(1 << CLK);PORTD &= ~(1 << CS); for(int i = 7; i >= 0; i--){ if(((reg >> i) & 1) == 1){PORTD |= (1 << DIN);}else{PORTD &= ~(1 << DIN);} PORTD |=(1 << CLK);PORTD &= ~(1 << CLK); } for(int i = 7; i >= 0; i--){ if(((data >> i) & 1) == 1){PORTD |= (1 << DIN);}else{PORTD &= ~(1 << DIN);} PORTD |=(1 << CLK);PORTD &= ~(1 << CLK); } PORTD |=(1 << CS);PORTD &= ~(1 << CLK);PORTD &= ~(1 << DIN); } ISR(TIMER0_COMPA_vect){ timer0++; if(timer0 == 1){ x = 0;TCNT1 = 0; TCCR1B = (1 << CS12)|(1 << CS11)|(1 << CS10);} if(timer0 == 10001){ TCCR1B &= ~(1 << CS12)|(1 << CS11)|(1 << CS10); f = ((x * 65535) + TCNT1)*pop_k; dec(f); timer0 = 0; } } ISR (TIMER1_OVF_vect){x++;}
Форум — http://forum.rcl-radio.ru/viewtopic.php?pid=3397#p3397