Главная » Статьи » Как подключить

КОГДА НЕ ХВАТАЕТ НОГ. ЧАСТЬ 3. ДРАЙВЕР ИНДИКАТОРОВ MAX7221. Часть 2


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

 Если пропустили первую часть об этой микросхеме, советую почитать.

 Итак, в прошлый раз мы выводили цифры на индикатор путем прямого управления сегментами, то есть зажигали каждый сегмент в каждом разряде по отдельности. Это заставляет поначалу поломать голову над подключением индикатора и соответствии регистров и сегментов. 
В режиме BCD code B с этим намного проще. Например, чтобы вывести в первый разряд какую-нибудь цифру, мы отправляем адрес этого разряда (как и в случае прямого управления) а затем отправляем саму эту цифру. 
 Это стало доступно благодаря встроенному в микросхему декодера символов, который сам зажжет нужные сегменты индикатора. Декодер имеет память всего на 16 символов: цифры от 0 до 9, знак "-", пустой символ и 4 буквы - "E", "H", "L", "P". 
 Как это работает: например нам нужно вывести цифру 9, мы просто берем и отправляем эту цифру в микросхему (см. значение в Register Data в таблице ниже). Понятно что отправленная цифра будет соответствовать выводимой цифре. 
 



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

 Схема подключения драйвера осталась от прошлого раза:




 Как и в прошлый раз для тестирования использовал 4х разрядный индикатор.


 Вот исходник тестовой прошивки, которая сначала выведет на индикатор "----", затем слово "HELP" и потом увеличивающееся значение переменной
 А:
 

$regfile = "attiny2313.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 10
$framesize = 40

Config Portd = Output

Cs Alias Portd.1
Ser_clk Alias Portd.2
Ser_data Alias Portd.3

Dim A As Word
Dim Digit(8)as Byte
Dim Y As Byte
Dim Disp_num As Byte
Dim Disp_data As Byte
Dim Digit_str As String * 4
Dim Temp_str As String * 2

Gosub Max7219_setup  'выполняем обязательную настройку микросхемы

'выведем эти строки на индикатор
Digit_str = "----"
Gosub Prepare
Wait 2
Digit_str = "HELP"
Gosub Prepare
Wait 2

Do 'в главном цикле будем отображать значение увеличивающейся переменной

Wait 1
Incr A                   'переменная значение которой выводим на индикатор
Digit_str = Str(a)
Digit_str = Format(digit_str , "0000")
Gosub Prepare
Loop

End





'Подготовка данных для передачи
Prepare:
Do
For Y = 1 To 4
   Temp_str = Mid(digit_str , Y , 1)
   Select Case Temp_str
     'каждый символ в Case имеет собственное цифровое значение (см. таблицу)
      Case "0" : Temp_str = "0"
      Case "1" : Temp_str = "1"
      Case "2" : Temp_str = "2"
      Case "3" : Temp_str = "3"
      Case "4" : Temp_str = "4"
      Case "5" : Temp_str = "5"
      Case "6" : Temp_str = "6"
      Case "7" : Temp_str = "7"
      Case "8" : Temp_str = "8"
      Case "9" : Temp_str = "9"
      Case "-" : Temp_str = "10"
      Case "E" : Temp_str = "11"
      Case "H" : Temp_str = "12"
      Case "L" : Temp_str = "13"
      Case "P" : Temp_str = "14"
      Case " " : Temp_str = "15"
   End Select
   Digit(y) = Val(temp_str)
      Disp_num = Y           'номер разряда в который будут записаны данные
      Disp_data = Digit(y)   'данные которые будут записаны в этот разряд
      Gosub Disp_write
Next Y
Loop Until Y = 5
Return



'Передаем данные в Max7221
Disp_write:
Ser_data = 0
Ser_clk = 0
Cs = 0
Shiftout Ser_data , Ser_clk , Disp_num , 1  'номер разряда для вывода информации
Shiftout Ser_data , Ser_clk , Disp_data , 1  'данные, выводимые в  этот разряд
Cs = 1
Return


