[pic12f675] Этап 4. Вывод информации на LCD-дисплей

В прошлый раз я не зря так подробно рассказывал о битах и байтах. Сейчас эти сведения пригодятся нам для вывода информации на жидкокристаллический индикатор. Дисплей WH1602A-YGH-CTK снабжён знакогенератором S6B0066U. Буквы CT в его названии указывают на способность отображать кириллические символы, цифра 16 - количество знакомест в строке, цифра 2 - количество строк. Y значит "жёлто-зелёный фон", а G - цвет знаков: серый. У него 16 пинов, все они подробно описаны в даташите. Восемь из этих ножек образуют шину данных - по одному биту на каждый пин. Итак, один байт должен прийти к дисплею по 8 линиям связи. Используемый нами МК имеет всего 6 портов ввода-вывода, поэтому волей-неволей придётся подключать LCD через сдвиговый регистр.

Информация
Компилятор SDCC, программатор EXTRA-PIC, программа-программатор IC-Prog. Схема собиралась на беспаечной макетной плате. Настройки битов конфигурации, равно как и весь процесс компиляции и прошивки МК, аналогичны первому этапу.
Даташит на ЖКИ WH1602A-YGH-CTK
Про команды управления ЖКИ можно почитать здесь и здесь.

Радиокомпоненты и приборы
- микроконтроллер pic12f675
- регистр сдвига 74HC595
- ЖКИ Winstar WH1602A-YGH-CTK (1602H REV.0)
- источник стабилизированного питания напряжением +5 В

Электрическая принципиальная схемаЭта схема отличается от предыдущей только блоком индикации, шина данных которого подключена к выводам сдвигового регистра (DB0...DB7 -> Q0...Q7 соответственно), а управляющие линии занимают порты GP4 и GP5 МК.

Исходный код прошивки на языке C
Файл pic.c, компилятор SDCC

#include <pic12f675.h>

#define SHCP GPIO0
#define DS GPIO1
#define STCP GPIO2
#define RS GPIO4 //Сигналы RS и E для ЖКИ будут отправляться по пинам GP4
#define E GPIO5 //и GP5 соответственно

//Функция задержки, в мкс. Исходит из того, что один такт этого МК при 4 МГц выполняется за 200 нс, согласно даташиту.
void __delay_us(unsigned char t){
while(t--){
//Ассемблерная вставка: 5 холостых тактов
__asm
NOP
NOP
NOP
NOP
NOP
__endasm;
}
}

//Функция задержки в мс
void __delay_ms(unsigned char m){
while(m--){
__delay_us(1000);
}
}

//Функция отправки байта в ЖКИ через сдвиговый регистр
void lcd_write(unsigned char c){
int i;
STCP = 0;
for(i=7;i>=0;i--){
DS = (c >> i) & 1;
SHCP = 0;
SHCP = 1;
}
STCP = 1;
E = 1;
__delay_us(200);
E = 0;
}

//Инициализация ЖКИ
void lcd_init(){
__delay_ms(15);

RS = 0; //Далее будет команда
lcd_write(0b00111100); //Шина 8 бит, 2 строки, 5х8 точек - Function Set
__delay_ms(40);

RS = 0;
lcd_write(0b00000001); //Очистка экрана - Clear Display
__delay_ms(2);

RS = 0;
lcd_write(0b00000110); //Инкремент - Entry Mode Set
__delay_ms(40);

RS = 0;
lcd_write(0b00001100); //Включили дисплей и курсор, мигание курсора отключили - Display ON/OFF Control
__delay_ms(40);

RS = 0;
lcd_write(0b10000000); //Очистили дисплей - Set DDRAM Address
__delay_ms(2);
}

main(){
OSCCAL = 0x80; //Установить внутренний осциллятор на среднюю частоту
TRISIO = 0b11001000; //Установить GPIO0, GPIO1, GPIO2, GPIO4, GPIO5 на выход, остальные - на вход
GPIO = 0b00000000; //На всех GPIO установить логический ноль
CMCON = 0b00000111; //Отключить компаратор
ADCON0 = 0b00000000; //Отключить АЦП
ANSEL = 0b00000000; //Отключить аналоговые входы, все ножки установить как цифровые входы-выходы

lcd_init();

RS = 1; //Далее будет символ
lcd_write(0b01010010); //R

RS = 1;
lcd_write(0b01111000); //x

RS = 1;
lcd_write(0b01001100); //L

RS = 1;
lcd_write(0b01100001); //a

RS = 1;
lcd_write(0b01100010); //b

RS = 1;
lcd_write(0b00101110); //.

RS = 1;
lcd_write(0b01001111); //O

RS = 1;
lcd_write(0b01110010); //r

RS = 1;
lcd_write(0b01100111); //g

//Входим в бесконечный цикл, чтобы не выйти из подпрограммы и не погасить экран
while(1){
__asm
NOP
__endasm;
}
}

Тонкости
Переменный резистор 10К, подключенный к ножке #3 дисплея, регулирует яркость/контрастность символов. После включения прибора следует отрегулировать этот подстроечник так, чтобы стали видны символы. Ножки 15 и 16 ЖКИ - подсветка. На них нужно подать 4 В.

Бинарные коды символов приведены в таблице в даташите. Латинские буквы и цифры допустимо писать напрямую (lcd_write('R'); lcd_write('5');), а вот русские буквы придётся записывать только двоичным кодом.

Примечание. Для моделирования этого ЖКИ в Proteus следует использовать модель LM016L. Для русификации этой модели нужно в папке MODELS заменить LCDALPHA.DLL, например, на эту версию (для Proteus 7.7).

Фотографии работающего устройства приведены ниже.
2013-11-29