Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Тема закрыта

Подключение пассивного мультиплексного ЖКИ к ATmega16A

Сб июн 09, 2012 23:56:17

МяВ! (ну в смысле - хай!)
В общем появился у меня тут с телефона вумного (Panasonic какой-то) ЖКИ вот такой:
Изображение
Там 12 семисегментов, без точек, но со специконками всякими.
Долго я его рассматривал, никак понять не мог как им управлять, тыкал маленьким напряжением (даже наводок хватает), там по куче сегментов сразу загоралось, думал непонятная хреновина какая-то, но все-таки решил разобраться, полез в наш великий и могучий... интернет...
А там сильно-то ничего конкретного не нашел, все как-то не очень понятно. Например тут: http://pro-radio.ru/it-works/3458/ есть описание как управлять мультиплексным ЖКИ, но что-то я там ничего не понял, кроме осциллограмм, которые надо организовать на общих электродах (которых у моего ЖКИ оказалось 4). Потом конечно я понял, о чем там еще пишут, когда уже сам разобрался :-)
Более-менее просветление в голове появилось, когда я тут http://ru-radio-electr.livejournal.com/ ... 2#t6242832 прочитал, от stp1973 такое объяснение обращения с мультиплексными ЖКИ: "... питаем МК 3-мя вольтами, линии портов, предназначенные для общих электродов, подтягиваем делителями из 100-ком резиков к половине питания, дальше бросаем z-состояние на все общие, кроме одного. Его на пару миллисекунд подтягиваем к плюсу, при этом неактивные сегменты тащим туда же, активные - в минус. В следующие пару миллисекунд всё инвертируем. Дальше бросаем его в z и берёмся за следующий общий..."
В общем может кому пригодится - опишу как у меня это заработало с МК ATmega16A.
Первое, что я сделал - изучил какие сегменты к каким ногам подцеплены, можно батарейкой, или контроллером в режиме отладки попадавать на все ноги 0, а на одну по порядку от начала, до конца единицу. Будут загораться разные комбинации сегментов, зарисовал их в такой вот файлик, он мне потом оооочень пригодился.
Изображение
Ног МК хватало тока-тока для его 28 выводов (вычесть конечно нужно ноги для отладчика JTAG), я уже даже думал бросить эту затею, думаю нафик мне нужен ЖКИ, под который отдельный МК надо ставить, или бОльший покупать. Но потом мне пришла в голову мысль, что где-то валялись у меня регистры сдвига (далее - с Вашего позволения - шифтеры) 74HC595, которые (4 штуки) соединив последовательно можно получить 4х8=32 вывода, с произвольным состоянием, управляемые всего тремя портами МК (DS (14-я нога шифтеров), SHCP (11-я) и STCP (12-я)). Последовательно они соединяются через выводs DS и Q7S на предыдущем. Остальные управляющие все в параллель - SHCP и STCP на МК, OE на ноль, MR на питание. Я запланировал, что выводы знакомест ЖКИ у меня встанут на первые регистры, по порядку, начиная с Q0 первого регистра, заканчивая Q7 третьего, а первые два вывода ЖКИ COM0, COM1, и последние два COM2 и COM3 на последний шифтер, как показано ниже:
Изображение
Тут получается, что если на два соседних бита подать одинаковые сигналы, то будет и на COM-е такой же сигнал, а если разные – то будет средняя точка. Нарисовал в екселе это, чтоб вникнуть в последовательность битов, вот:
Изображение
Получается простая логика, что к общему содержимому 0b10101010 (или 0b01010101 – разницы большой нет) надо (через поразрядное ИЛИ) добавлять 1 через разряд, первые четыре шага мультиплексирования, а в остальные 4 все также, только конечный результат еще и весь инвертируется поразрядно (по сегментным кстати выводам аналогично). Таааак с COM-ами разобрались… поехали дальше…
Теперь надо разобраться что подавать на сегментные выводы. Вообще вывод информации я решил сделать через глобальный массив из 12 элементов, который по необходимости будет внутри программы периодически обновляться и процедурка вывода на ЖКИ (которую конечно стоит на таймер повешать и пусть она через прерывание дергается) будет этот массив «визуализировать». В массив решил заносить код символа, который по таблице будет переводиться в байт, содержащий биты зажигаемых сегментов (их как раз 8 получается). Для начала такая табличка перевода (задана массивом):
Код:
Char symb[14] =           //коды -> в сегменты
   {   0xfc,       //0
      0x60,       //1
      0xda,       //2
      0xf2,       //3
      0x66,       //4
      0xb6,       //5
      0xbe,       //6
      0xe0,       //7
      0xfe,       //8
      0xf6,       //9
      0x00,       //10-й элемент - пустота
      0x1e,       //11-й символ t
      0x9c,       //12-й символ С
      0xc6};      //13-й символ градуса

