Я уже писал о работе с символьным ЖК индикатором на stm32 микроконтроллерах. Та статья получилась очень обзорной да и работа велась по восьмибитной шине. Таким образом я предлагаю вам бегло ознакомиться с предыдущей статьей, а уже потом перейти к этой.
Все дисплеи на основе контроллера HD44780 (а на другом я дисплея пока не видел) могут работать в режиме четырехбитной шины. В таком режиме работы байт (8 бит) передается тетрадами (то есть частями по 4 бита), что экономит нам 4 ножки контроллера, слегка при этом увеличивая время обращения к дисплею.
Подключение выполнено следующим образом:
Как и в прошлой статье, не будем считывать данные с дисплея, поэтому RW соединяем с землей.
Для инициализации дисплея в 4битном режиме необходимо изменить посылаемые комбинации при инициализации. Посылаем:
0x30 0x30 0x28
в восьмибитном режиме. Первые комбинации посылать потетрадно не нужно! Все последующие же нужно дробить на 2 части. После данных комбинаций шлются обычные настройки дисплея.
Я решил определить несколько макросов для более удобной работы:
#define RS_ENABLE PORTD.0 = 1; #define RS_DISABLE PORTD.0 = 0; #define E_ENABLE PORTD.1 = 1; #define E_DISABLE PORTD.1 = 0; #define LCD_PORT PORTD
Я работаю в AVR CodeVision, если вы нет, вам их придется немного изменить используя операции сдвигов.
Фунция для оправки тетрады:
void lcd_write_nibble(int data) { LCD_PORT |= data; E_ENABLE; delay_ms(20); E_DISABLE; LCD_PORT &= ~(data); }
Тут мы устанавливаем данные в порт, затем делаем сигнал E активным, ждем, выключаем E и очищаем шину от наших данных.
Далее рассмотрим функцию посылки байта потетрадно:
void lcd_write_data(int data) { lcd_write_nibble(data & 0xF0); // старший полубайт lcd_write_nibble(data << 4); //младший полубайт }
Из-за того, что дисплей подключен к старшим выводам порта контроллера. Необходимо сдвинуть младший полубайт на 4 бита влево. По сути мы передаем в порт тетраду сдвинутую на 4 влево каждый раз из-за специфики функции отправки тетрады.
Функция инициализации дисплея:
void lcd_init() { RS_DISABLE; // rs = 0 delay_ms(200); lcd_write_nibble(0x30); delay_ms(50); lcd_write_nibble(0x30); delay_ms(50); lcd_write_nibble(0x28); delay_ms(20); lcd_write_data(0x08); // полное выключение дисплея delay_ms(20); lcd_write_data(0x01); // очистка дисплея delay_ms(20); lcd_write_data(0x06); // сдвиг курсора вправо delay_ms(20); lcd_write_data(0x0D); // включение дисплея delay_ms(20); RS_ENABLE; //rs = 1 }
Функция для отправки строки:
void lcd_write_str(char*str) { do { lcd_write_data(*str); }while(*++str); }
Функция отправки команды:
void lcd_write_cmd(int cmd) { RS_DISABLE; lcd_write_data(cmd); RS_ENABLE; }
Функция перемещения курсора:
void lcd_set_cursor(int line,int pos) { pos |= 0b10000000; if (line == 1) { pos += 0x40; } lcd_write_cmd(pos); }
Функция main для вызова всего вышеуказанного:
void main(void) { // настройка порта DDRD=0xFF; PORTD=0x00; lcd_init(); lcd_write_str("HELLO!"); lcd_set_cursor(1,1); lcd_write_str("HELLO28!"); while (1) { // Place your code here } }
Как видите работа с дисплеем по 4ех битной шине усложнила наш код всего на одну функцию, но дала четыре свободных ножки.