В общем появился у меня тут с телефона вумного (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-й символ градусаКод: Выделить всё
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,gstep = 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 на ЖКИ:
Предупреждаю сразу, никакую оптимизацию не проводил, т.к. это маленькая часть сложного устройства, когда поблочно со всеми частями разберусь, потом уже в кучу соберу, и буду думать в какую сторону оптимизировать.
