Application Note PCA85134. Final.

Тихим сапом мы добрались к финальной части трилогии. Я надеюсь, что в результате изучения двух первых статей у читателя сложились вполне определённые представления о принципах работы PCA85134, макет собран и отлажен. Самое время заняться выводом осмысленной информации…
Рабочая программная часть.
В первой статье по применению PCA85134, в её завершении мы получили таблицу соответствия разрядов байтов видео ОЗУ сегментам ЖКИ. Эта таблица сыграет ключевую роль в разработке алгоритма вывода символов. Приведём её к такому виду (V[i] — байты массива видео ОЗУ, i=(0…7)):
Table_segmentsт.е. мы упорядочили наборы сегментов для каждого знакоместа двух индикаторов. Теперь наглядно и очевидно, что для отображения,  допустим, сегмента d 2-го знакоместа 2-го индикатора нужно в 6-м байте массива видео ОЗУ, 5-й разряд установить в 1.
Как мы увидели, друзья, критерий удобства разводки печатной платы, который для меня являлся приоритетным, привел к разбросу кодировок символов случайным образом 🙁 Есть знакоместа, где в формировании символов присутствуют разные разряды четырёх байтов ! Сей факт, безусловно, печален, но не смертелен.
Чтобы было легче разговаривать качаем архив с исходником и смотрим по нему, вникая в комментарии.
Обдумывая принцип обновления информации на экране ЖКИ я пришёл к выводу, что лучше её обновлять сразу всем массивом (8 байт) видео ОЗУ. Конечно, будут такие моменты работы, когда во всей отображаемой информации изменится только один сегмент, но при таком принципе необходимо вводить дополнительные флаги-признаки обновления. К тому же такие обновления нужно постоянно анализировать и адресовать отдельно каждый сегмент, что «сожрёт» кучу времени и ресурсов. Гораздо проще во всех отношениях писать заново массив видео ОЗУ и обновлять его с нужной периодичностью — хоть по таймеру, хоть по событию. Именно такой подход я и реализовал.
Теперь о кодировке выводимых символов. Возвращаемся к таблице вверху статьи… Самая простая реализация кодировки символов, что приходит в голову, выглядит, в оформлении вывода каждой цифры через switch — case. Т.е. анализируем в switch отображаемый символ и в case лепим его из кучи операторов
V[необходимый] |= 1<< сколько надо; и V[необходимый] &= ~(1<< сколько надо);
И программа, стопудово, будет работать на МК с памятью, ну, где-то 2к и больше. Однако это не наш подход, и в распоряжении ATtiny13A со своим 1 к . Многострадальную таблицу вверху статьи я записал во флеш контроллера, дабы не пользовать драгоценное ОЗУ следующим образом:

const char aa[] PROGMEM= {0x33,0x23,0x37,0x41,0x55,0x47};//Массивы в которых хранятся
const char bb[] PROGMEM= {0x34,0x22,0x36,0x40,0x44,0x30};//закодированные байты
const char cc[] PROGMEM= {0x27,0x16,0x02,0x62,0x51,0x77};//распределения выводов
const char dd[] PROGMEM= {0x26,0x15,0x01,0x61,0x65,0x54};//PCA85134 сегментам ЖКИ.
const char ee[] PROGMEM= {0x25,0x14,0x00,0x60,0x64,0x53};//первая тетрада - номер байта в массиве видео ОЗУ
const char ff[] PROGMEM= {0x32,0x24,0x20,0x42,0x56,0x46};//вторая тетрада - номер разряда в этом байте
const char gg[] PROGMEM= {0x31,0x35,0x21,0x43,0x57,0x45};//аа - байты соответствия сегмента а знакоместам 0 - 5
const char hh[] PROGMEM= {0x10,0x17,0xFF,0x63,0x52,0xFF};//bb - байты соответствия сегмента b ... и т.д.

Массивов восемь — для восьми сегментов (строки таблицы). Элементов в массиве шесть — для каждого знакоместа (столбцы таблицы). Внимательно взглянув на эти массивы вы, конечно же, друзья, увидите, что каждый их элемент в своей старшей тетраде содержит номер байта видео ОЗУ, а в младшей тетраде — разряд в этом байте, который соответствует конкретному сегменту на конкретном знакоместе.
Далее создаём массив с указателями на строки, в которых закодированы сегменты (т.е. на массивы aa, bb, cc, и т.д., полученные из таблицы). Этот массив тоже размещаем в программной памяти микроконтроллера.

