Динамическая индикация

Итак, девочки и мальчики, сегодня дядя Сережа расскажет о том, как соорудить динамическую индикацию в домашних условиях, че это ваще такое, и зачем оно нам.
Не вдаваясь в нудные предисловия скажем так:
Динамическая индикация – это метод отображения целостной картины через быстрое последовательное отображение отдельных элементов этой картины. Причем, «целостность» восприятия получается благодаря инерционности человеческого зрения.
На этом принципе, как вы догадываетесь, построено кино и телевидение. Не слишком занудно?
Поконкретнее.
Скажем, нам нужно организовать вывод какого-то числа на 7-сегментные индикаторы. Ну, например, мы делаем часы, или термометр, или еще чего-нибудь. Давайте посчитаем, сколько понадобится проводов, чтобы подключить индикаторы.
Кстати, индикаторы выглядят примерно вот так:
Уделим пару слов увиденному.
Перед нами – самый обычный светодиодный 7-сегментный индикатор. Вопрос: почему 7-сегментный, когда сегментов на самом деле – восемь? Ответ: потому что 8-й сегмент – это точка, которая не входит в изображение цифры и вообще, является необязательной. Бывают индикаторы и без точек.
Для нумерации сегментов используются латинские буквы от a до h . У всех всех всех 7-сегментных индикаторов в нашем бренном мире, сегменты нумеруются в том порядке, как это показано на рисунке, и никак иначе.
Теперь смотрим на схемы. Во-первых, почему их две? Да потому что индикаторы бывают разные. Бывают – с общим катодом (ОК), бывают – с общим анодом (ОА). Среди буржуйских более распространены, как ни странно, индикаторы с ОА. Но встречаются и с ОК. Так что – нужно быть осторожным, чтоб не спутать. Хотя, нам-то все равно. Нашими индикаторами будет управлять контроллер. А его можно запрограммировать как на работу с ОК так и с ОА. Тут сложностей нет.
У каждого индикатора – 9 ножек. С 1 по 8 – выводы сегментов, 9-я – общий. Допустим, мы хотим отображать 4-разрядное число. Надо 4 индикатора.
Арифметика маленького Пети: 8*4 = 32. То есть, нам потребуется 32 провода (не считая общие) Неслабо? Ничуть. Тем более, учитывая, что у большинства контроллеров количество каналов ввода/вывода как раз равно 32. Как-то меня не очень греет перспектива угрохать все выводы контроллера на индикацию. А вас? Ведь надо ж еще куда-то подключить кнопочки, ручечки, датчички и пр. пр. пр. а мало ли чего? Кстати, у любимого нами AT 90 s 2313 всего 15 каналов ввода/вывода. Как здесь прикажете быть? Вот тут нам и поможет динамическая индикация. Делаем очень просто: подключаем все индикаторы параллельно. Точнее, сажаем выводы сегментов на общую шину. А общие провода оставляем раздельно.
Смотрим небольшой поясняющий мультик:
Че мы делаем?
Мы последовательно подаем напряжение на адресные входы индикаторов, и одновременно выдаем в шину данных 7-сегментный код, соответствующий индикатору, активному в данный момент.
Все. Прекращаю кормить Вас баснями. Сейчас мы пишем прогу. В этой проге мы выведем на 4-разрядный индикатор число 1234. Вот тут то нам и понадобится узнанное в предыдущей главе об оперативной памяти.
Итак, я хочу, чтобы значения цифр, выводимых на индикацию, лежали в ячейках памяти. Поскольку у индикатора 4 разряда – значит цифр тоже будет 4, и соответственно, столько же ячеек памяти. Дабы не заморачиваться, мы объединяем все четыре ячейки в переменную Digit . Итак, пишем:
.include "d:\avr\avrasm\appnotes\2313def.inc" .def Temp1=R16 .def Temp2=R17 .def Temp3=R18 .def Temp4=R19 .def Temp=R20 .dseg Digit: .byte 4 Написали.
Теперь самое время определиться с портами.
Поскольку у нас на порт B уже повешены светодиоды – наверно не будет большим криминалом повесить туда еще и сегменты индикаторов.
Порт D пока что пустует – ну дык значит посадим туда общие провода. Рисуем схему:
Схему прошивки, как и договаривались, не показываем, но подразумеваем ее наличие.
В данной схеме используется два сдвоенных индикатора C562. Эти индикаторы – с общим катодом (об этом говорит буква C в названии). Будем иметь это ввиду при написании программы.
Вы можете поставить совершенно любые индикаторы, какие будут под рукой. Можно, например, поставить один счетверенный, или четыре одинарных. Также, можно ставить индикаторы с общим анодом – в программе только придется дописать пару строчек – совершенно ничего сложного…
Резисторы в шине данных взяты меньшего номинала, чем были. Зачем? Чтоб ярче светили светодиоды. Поскольку индикация динамическая, то каждый индикатор работает только 1/4 общего времени работы схемы. Глаз это воспринимает как пропорциональное уменьшение яркости свечения (т.е. – тоже в 4 раза.). Чтобы как-то компенсировать этот недостаток, на светодиоды подается завышенный ток (больше максимально допустимого). В статическом режиме этот ток может причинить светодиодам вред. Однако в динамическом режиме, кратковременные воздействия тока не столь фатальны.
Ну вот, вроде все. Теперь пишем программулину дальше.
.cseg .org 0 rjmp RESET ; Reset Handler rjmp EXT_INT0 ; IRQ0 Handler rjmp EXT_INT1 ; IRQ1 Handler rjmp TIM_CAPT1 ; Timer1 Capture Handler rjmp TIM_COMP1 ; Timer1 Compare Handler rjmp TIM_OVF1 ; Timer1 Overflow Handler rjmp TIM_OVF0 ; Timer0 Overflow Handler rjmp UART_RXC ; UART RX Complete Handler rjmp UART_DRE ; UDR Empty Handler rjmp UART_TXC ; UART TX Complete Handler rjmp ANA_COMP ; Analog Comparator Handler EXT_INT0 : ret EXT_INT1 : ret TIM_CAPT1 : ret TIM_OVF0 : ret TIM_OVF1 : ret UART_RXC : ret UART_DRE : ret UART_TXC : ret ANA_COMP : ret TIM_COMP1 : ret reset: ldi Temp1,RamEnd ;инициализация стека out SPL,Temp1 cli ldi Temp,0b11111111 ;настройка портов out ddrb,Temp ldi Temp,0b00001111 out ddrd,Temp ldi Temp,4 sts Digit ,Temp ;загрузка начальных сначений ldi Temp,3 sts Digit+1,Temp ldi Temp,2 sts Digit+2,Temp ldi Temp,1 sts Digit+3,Temp ;********************************************************* ;MAIN ;********************************************************* IndicCycle: rcall Display ;цикл индикации rjmp IndicCycle ;********************************************************* Display: ;последовательный вывод на индикацию содержимого ;переменной Digit lds Temp1,Digit ;загружаем 0-ю ячейку ldi Temp,0b00001110 ;активируем 0-й разряд ;индикации out PortD,Temp rcall Decoder ;вызываем 7-сегм. декодер out PortB,Temp1 ;выводим значение в порт rcall Delay1 ;ждем lds Temp1,Digit+1 ;и .т.д ldi Temp,0b00001101 out PortD,Temp rcall Decoder out PortB,Temp1 rcall Delay1 lds Temp1,Digit+2 ldi Temp,0b00001011 out PortD,Temp rcall Decoder out PortB,Temp1 rcall Delay1 lds Temp1,Digit+3 ldi Temp,0b00000111 out PortD,Temp rcall Decoder out PortB,Temp1 rcall Delay1 ret ;********************************************************* Decoder: ;преобразование двоичного числа ;в код 7-сегментного индикатора ldi ZL,Low(DcMatrix*2) ;инициализация массива ldi ZH,High(DcMatrix*2) ldi Temp2,0 ;прибавление переменной add ZL,Temp1 ;к 0-му адресу массива adc ZH,Temp2 lpm ;загрузка значения mov Temp1,r0 ret DcMatrix: ;массив - таблица истинности декодера ; hgfedcba hgfedcba .db 0b00111111,0b00000110 ;0,1 .db 0b01011011,0b01001111 ;2,3 .db 0b01100110,0b01101101 ;4,5 .db 0b01111101,0b00000111 ;6,7 .db 0b01111111,0b01101111 ;8,9 ;********************************************************* Delay1: ;цикл задержки push Temp1 push Temp2 ldi Temp1,0 ldi Temp2,50 d11: dec Temp1 brne d11 dec Temp2 brne d11 pop Temp2 pop Temp1 ret Очень внимательно читаем программу.
Сначала мы настраиваем прерывания, порты и стек. Это стандартно.
Затем, мы записываем в переменную Digit число 1234.
Потом мы выходим в главный цикл программы. из этого цикла вызывается функция Display , которая, собственно, и занимается динамическим выведением на индикацию числа из переменной Digit . Функция состоит из 4-х похожих кусков. Эти куски различаются лишь номером вызываемой ячейки Digit и разрядом текущего индикатора.
Из каждого кусочка вызывается функция Decoder – 7-сегментный декодер. Этот декодер преобразует значение из ячейки Digit в код 7-сегментного индикатора, и передает этот код обратно функции Display , которая выводит его на индикацию.
Вот так, в общих чертах, все просто и понятно.
Далее мы сделаем из этого дела секундомер.






Рекомендуемый контент




Copyright © 2010-2017 housea.ru. Контакты: info@housea.ru При использовании материалов веб-сайта Домашнее Радио, гиперссылка на источник обязательна.