Далее надо понять при действии какого COM-a (и соответственно шага мультиплексирования) нам надо дергать ногу «полузнакоместа», а еще надо понять какое из «полузнакомест» дергать чтоб отобразить нужный сегмент, т.к. каждое знакоместо на две ноги разбито. Ничего умнее я не придумал, кроме как использовать маски вхождения в группы сегментов, соответственно надо задать в таблички маски принадлежности сегментов к отдельным линиям COM и к отдельным «полузнакоместам». Вот маски по COM-ам:
Код:
char mask[4] =    {0x0a,       //0-й - сегменты e,g
       0x30,       //1-й - сегменты c,d
       0x44,       //2-й - сегменты f,b
       0x81};      //3-й – сегмент  a и специконки

И маски по «полузнакоместам»:
Код:
char segmask[2] ={   0x1d,       //0-й - сегменты f,e,d,h
         0xe2};      //1-й - сегменты a,b,c,g

Далее я думаю будет проще прокоментировать код получившейся функции для вывода инфы из массива lcd на ЖКИ. Полный текст исходника приложил (Made in IAR). Тут разберу только сложные моменты, если что еще кому не понятно, могу в обсуждении подсказать.
step = StepMulti & 3; //выделяем два младших бита как номер шага – не стал писать для StepMulti всяких условий или ограничений (типа от 0 до 3), нафик, просто инкрементирую его в конце процедуры и тупо беру два бита как номер шага – и все тут.
inv = (StepMulti & 4)>>2; //выделяем 3-й бит как признак инверсии – все 8 шагов вместе с инверсией готово.
for (volatile int i=0; i<24; i++) //цикл по 24-ём битам
bytenumber = (24-i+7)>>3; //номер байта 3-2-1 (0-й под COM-ы – он тут не нужен)
bitnumber = ((23-i)%8); //номер бита в байте от 7 до 0 в каждом байте
specikon = (lcd[i>>1]>>7); //есть специконка – специконку решил сделать старшим битом в элементе массива lcd
code = symb[lcd[i>>1]] | specikon; //код символа по сегментам получаем из массива (младший бит - специконка)
code = code & segmask[i&1]; //выделение из кода сегмента тех сегментов которые соответствуют текущему «полузнакоместу» по маске
bit = !(mask[step] & code); //ну и маска текущего COM-a (шага), если остаток кода обрезанный «полузнакоместом» попадает в маску COM-a, то соответственно бит на ноге будет 0 (в противоположность COM-у, который будет в 1)
bit = bit << bitnumber; //сдвигаем полученный бит на нужное место
bytes[bytenumber] |= (bit); //и прилепляем его в байт
цикл повторяется по 24-рём битам. Затем когда они все сформировались в массив, надо его загнать в шифтеры, там еще в 0-й ячейке массива планировал заносить коды для COM, но т.к. там код получился из одной строчки, не стал его заполнять, а заполняю сразу байт во время задвигания в шифтеры:
if (i==0) {byte = (0x55 | (1<<(7-(step*2))));} //вот тут вот формируется байт для СОМ-ов, с бегущей единицей
DS = (inv) ? (!(byte&1)) : (byte&1); // в этом месте проверяется есть ли инверсия, т.е. на каком мы этапе мультиплексирования находимся 0-3 или 4-7, и для 4-7 идет инверсия всех данных и сегментов и СОМ. Дальше стробы сдвига и записи, и инкремент счетчика шагов – Все!
Вот заветные 0123456789 t на ЖКИ:
Изображение
Предупреждаю сразу, никакую оптимизацию не проводил, т.к. это маленькая часть сложного устройства, когда поблочно со всеми частями разберусь, потом уже в кучу соберу, и буду думать в какую сторону оптимизировать.
Вложения
main.c
Код на СИ
(4 KiB) Скачиваний: 205

Re: Подключение пассивного мультиплексного ЖКИ к ATmega16A

Пн июн 11, 2012 16:13:34

В этой статье я описал общий подход и немного теории по "пассивным" ))) ЖКИ, в.т.ч. как определять выводы сегментов. Здесь упор именно на мультиплексный режим - управление с помощью обычного, неспециализированного контроллера, и управление контроллером с драйвером ЖКИ. Успехов!

Re: Подключение пассивного мультиплексного ЖКИ к ATmega16A

Чт июн 14, 2012 03:51:51

Вот спасибо, почитал, стало более понятно, почему у меня контрастности нет. Почему-то эта статья в поиске мне не попадалась. Макетку правда уже разобрал, похоже проще будет приобрести МК со встроенным контроллером ЖКИ, а то действительно с такими индикаторами 4-х уровневое напряжение на всех выводах получать на обычном МК - извращение :-)
Тема закрыта