'инициализации max7221
Max7219_setup:
Disp_num = &H0C : Disp_data = 0  'будим микросхему и начинаем ее настраивать
Gosub Disp_write
Disp_num = &H09 : Disp_data = &B11111111       'включаем режим BCD code B
Gosub Disp_write
Disp_num = &H0A : Disp_data = 10   'уровень свечения сегментов от 0 до 15
Gosub Disp_write
Disp_num = &H0B : Disp_data = 3    'число используемых разрядов (4 разряда)
Gosub Disp_write
Disp_num = &H0F : Disp_data = 0    'тестовый режим выключен (0-вык, 1-вкл)
Gosub Disp_write
Disp_num = &H0C : Disp_data = 1
Gosub Disp_write
Return


Видео работы (я тут немного изменил программу, для поочередного вывода символов)






Категория: Как подключить | Добавлено: 06.09.2013
Просмотров: 19174 | Комментарии: 13 | Теги: MAX7221 | Рейтинг: 4.4/9
Всего комментариев: 13
13 xtrason   (16.05.2019 12:11) [Материал]
Макс, ты же вроде из Барнаула? Я тоже. Напиши мне в WhatsApp 8-983-107-4613

12 max   (15.05.2019 17:01) [Материал]
Отключите антивирус и будет счастье.

11 xtrason   (15.05.2019 11:49) [Материал]
Спасибо, но к сожалению антивирус блокирует доступ к ресурсу. Другой ссылки нет?

10 max   (15.05.2019 09:04) [Материал]
Посмотрите тут: http://lightportal.info/publ/chasy/chasy_kalendar_termometr_barometr_gigrometr_na_max7219_v_stile_stimpank/19-1-0-110 и тут: http://lightportal.info/publ/chasy/prostaja_meteostancija_s_chasami/19-1-0-119

9 xtrason   (15.05.2019 08:09) [Материал]
Например так:

$regfile = "attiny2313.dat"
$crystal = 8000000
$swstack = 16
$hwstack = 16
$framesize = 40

Ddrb = &B0000_0111
Portb = &B0000_0000
Config Timer0 = Timer , Prescale = 64

Dim Num(8) As Integer
Dim Dot(8) As Byte
Dim Count As Byte
Dim N As Long
Dim Ledout As Integer

Dat Alias Portb.0
Clk Alias Portb.1

On Ovf0 Refresh
Enable Ovf0
Enable Interrupts

N = 12345678

Do
'Можно так, а можно через строковые (STR - VAL)
Num(1) = N / 10000000
N = N Mod 10000000
Num(2) = N / 1000000
N = N Mod 1000000
Num(3) = N / 100000
N = N Mod 100000
Num(4) = N / 10000
N = N Mod 10000
Num(5) = N / 1000
N = N Mod 1000
Num(6) = N / 100
N = N Mod 100
Num(7) = N / 10
Num(8) = N Mod 10
Dot(3) = 1 : Dot(6) = 1
Loop

End

Refresh:
Incr Count : If Count > 8 Then Count = 1
Ledout = Lookup(count , Rank)
Shiftout Dat , Clk , Ledout , 1
Ledout = Lookup(num(count) , Symbol)
'для общего катода надо инвертировать выходные данные
'Ledout = Not Ledout
If Dot(count) = 1 Then Ledout = Ledout Xor &B0000_0001
Shiftout Dat , Clk , Ledout , 1
Pulseout Portb , 2 , 10
Return
'*******************************************************
'Разряд
Rank:
Data &B0000_0000
Data &B1000_0000 , &B0100_0000 , &B0010_0000 , &B0001_0000
Data &B0000_1000 , &B0000_0100 , &B0000_0010 , &B0000_0001
'-------------------------------------------------------
'Код символа - для общего анода
Symbol:
'0 1 2 3
'4 5 6 7
'8 9 10(пробел) 11(минус) и так далее по желанию...
'abcd_efgh
'
Data &B0000_0011 , &B1001_1111 , &B0010_0101 , &B0000_1101
Data &B1001_1001 , &B0100_1001 , &B0100_0001 , &B0001_1111
Data &B0000_0001 , &B0000_1001 , &B1111_1111 , &B1111_1101