PGM_P segments [] PROGMEM= {aa,bb,cc,dd,ee,ff,gg,hh};//массив указателей на строки во флеше с кодами сегментов

Следующим шагом будет кодировка необходимых для вывода символов, в нашем случае цифр 0-9.

const unsigned char kod_cifra[] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6};//коды цифр 0-9 при a-7разряд b-6 c-5...h-8

Кодировка осуществлялась при соответствии сегмента а — 7-му разряду байта, b — 6-му разряду,  c — 5-му и т.д.
Ну и, наконец мы подошли к самой главной цели поставленной задачи — выводу символа по адресу знакоместа. Функция представлена ниже:

//Функция записи отображаемой цифры на нужном знакоместе - по сути это заполнение массива видео ОЗУ
void set_number (unsigned char n, unsigned int p)//n - number цифра (0-9), p - position знакоместо (0-5)
{
	unsigned char k,kod_seg;//счётчик цикла, код сегмента (значения массивов aa, bb, и т.д)
 
	for (k = 0; k < 8; k++)//в цикле 0-7 т.е. для всех байт видео ОЗУ    
    { 
	    kod_seg = (pgm_read_byte(pgm_read_word(&(segments[k]))+p));//вычисляем текущий код сегмента 
        if(0x01 &amp; (kod_cifra[n] >> (7-k)))//если разряд кода цифры = 1
        {  
		    Video_RAM[kod_seg >> 4] |= 1 < < (kod_seg & 0x0F);//на его место в байте видео ОЗУ записываем единицу
		}
 
	    else //если разряд кода цифры = 0
		{
		    Video_RAM[kod_seg >> 4] &= ~(1 < < (kod_seg & 0x0F));//на его место в байте видео ОЗУ записываем ноль
		}      
    }
}

Самое сложное, что осталось неразжёванным в работе этой функции — это извлечение кода сегмента, т.е. работа через указатели. Ну этот момент нужно читать в учебниках по Си.
Оставшиеся в исходнике функции я объяснял в прошлой статье. Главная функция в главном цикле гоняет по кругу отображение всех цифр на всех знакоместах. После прогона мы окончательно убеждаемся в правильном определении соответствия выводов управления сегментами самим сегментам и в правильности подхода. Ну и короткий видяшник о работе:

Исходя из приведённой информации, друзья, можно построить универсальный индикатор. Все функции для этой реализации я предоставил. Памяти в МК осталось достаточно — около 12 %. Кроме того можно закомментировать в файле I2C.с неиспользуемые функции типа void i2mack (void); void i2nack (void); unsigned char i2read (void); — останется свободным уже около 25 %. Т.е. простор для творчества огромный. Когда подойдёте к финальному этапу освоения PCA85134, можно будет поэкспериментировать с установкой мигания, других банков памяти, других режимов работы и пр..
Всего хорошего, друзья! Удачи вам и успехов!

Запись опубликована в рубрике Разное с метками , , , . Добавьте в закладки постоянную ссылку.

4 комментария: Application Note PCA85134. Final.

  1. Вася говорит:

    Здесь был вася 🙂

  2. s_black говорит:

    Молодца! Отметился.

  3. Сергей говорит:

    Спасибо за отличную статью, все толково и доходчиво расписано. Всем хорош этот PCA за исключением потреблямого тока. Сам драйвер согласно ДШ кушает 8 мкА через пин VDD. Это еще терпимо, но 24 мкА для блока управлния ЖКИ через пин VLCD не в какие ворота не лезет. Дело в том, что для формирования уровней напряжений ЖКИ в мультиплексном режим в PCA просто используется резистивный делитель. Отсюда и токопотребление. В более продвинутых ЖКИ драиверах для этой цели используется делитель на переключаемых конденсаторах и токопотребление таким образом снижается буквально на порядок. Другой крупный недостаток — отсутствие бустера для стабилизации питающих напряжний ЖКИ (значит и контраста) по мере разряда батареи.

  4. s_black говорит:

    Ну, для моего случая (я делал этот дисплей для индикации I, U в блоке питания Светозарова) потребление в микроамперах некритично, поэтому я и не заморачивался.

Добавить комментарий

Ваш e-mail не будет опубликован.