Микросхема MAX7219 (MAX7221) предназначена для управления семисегментными светодиодными индикаторами. Использование данного драйвера в электронных устройствах на микроконтроллере значительно упрощает вывод информации на индикаторы. Отпадает необходимость в реализации динамической индикации, как следствие экономия процессорного времени, упрощение кода программы. Управление драйвером осуществляется по интерфейсу SPI, для реализации которого потребуется выделить всего 3 линии ввода/вывода микроконтроллера, максимальная частота тактирования равна 10 Мгц. Помимо семисегментных индикаторов, с помощью драйвера можно управлять светодиодной матрицой. MAX7221 является аналогичным драйвером, с незначительными отличиями.
Ниже представлена схема подключения семисегментных индикаторов к драйверу MAX7219:
К драйверу можно подключить до 8-ми индикаторов с общим катодом. Выводы DIN, CLK, CS (LOAD для MAX7221) используются для передачи данных по интерфейсу SPI, к выводу ISET подключается резистор, задающий максимальный ток через сегменты индикатора, минимальное сопротивление резистора равно 9,53 кОм, при этом максимальный ток составит 40 мА. Вывод DOUT используется для каскадного подключения нескольких драйверов, этот вывод подключают к входу DIN второго драйвера, тем самым данные загруженные в первый драйвер последовательно загружаются во второй. Я не стал собирать схему из отдельных деталей, а заказал в Китае готовое цифровое табло из 8-ми индикаторов на основе данного драйвера, схема которого соответствует вышеприведенной.
Передача данных на драйвер осуществляется пакетами, состоящими из двух байт, первый байт – адрес регистра к которому идет обращение, второй байт непосредственно данные, которые надо записать в этот регистр. Во время передачи пакета данных, необходимо установить низкий логический уровень на линии CS.
Всего имеется 14 регистров, с помощью которых осуществляется управление драйвером. При задании адреса старший полубайт не имеет значения. В следующей таблице показаны адреса регистров и их назначение:
Адрес | Название | Назначение |
0хХ0 | No-Op | Пустой регистр, изменение значения регистра не влияет на работу драйвера. |
0хХ1 | Digit 0 | Данные для 0-го индикатора |
0хХ2 | Digit 1 | Данные для 1-го индикатора |
0хХ3 | Digit 2 | Данные для 2-го индикатора |
0хХ4 | Digit 3 | Данные для 3-го индикатора |
0хХ5 | Digit 4 | Данные для 4-го индикатора |
0хХ6 | Digit 5 | Данные для 5-го индикатора |
0хХ7 | Digit 6 | Данные для 6-го индикатора |
0хХ8 | Digit 7 | Данные для 7-го индикатора |
0хХ9 | Decode Mode | Регистр управления режимом декодирования данных |
0хХA | Intensity | Регистр настройки яркости свечения индикаторов |
0хХB | Scan Limit | Регистр настройки количества активных индикаторов |
0хХC | Shutdown | Регистр управления режимом работы |
0хХF | Display Test | Регистр для тестирования драйвера |
Регистр Decode Mode позволяет установить режим декодирования данных для каждого индикатора: 0-й бит регистра отвечает за 0-й индикатор (на схеме HG1), 1-й бит соответствует 1-му индикатору (на схеме HG2) и т.д. Если значение бита равно 0, декодирование данных отключено, если 1 – включено.
При отключенном режиме декодирования, значения битов в регистрах Digit X (где X – номер индикатора) определяют состояние сегментов на соответствующем индикаторе. Сегмент погашен при 0-м значении бита, и включен при 1, то есть, чтобы отобразить какой-либо символ на индикаторе, необходимо правильно выставить биты в регистре Digit X.
Режим декодирования упрощает процесс вывода символов на индикаторы, например, для отображения цифры 1, надо просто записать в регистр Digit X число 1. Ниже в таблице приведено соответствие отображаемых символов от значения регистра Digit X, для режима с декодированием данных и без него:
Символ | Декодирование включено | Декодирование отключено | ||||||||||||
Биты регистра Digit X | Биты регистра Digit X и соответствующие сегменты индикатора | |||||||||||||
DP | A | B | C | D | E | F | G | |||||||
7 | 6-4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0 | X | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | ||
1 | X | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | ||
2 | X | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | ||
3 | X | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | ||
4 | X | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | ||
5 | X | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | ||
6 | X | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | ||
7 | X | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | ||
8 | X | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | ||
9 | X | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | ||
– | X | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
E | X | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | ||
H | X | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | ||
L | X | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | ||
P | X | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | ||
Индикатор погашен | X | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Расположение сегментов (a, b, c, d, e, f, g, dp) в стандартном индикаторе можно увидеть на вышеприведенной схеме. В режиме декодирования, состояние 4,5,6-го битов в регистре Digit X не имеет значения. Независимо от режима, 7-й бит отвечает за отображение десятичного знака.
Регистр Intensity предназначен для цифровой регулировки интенсивности свечения. Изменение яркости свечения реализовано с помощью ШИМ, всего имеется 16 уровней яркости, в следующей таблице представлено соответствие между яркостью свечения и значением регистра Intensity:
Коэффициент заполнения ШИМ | Биты регистра Intensity | Шестнадцатеричное значение | |||||
MAX7219 | MAX7221 | D7-D4 | D3 | D2 | D1 | D0 | |
1/32 (мин.) | 1/16 (мин.) | X | 0 | 0 | 0 | 0 | 0хХ0 |
3/32 | 2/16 | X | 0 | 0 | 0 | 1 | 0хХ1 |
5/32 | 3/16 | X | 0 | 0 | 1 | 0 | 0хХ2 |
7/32 | 4/16 | X | 0 | 1 | 1 | 0 | 0хХ3 |
9/32 | 5/16 | X | 0 | 1 | 0 | 0 | 0хХ4 |
11/32 | 6/16 | X | 0 | 1 | 0 | 1 | 0хХ5 |
13/32 | 7/16 | X | 0 | 1 | 1 | 0 | 0хХ6 |
15/32 | 8/16 | X | 0 | 1 | 1 | 1 | 0хХ7 |
17/32 | 9/16 | X | 1 | 0 | 0 | 0 | 0хХ8 |
19/32 | 10/16 | X | 1 | 0 | 0 | 1 | 0хХ9 |
21/32 | 11/16 | X | 1 | 0 | 1 | 0 | 0хХA |
23/32 | 12/16 | X | 1 | 0 | 1 | 1 | 0хХB |
25/32 | 13/16 | X | 1 | 1 | 0 | 0 | 0хХC |
27/32 | 14/16 | X | 1 | 1 | 0 | 1 | 0хХD |
29/32 | 15/16 | X | 1 | 1 | 1 | 0 | 0хХE |
31/32(макс.) | 15/16(макс.) | X | 1 | 1 | 1 | 1 | 0хХF |
Значение старшего полубайта регистра Intensity не имеет значения. Максимальная яркость ограничивается резистором на выводе ISET, о чем было сказано выше.
С помощью регистра Scan Limit можно настроить количество активных индикаторов используемых для отображения данных, неактивные индикаторы при этом будут погашены. Ниже приведена таблица для настройки регистра Scan Limit:
Активные индикаторы | Биты регистра Scan Limit | Шестнадцатеричное значение | |||
D7-D3 | D2 | D1 | D0 | ||
0 | X | 0 | 0 | 0 | 0хХ0 |
0,1 | X | 0 | 0 | 1 | 0хХ1 |
0,1,2 | X | 0 | 1 | 0 | 0хХ2 |
0,1,2,3 | X | 1 | 1 | 0 | 0хХ3 |
0,1,2,3,4 | X | 1 | 0 | 0 | 0хХ4 |
0,1,2,3,4,5 | X | 1 | 0 | 1 | 0хХ5 |
0,1,2,3,4,5,6 | X | 1 | 1 | 0 | 0хХ6 |
0,1,2,3,4,5,6,7 | X | 1 | 1 | 1 | 0хХ7 |
Значение битов 3-7 в регистре Scan Limit не имеет значения. От количества активных индикаторов зависит частота их обновления, которая рассчитывается по следующей формуле: 6400/N, где N – количество активных индикаторов, например, при использовании всех 8-ми индикаторов частота обновления составит 800Гц.
Регистр No-Op используется для обращения к конкретному драйверу при использовании каскадного подключения нескольких драйверов, при этом линии CS (LOAD) всех драйверов необходимо соединить вместе, линии CLK также соединить вместе. Например, чтобы обратиться к четвертому драйверу в цепочке, сначала необходимо отправить пакет данных для этого драйвера, а затем установить 0 на линии DIN, и отправить еще 3 пакета. Таким образом, для первых 3-х драйверов обращение произойдет к регистру No-Op, не повлияв на их работу, а в 4-й драйвер будет доставлен требуемый пакет данных.
В регистре Shutdown активным является только 0-й бит, если значение этого бита установить в 0, то драйвер перейдет в спящий режим, и отключит индикаторы, при этом содержимое регистров не изменяется, при установке бита в 1 драйвер просыпается. В спящем режиме ток потребления составляет 250 мкА.
С помощью регистра Display Test можно проверить работоспособность сегментов на индикаторах, для этого необходимо установить 0-й бит регистра в 1, после чего засветятся все сегменты на всех индикаторах, для выключения теста надо установить бит обратно в 0.
На следующей картинке представлена схема подключения цифрового табло (заказать можно тут) на драйвере MAX7219 к микроконтроллеру PIC16F628A:
Рассмотрим код программы микроконтроллера:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | #include <P16F628A.INC> LIST p=16F628A __CONFIG H'3F10' ;Конфигурация микроконтроллера Sec equ 20h ;регистры хранения временных данных для Sec1 equ 21h ;подпрограмм паузы Sec2 equ 22h ; scetbit equ 23h ;регистр счета битов для передачи по протоколу spi dat_ind equ 24h ;регистр хранения данных для передачи по протоколу spi adr_ind equ 25h ;регистр хранения адреса для передачи по протоколу spi dat_tmp equ 26h ;вспомогательный регистр данных для передачи по протоколу spi adr_tmp equ 27h ;вспомогательный адресный регистр для передачи по протоколу spi #DEFINE din PORTB,5 ;линия входа данных драйвера MAX7219 #DEFINE cs PORTB,6 ;линия выбора драйвера MAX7219 #DEFINE clk PORTB,7 ;линия тактирования драйвера MAX7219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0000h ;начать выполнение программы с адреса 0000h goto Start ;переход на метку Start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Основная программа Start movlw b'01000000' ;установка выходных защелок порта B movwf PORTB movlw b'00000111' ;выключение компараторов movwf CMCON bsf STATUS,RP0 ;выбрать 1-й банк movlw b'00011111' ;настройка линий ввода\вывода порта B movwf TRISB ;RB0-RB4 на вход, остальные на выход bcf STATUS,RP0 ;выбрать 0-й банк call init_lcd ;вызов подпрограммы инициализации драйвера(MAX7219) met_1 movlw 0x09 ;отключить декодирование для всех индикаторов movwf adr_ind ; movlw 0x00 ; movwf dat_ind ; call send ; movlw 0x08 ;установка адреса 7-го индикатора (на схеме HG8) movwf adr_ind ; movlw b'01110111' ;установка битов в регистре данных для вывода буквы 'A' movwf dat_ind ; call send ; movlw 0x07 ;установка адреса 6-го индикатора (на схеме HG7) movwf adr_ind ; movlw b'00110111' ;установка битов в регистре данных для вывода буквы 'H' movwf dat_ind ; call send ; movlw 0x06 ;установка адреса 5-го индикатора (на схеме HG6) movwf adr_ind ; movlw b'01001111' ;установка битов в регистре данных для вывода буквы 'E' movwf dat_ind ; call send ; movlw 0x05 ;установка адреса 4-го индикатора (на схеме HG5) movwf adr_ind ; movlw b'01100111' ;установка битов в регистре данных для вывода буквы 'P' movwf dat_ind ; call send ; movlw 0x04 ;установка адреса 3-го индикатора (на схеме HG4) movwf adr_ind ; movlw b'00011111' ;установка битов в регистре данных для вывода буквы 'b' movwf dat_ind ; call send ; movlw 0x03 ;установка адреса 2-го индикатора (на схеме HG3) movwf adr_ind ; movlw b'00001101' ;установка битов в регистре данных для вывода буквы 'c' movwf dat_ind ; call send ; movlw 0x02 ;установка адреса 1-го индикатора (на схеме HG2) movwf adr_ind ; movlw b'00111101' ;установка битов в регистре данных для вывода буквы 'd' movwf dat_ind ; call send ; movlw 0x01 ;установка адреса 0-го индикатора (на схеме HG1) movwf adr_ind ; movlw b'00011101' ;установка битов в регистре данных для вывода буквы 'o' movwf dat_ind ; call send ; call paus_2s ;вызов подпрограммы паузы 1 сек movlw 0x09 ;включить декодирование для всех индикаторов movwf adr_ind ; movlw 0xFF ; movwf dat_ind ; call send ; movlw 0x08 ;установка адреса 7-го индикатора (на схеме HG8) movwf adr_ind ; movlw 0x00 ;запись числа 0 в регистр данных индикатора (вывод цифры 0) movwf dat_ind ; call send ; movlw 0x07 ;установка адреса 6-го индикатора (на схеме HG7) movwf adr_ind ; movlw 0x01 ;запись числа 1 в регистр данных индикатора (вывод цифры 1) movwf dat_ind ; call send ; movlw 0x06 ;установка адреса 5-го индикатора (на схеме HG6) movwf adr_ind ; movlw 0x02 ;запись числа 2 в регистр данных индикатора (вывод цифры 2) movwf dat_ind ; call send ; movlw 0x05 ;установка адреса 4-го индикатора (на схеме HG5) movwf adr_ind ; movlw 0x03 ;запись числа 3 в регистр данных индикатора (вывод цифры 3) movwf dat_ind ; call send ; movlw 0x04 ;установка адреса 3-го индикатора (на схеме HG4) movwf adr_ind ; movlw 0x04 ;запись числа 4 в регистр данных индикатора (вывод цифры 4) movwf dat_ind ; call send ; movlw 0x03 ;установка адреса 2-го индикатора (на схеме HG3) movwf adr_ind ; movlw 0x05 ;запись числа 5 в регистр данных индикатора (вывод цифры 5) movwf dat_ind ; call send ; movlw 0x02 ;установка адреса 1-го индикатора (на схеме HG2) movwf adr_ind ; movlw 0x06 ;запись числа 6 в регистр данных индикатора (вывод цифры 6) movwf dat_ind ; call send ; movlw 0x01 ;установка адреса 0-го индикатора (на схеме HG1) movwf adr_ind ; movlw 0x07 ;запись числа 7 в регистр данных индикатора (вывод цифры 7) movwf dat_ind ; call send ; call paus_2s ;вызов подпрограммы паузы 1 сек goto met_1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма инициализации драйвера(MAX7219) init_lcd call pauslcd ;вызов подпрограммы паузы 2 мс movlw 0x0F ;выключить тестовый режим movwf adr_ind ; movlw 0x00 ; movwf dat_ind ; call send ; movlw 0x0C ;включить драйвер в рабочий режим movwf adr_ind ; movlw 0x01 ; movwf dat_ind ; call send ; movlw 0x0A ;установить интенсивность свечения 15/32 movwf adr_ind ; movlw 0x07 ; movwf dat_ind ; call send ; movlw 0x09 ;включить декодирование для всех индикаторов movwf adr_ind ; movlw 0xFF ; movwf dat_ind ; call send ; movlw 0x0B ;использовать 8 индикаторов movwf adr_ind ; movlw 0x07 ; movwf dat_ind ; call send ; return ;выход из подпрограммы ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма отправки 2-х байт (пакета данных) на драйвер (MAX7219) по протоколу SPI send bcf cs ;Сбросить линию выбора драйвера CS movlw .8 ;Отправка содержимого адресного байта adr_ind movwf scetbit ; movf adr_ind,W ;копирование данных для передачи в промежуточный регистр movwf adr_tmp ; povtor bcf clk ; btfsc adr_tmp,7 ; bsf din ; btfss adr_tmp,7 ; bcf din ; bsf clk ; rlf adr_tmp,F ; decfsz scetbit,F ; goto povtor ; movlw .8 ;Отправка содержимого байта данных dat_ind movwf scetbit ; movf dat_ind,W ;копирование адреса для передачи в промежуточный регистр movwf dat_tmp ; povtr1 bcf clk ; btfsc dat_tmp,7 ; bsf din ; btfss dat_tmp,7 ; bcf din ; bsf clk ; rlf dat_tmp,F ; decfsz scetbit,F ; goto povtr1 ; bcf clk ; bsf cs ;установить в 1 линию выбора драйвера CS return ;выход из подпрограммы ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pauslcd movlw .4 ;подпрограмма пауза 2 мс movwf Sec1 ; p2 movlw .166 ; movwf Sec ; p1 decfsz Sec,F ; goto p1 ; decfsz Sec1,F ; goto p2 ; return ;выход из подпрограммы paus_2s movlw .10 ;подпрограмма пауза 2 сек movwf Sec2 ; p_3 movlw .255 ; movwf Sec1 ; p_2 movlw .255 ; movwf Sec ; p_1 decfsz Sec,F ; goto p_1 ; decfsz Sec1,F ; goto p_2 ; decfsz Sec2,F ; goto p_3 ; return ;выход из подпрограммы end ;конец всей программы ; |
В начале программы идет настройка регистров порта B, выключение компараторов. Далее вызывается подпрограмма инициализации драйвера MAX7219 (init_lcd), где производится настройка внутренних регистров драйвера. В начале инициализации вызывается подпрограмма паузы 2 мс, для того чтобы драйвер полностью включился и вошел в рабочий режим, иначе он не будет реагировать на команды. Инициализация выполняется путем последовательной отправки пакетов данных, и включает следующие этапы:
1. Отключение тестового режима (запись числа 0x00 в регистр драйвера Display Test);
2. Выход из спящего режима и переход в рабочий (запись числа 0x01 в регистр драйвера Shutdown);
3. Установка интенсивности свечения 15/32 (запись числа 0x07 в регистр драйвера Intensity);
4. Включение декодирование для всех индикаторов (запись числа 0x00 в регистр драйвера Decode Mode);
5. Установка 8-ми активных индикаторов (запись числа 0x07 в регистр драйвера Scan Limit).
В подпрограмме инициализации значения регистров Intensity, Decode Mode, Scan Limit могут иметь другие значения, в зависимости от требуемых параметров.
Отправка пакета данных на драйвер выполняется следующим образом: в регистр adr_ind записывается адрес регистра, к которому идет обращение, в регистр data_ind записывается значение, которое необходимо передать. Далее вызывается подпрограмма передачи пакета данных (send) по протоколу SPI, где сначала передается содержимое регистра adr_ind, а затем data_ind.
После выхода из подпрограммы инициализации, на драйвер отправляются данные, которые необходимо отобразить на индикаторах. Для примера на индикаторы слева-направо выводятся символы AHEPbcdo, с отключенным декодированием. Сначала выполняется отключение декодирования, далее в регистры драйвера Digit 0 – Digit 7 последовательно загружаются байты для каждого символа. В программе передаваемые байты представлены в виде двоичных чисел, для более удобной настройки символа выводимого на индикатор, настройка выполняется согласно вышеприведенной таблице соответствия битов регистра Digit X и сегментов индикатора.
Далее в программе показан пример вывода цифр от 0 до 7, с включенным декодированием. В регистры драйвера Digit 0 – Digit 7 последовательно загружаются числа от 7 до 0. Так как декодирование включено, отображаемые цифры будут соответствовать загруженным числам, что упрощает процедуру вывода. На индикаторах слева – направо отобразятся цифры от 0 до 7.
Драйвер имеет 16 выходов, соответственно к нему можно подключить светодиодную матрицу 8×8, причем в продаже имеются уже готовые модули на основе драйвера MAX7219 и матрицы 8×8, один из таких модулей я заказал здесь. Ниже представлена схема модуля и его подключение к микроконтроллеру PIC16F628A:
Линии драйвера, отвечающие за сегменты a, b, c, d, e, f, g, dp (7-ми сегментного индикатора) подключаются к линиям столбцов матрицы, строки матрицы подключаются к линиям управления индикаторами.
Код программы микроконтроллера представлен ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | #include <P16F628A.INC> LIST p=16F628A __CONFIG H'3F10' ;Конфигурация микроконтроллера Sec equ 20h ;регистры хранения временных данных для Sec1 equ 21h ;подпрограмм паузы Sec2 equ 22h ; scetbit equ 23h ;регистр счета битов для передачи по протоколу spi dat_ind equ 24h ;регистр хранения данных для передачи по протоколу spi adr_ind equ 25h ;регистр хранения адреса для передачи по протоколу spi dat_tmp equ 26h ;промежуточный регистр данных для передачи по протоколу spi adr_tmp equ 27h ;промежуточный адресный регистр для передачи по протоколу spi shet equ 28h ;вспомогательный регистр счета data_1 equ 29h ;начальный регистр хранения данных для вывода на матрицу #DEFINE din PORTB,5 ;линия входа данных драйвера MAX7219 #DEFINE cs PORTB,6 ;линия выбора драйвера MAX7219 #DEFINE clk PORTB,7 ;линия тактирования драйвера MAX7219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0000h ;начать выполнение программы с адреса 0000h goto Start ;переход на метку Start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Основная программа Start movlw b'01000000' ;установка выходных защелок порта B movwf PORTB movlw b'00000111' ;выключение компараторов movwf CMCON bsf STATUS,RP0 ;выбрать 1-й банк movlw b'00011111' ;настройка линий ввода\вывода порта B movwf TRISB ;RB0-RB4 на вход, остальные на выход bcf STATUS,RP0 ;выбрать 0-й банк call init_lcd ;вызов подпрограммы инициализации драйвера(MAX7219) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Последовательная запись 8-ми байт в регистры ОЗУ, из которых составляется буква 'R' на матрице ;запись байтов в регистры ОЗУ производится с помощью косвенной аддресации met_1 movlw data_1 ;установка начального адреса регистра для косвенной аддресации movwf FSR ; movlw b'01111000' ;запись 1-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000100' ;запись 2-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000100' ;запись 3-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01111000' ;запись 4-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01010000' ;запись 5-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01001000' ;запись 6-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000100' ;запись 7-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00000000' ;запись 8-го байта в регистр ОЗУ movwf INDF ; ; call vivod ;вызов подпрограммы вывода данных на матрицу call paus_2s ;вызов подпрограммы паузы 2 сек ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Последовательная запись 8-ми байт в регистры ОЗУ, из которых составляется буква 'L' на матрице ;запись байтов в регистры ОЗУ производится с помощью косвенной аддресации movlw data_1 ;установка начального адреса регистра для косвенной аддресации movwf FSR ; movlw b'01000000' ;запись 1-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000000' ;запись 2-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000000' ;запись 3-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000000' ;запись 4-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000000' ;запись 5-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000100' ;запись 6-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01111100' ;запись 7-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00000000' ;запись 8-го байта в регистр ОЗУ movwf INDF ; ; call vivod ;вызов подпрограммы вывода данных на матрицу call paus_2s ;вызов подпрограммы паузы 2 сек ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Последовательная запись 8-ми байт в регистры ОЗУ, из которых составляется цифра 15 на матрице ;запись байтов в регистры ОЗУ производится с помощью косвенной аддресации movlw data_1 ;установка начального адреса регистра для косвенной аддресации movwf FSR ; movlw b'00101111' ;запись 1-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01101000' ;запись 2-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'10101000' ;запись 3-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00101111' ;запись 4-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00100001' ;запись 5-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00100001' ;запись 6-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00101111' ;запись 7-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00000000' ;запись 8-го байта в регистр ОЗУ movwf INDF ; ; call vivod ;вызов подпрограммы вывода данных на матрицу call paus_2s ;вызов подпрограммы паузы 2 сек ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Последовательная запись 8-ми байт в регистры ОЗУ, из которых составляется узор 1 на матрице ;запись байтов в регистры ОЗУ производится с помощью косвенной аддресации movlw data_1 ;установка начального адреса регистра для косвенной аддресации movwf FSR ; movlw b'00111100' ;запись 1-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000010' ;запись 2-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'10111101' ;запись 3-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'10100101' ;запись 4-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'10100101' ;запись 5-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'10111101' ;запись 6-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000010' ;запись 7-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00111100' ;запись 8-го байта в регистр ОЗУ movwf INDF ; ; call vivod ;вызов подпрограммы вывода данных на матрицу call paus_2s ;вызов подпрограммы паузы 2 сек ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Последовательная запись 8-ми байт в регистры ОЗУ, из которых составляется узор 2 на матрице ;запись байтов в регистры ОЗУ производится с помощью косвенной аддресации movlw data_1 ;установка начального адреса регистра для косвенной аддресации movwf FSR ; movlw b'11100111' ;запись 1-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'11000011' ;запись 2-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'10100101' ;запись 3-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00011000' ;запись 4-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00011000' ;запись 5-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'10100101' ;запись 6-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'11000011' ;запись 7-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'11100111' ;запись 8-го байта в регистр ОЗУ movwf INDF ; ; call vivod ;вызов подпрограммы вывода данных на матрицу call paus_2s ;вызов подпрограммы паузы 2 сек ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Последовательная запись 8-ми байт в регистры ОЗУ, из которых составляется узор 3 на матрице ;запись байтов в регистры ОЗУ производится с помощью косвенной аддресации movlw data_1 ;установка начального адреса регистра для косвенной аддресации movwf FSR ; movlw b'10011001' ;запись 1-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000010' ;запись 2-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00100100' ;запись 3-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'10100101' ;запись 4-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'10100101' ;запись 5-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'00100100' ;запись 6-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'01000010' ;запись 7-го байта в регистр ОЗУ movwf INDF ; incf FSR,F ;инкремент регистра FSR movlw b'10011001' ;запись 8-го байта в регистр ОЗУ movwf INDF ; ; call vivod ;вызов подпрограммы вывода данных на матрицу call paus_2s ;вызов подпрограммы паузы 2 сек goto met_1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;подпрограмма отправки 8-ми байт данных из регистров ОЗУ на драйвер MAX7219 vivod movlw .8 ;запись счетчика циклов movwf shet ; movlw data_1 ;установка начального адреса регистра для косвенной аддресации movwf FSR ; movlw .1 ;запись начального адреса для обращению к регистрам MAX7219 в movwf adr_ind ;адресный регистр adr_ind viv_1 movf INDF,W ;копирование содержимого из регистра ОЗУ в регистр movwf dat_ind ;данных (dat_ind) для отправки на драйвер MAX7219 call send ;вызов подпрограммы отправки пакета данных на драйвер incf FSR,F ;инкремент регистра FSR incf adr_ind,F ;инкремент регистра adr_ind decfsz shet,F ;декремент счетчика циклов goto viv_1 ;счетчик не равен нулю: переход на метку viv_1 return ;счетчик равен нулю: выход из подпрограммы ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма инициализации драйвера(MAX7219) init_lcd call pauslcd ;вызов подпрограммы паузы 2 мс movlw 0x0F ;выключить тестовый режим movwf adr_ind ; movlw 0x00 ; movwf dat_ind ; call send ; movlw 0x0C ;включить драйвер в рабочий режим movwf adr_ind ; movlw 0x01 ; movwf dat_ind ; call send ; movlw 0x0A ;установить интенсивность свечения 15/32 movwf adr_ind ; movlw 0x07 ; movwf dat_ind ; call send ; movlw 0x09 ;отключить декодирование для всех индикаторов movwf adr_ind ; movlw 0x00 ; movwf dat_ind ; call send ; movlw 0x0B ;использовать 8 индикаторов movwf adr_ind ; movlw 0x07 ; movwf dat_ind ; call send ; return ;выход из подпрограммы ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Подпрограмма отправки 2-х байт (пакета данных) на драйвер (MAX7219) по протоколу SPI send bcf cs ;Сбросить линию выбора драйвера CS movlw .8 ;Отправка содержимого адресного байта adr_ind на драйвер movwf scetbit ; movf adr_ind,W ;копирование данных для передачи в промежуточный регистр movwf adr_tmp ; povtor bcf clk ; btfsc adr_tmp,7 ; bsf din ; btfss adr_tmp,7 ; bcf din ; bsf clk ; rlf adr_tmp,F ; decfsz scetbit,F ; goto povtor ; movlw .8 ;Отправка содержимого байта данных dat_ind на драйвер movwf scetbit ; movf dat_ind,W ;копирование адреса для передачи в промежуточный регистр movwf dat_tmp ; povtr1 bcf clk ; btfsc dat_tmp,7 ; bsf din ; btfss dat_tmp,7 ; bcf din ; bsf clk ; rlf dat_tmp,F ; decfsz scetbit,F ; goto povtr1 ; bcf clk ; bsf cs ;установить в 1 линию выбора драйвера CS return ;выход из подпрограммы ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pauslcd movlw .4 ;подпрограмма пауза 2 мс movwf Sec1 ; p2 movlw .166 ; movwf Sec ; p1 decfsz Sec,F ; goto p1 ; decfsz Sec1,F ; goto p2 ; return ;выход из подпрограммы paus_2s movlw .10 ;подпрограмма пауза 2 сек movwf Sec2 ; p_3 movlw .255 ; movwf Sec1 ; p_2 movlw .255 ; movwf Sec ; p_1 decfsz Sec,F ; goto p_1 ; decfsz Sec1,F ; goto p_2 ; decfsz Sec2,F ; goto p_3 ; return ;выход из подпрограммы end ;конец всей программы ; |
Как и в первой программе, сначала выполняется настройка регистров микроконтроллера, затем следует инициализация драйвера. Для более удобного восприятия передача данных на драйвер осуществляется с помощью косвенной регистровой адресации. Согласно схеме, содержимое регистров Digit 0 – Digit 7 драйвера будет соответствовать строкам матрицы. Содержимое регистра Digit 0 отображается в первой строке матрицы, Digit 1 во второй и т.д. Старший 7-й бит регистров Digit (0-7) соответствует первому столбцу, 0-й бит восьмому столбцу.
В программе выполняется последовательная запись 8-ми байтов составляющих изображение в регистры ОЗУ с помощью косвенной адресации. Далее вызывается подпрограмма vivod, для отправки данных на драйвер, 8 байт данных поочередно извлекаются из регистров ОЗУ и отправляются на драйвер с помощью подпрограммы отправки пакета данных (send). При этом адресный регистр adr_ind инкрементируется от 1 до 8, соответственно данные записываются в регистры c Digit 0 по Digit 7, то есть с первой строки матрицы по восьмую (сверху-вниз).
В программе выполняется вывод 6-ти изображений (символы R, L, цифра 15 и три узора) сменяющих друг друга через 2 сек. Составить желаемое изображение просто, всего необходимо записать 8 байт на 8 строк матрицы, первый байт соответствует первой строке матрицы, на следующей картинке можно посмотреть данное соответствие:
Способ вывода изображения в программе зависит от ориентации модуля с матрицей в пространстве относительно зрителя, я подобрал ориентацию для получения наиболее простого и понятного кода. Например, если повернуть модуль на 180 градусов, то в программе для текущих данных придется делать зеркальную симметрию в двух плоскостях, другой вариант, это составить байты данных, учитывая текущую ориентацию.
Данный модуль сконструирован так, что к нему можно подключить такой же модуль, по схеме получается каскадное соединение драйверов. Взяв несколько таких модулей, можно собрать светодиодную панель, на которой можно выводить движущийся текст, время, и т.д. Более подробно об этом можно почитать в статье про подключение светодиодных матриц MAX7219.
Александр
30 Мар 2017Доброго времени суток, подскажите пожалуйста можно ли использовать данный драйвер для управления диодными лентами (7 сегментный индикатор из диодной ленты) с напряжением 12В?
admin
30 Мар 2017Подключить можно, если дополнительно поставить транзисторы на выходы MAX7219
Олег
9 Дек 2017Я купил сборку из 4-х матриц matrix 8х8. Не подскажите можно ли развернуть матрицу на 180 гр. Только не программно, а воткнуть на плату. Не сгорит она при этом. Спрашиваю, т.к какой скеч не загружу в ардуино результат один – что-то происходит только на нескольких вертикальных рядах, остальные просто горят. Инфа и видео тут https://yadi.sk/d/hXDLDtV_3QJWFT
Благодарю за помощь.
admin
9 Дек 2017Неправильное подключение не навредит матрице.
На некоторых матрицах с обратной стороны можно увидеть подписанные номера выводов, но бывают матрицы где нумерация не видна и определить сразу не получится. У меня например модель матрицы нанесена на стороне где расположены выводы 1-8, а так надо мультиметром прозванивать и смотреть какие сегменты загораются. Например по рисунку их схемы в статье, если поднести плюсовой щуп к 13 выводу, а минусовой щуп к 9, то должен загореться сегмент в первой строке и в первом столбце (1-1). Если расположить матрицу так же как на схеме то это будет крайний левый и верхний сегмент.
Направление нумерации у матриц такая же, как и для микросхем, то есть смотрим сверху и начинаем отсчитывать слева с нижнего ряда и далее против часовой стрелки.
Фото с нумерацией матрицы и модуля MAX7219:
Олег
10 Дек 2017Спасибо огромное. Завелась, работает.
Иван
18 Окт 2020А можно ли использовать встроенный (USART) микроконтроллера?
Николай
23 Мар 2021Здравствуйте, у вас ошибка в таблице
При включенном декодировании:
6 это 0110 и 3 это тоже 0110?)
Роман
5 Ноя 2021Здравствуйте, не подскажете ваши примеры в си.?