8 xtrason   (15.05.2019 06:45) [Материал]
Макс, добрый день. А вы не пытались зажечь несколько точек на 8-разрядном дисплее? Например так: 123.456.78? Как это осуществить в программе? Как это сделать для двух 74HC595 с написанием собственной кодировки символов, я знаю. А вот как быть с этой мелкосхемой?

+1   Спам
7 TomaTLAB   (18.08.2014 23:30) [Материал]
to 6 pchela5 (10.09.2013 16:49) зачем Вам, милостивый государь, чтоб оно само точку ставило? :) Плавучку к энтому подключать? Вполне можно обойтись цельночисельной арихметикой с масштабированием и точку ручками поставить.

Незначащие нули не гасит, правда, и минус выводит в крайнюю левую позицию.
Но оно мне так нужно было.

Declare Sub Led_disp(byval Ud As Integer , Byval Udp As Byte)
Declare Sub Led_init()
Declare Sub Led_out(byval La0 As Byte , Byval Ld0 As Byte)

Const Lnop = &HF0
Const Ldecmode = &HF9
Const Lintens = &HFA
Const Lscanlim = &HFB
Const Lenable = &HFC
Const Ltest = &HFF

'LED driver out
Ledld Alias Portb.4 '/SS
Ledck Alias Portb.7 'SCK
Leddi Alias Portb.5 'MOSI
Led_init

Main:
Do
Loop

End

'*****************************
'LED display
'ud - out value
'udp - decimal point position

Sub Led_disp(ud , Udp)
Local Udi As Integer
Local Udb As Byte
Local I As Byte

If Ud < 0 Then Udb = 10 Else Udb = 15
If Udp = 5 Then Udb = Udb + &H80
Call Led_out(5 , Udb)

Ud = Abs(ud)
For I = 1 To 4
Udi = Ud Mod 10
Udb = Udi
Ud = Ud / 10
If Udp = I Then Udb = Udb Or &H80
Call Led_out(i , Udb)
Next
End Sub

'*****************************
'Init LED display
Sub Led_init()
Local J As Byte

For J = 1 To 8
Call Led_out(j , 0)
Next

Call Led_out(ldecmode , 255)
Call Led_out(lscanlim , 4)
Call Led_out(lintens , 15)
Call Led_out(ltest, 0)
Call Led_out(lenable , 1)
End Sub

'*****************************
'Send data to LED display
Sub Led_out(la0 , Ld0)

Reset Ledld
Shiftout Leddi , Ledck , La0 , 1 ' , 8 , 15
Shiftout Leddi , Ledck , Ld0 , 1 ' , 8 , 15
Set Ledld
'Delay
End Sub

6 pchela5   (10.09.2013 16:49) [Материал]
to 3 exersizze (08.09.2013 11:08)
> В этом режиме точка не задействована. Ей придется управлять в обход драйвера.

В этой программе я бы сказал. Ибо точку можно поставить, записав в седьмой бит числа единичку - ниже под табличкой 5 даташита написано: "*The decimal point is set by bit D7 = 1". А вообще, я бы не отказался от куска кода в виде подпрограммы для данной максимки, который:
1. Гасит незначащие нули.
2. Сам ставит точку, куда надо.
3. Если будет выводить минус впереди для отрицательных чисел - будет вообще круто.

5 max   (08.09.2013 20:06) [Материал]
Лето - бывает.

4 exersizze   (08.09.2013 19:07) [Материал]
Спасибо, Макс. Этот материал должен быть опубликован аж 3 месяца назад, только сейчас стали доходить руки

3 exersizze   (08.09.2013 11:08) [Материал]
В этом режиме точка не задействована. Ей придется управлять в обход драйвера.

2 stepdim   (07.09.2013 12:21) [Материал]
Доброго времени суток. Подскажите пожалуйста, а как вывести точку на индикатор?

1 Scorpushka   (07.09.2013 10:10) [Материал]
спасибо! я так долго ждал обновления сайта

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]






авторизация
Логин:
Пароль: