Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Удаленная работа
Помощь проекту


Трёхпроводное подключение LCD к микроконтроллеру PIC: драйвер для CCS C


15 000 000 даташитовпоиск по параметрам · аналоги · заводские PDFНайти даташит →

Знакомый по HD44780 текстовый индикатор можно подключить к микроконтроллеру всего тремя выводами, если поставить между ними обычный сдвиговый регистр. Готовый драйвер для компилятора CCS PIC C берёт всю работу с последовательной посылкой на себя.

Зачем нужен трёхпроводный интерфейс

Даже в экономичном четырёхбитном режиме символьный LCD требует от микроконтроллера как минимум шесть линий: четыре линии данных, линия RS и линия разрешения E. Для многих корпусов это неприемлемо — например, у семейства PIC12F просто нет такого количества свободных выводов. Значит, нужен способ уменьшить число задействованных ног.

Решение простое: данные передаются к индикатору последовательно, через сдвиговый регистр с последовательным входом и параллельным выходом. Микроконтроллер работает с регистром всего по двум линиям — линии данных и линии тактирования, а регистр уже раскладывает принятые биты по параллельным выводам индикатора. Третья линия — разрешение E — идёт от микроконтроллера к LCD напрямую. Итого три вывода вместо шести.

Подойдёт любой сдвиговый регистр типа «последовательный вход — параллельный выход»: 74HC595, 74HC164, CD4094 (он же HEF4094) и аналогичные.

Схемы включения

Аппаратная часть предельно проста — кроме индикатора и микроконтроллера в ней есть только сдвиговый регистр. Ниже приведены три варианта соединения, отличающиеся типом применённой микросхемы.

Вариант на 74HC595:

3-wire LCD using 74HC595 shift register
Нажмите для увеличения (1024x609)

Вариант на 74HC164:

3-wire LCD using 74HC164 shift register
Нажмите для увеличения (1024x609)

Вариант на HEF4094 (CD4094, 74HC4094):

3-wire LCD using HEF4094 shift register
Нажмите для увеличения (1024x613)

Исходный код драйвера

Ниже полный текст драйвера для компилятора CCS PIC C, рассчитанного на контроллеры индикаторов, совместимые с HD44780. Драйвер проверен на индикаторах 1602 (16x2) и 2004 (20x4) при тактовых частотах кварца 8 МГц и 48 МГц.

// 3-Wire LCD driver for CCS PIC C compiler (for HD44780 compliant controllers)

#define LCD_FIRST_ROW          0x80
#define LCD_SECOND_ROW         0xC0
#define LCD_THIRD_ROW          0x94
#define LCD_FOURTH_ROW         0xD4
#define LCD_CLEAR              0x01
#define LCD_RETURN_HOME        0x02
#define LCD_CURSOR_OFF         0x0C
#define LCD_UNDERLINE_ON       0x0E
#define LCD_BLINK_CURSOR_ON    0x0F
#define LCD_MOVE_CURSOR_LEFT   0x10
#define LCD_MOVE_CURSOR_RIGHT  0x14
#define LCD_TURN_ON            0x0C
#define LCD_TURN_OFF           0x08
#define LCD_SHIFT_LEFT         0x18
#define LCD_SHIFT_RIGHT        0x1E

short RS;

void lcd_write_nibble(unsigned int8 n)
{
  unsigned int8 i;

  output_low(LCD_CLOCK_PIN);
  output_low(LCD_EN_PIN);

  for(i = 8; i > 0; i = i >> 1)
  {
    if(n & i)
      output_high(LCD_DATA_PIN);
    else
      output_low(LCD_DATA_PIN);

    Delay_us(10);
    output_high(LCD_clock_PIN);
    Delay_us(10);
    output_low(LCD_clock_PIN);
  }

  if(RS)
    output_high(LCD_DATA_PIN);
  else
    output_low(LCD_DATA_PIN);

  for(i = 0; i < 2; i++)
  {
    Delay_us(10);
    output_high(LCD_clock_PIN);
    Delay_us(10);
    output_low(LCD_clock_PIN);
  }

  output_high(LCD_EN_PIN);
  delay_us(2);
  output_low(LCD_EN_PIN);
}

void LCD_Cmd(unsigned int8 Command)
{
  RS = 0;
  lcd_write_nibble(Command >> 4);
  lcd_write_nibble(Command & 0x0F);

  if((Command == 0x0C) || (Command == 0x01) || (Command == 0x0E) ||
     (Command == 0x0F) || (Command == 0x10) || (Command == 0x1E) ||
     (Command == 0x18) || (Command == 0x08) || (Command == 0x14) ||
     (Command == 0x02))
    Delay_ms(50);
}

void LCD_GOTO(unsigned int8 col, unsigned int8 row)
{
  switch(row)
  {
    case 1:
      LCD_Cmd(0x80 + col - 1);
      break;
    case 2:
      LCD_Cmd(0xC0 + col - 1);
      break;
    case 3:
      LCD_Cmd(0x94 + col - 1);
      break;
    case 4:
      LCD_Cmd(0xD4 + col - 1);
      break;
  }
}

void LCD_Out(unsigned int8 LCD_Char)
{
  RS = 1;
  lcd_write_nibble(LCD_Char >> 4);
  delay_us(10);
  lcd_write_nibble(LCD_Char & 0x0F);
  break;
}

void LCD_Initialize()
{
  RS = 0;
  output_low(LCD_DATA_PIN);
  output_low(LCD_CLOCK_PIN);
  output_low(LCD_EN_PIN);
  output_drive(LCD_DATA_PIN);
  output_drive(LCD_CLOCK_PIN);
  output_drive(LCD_EN_PIN);

  delay_ms(40);
  lcd_Cmd(3);
  delay_ms(5);
  lcd_Cmd(3);
  delay_ms(5);
  lcd_Cmd(3);
  delay_ms(5);
  lcd_Cmd(2);
  delay_ms(5);
  lcd_Cmd(0x28);
  delay_ms(50);
  lcd_Cmd(0x0C);
  delay_ms(50);
  lcd_Cmd(0x06);
  delay_ms(50);
  lcd_Cmd(0x0C);
  delay_ms(50);
}

Драйвер распространяется и отдельным файлом 3WireLCD.c, который достаточно положить в папку проекта или в каталог драйверов CCS PIC C.

Как драйвер формирует посылку

Вся низкоуровневая работа сосредоточена в функции lcd_write_nibble(). Перед началом посылки линии тактирования и разрешения сбрасываются в ноль. Затем цикл for(i = 8; i > 0; i = i >> 1) перебирает биты полубайта от старшего к младшему: маска начинается с восьмёрки и на каждом шаге сдвигается вправо. Проверенный бит выставляется на линии данных, после чего формируется тактовый импульс — пауза 10 мкс, подъём линии тактирования, ещё 10 мкс и спад. Так в регистр уходят четыре бита данных.

Дальше на линию данных выставляется состояние переменной RS (признак «команда/данные») и выдаются ещё два тактовых импульса — этим бит RS дотесняется до того выхода регистра, который соединён с одноимённым входом индикатора. Только после этого микроконтроллер собственной ногой формирует стробирующий импульс на линии E: подъём, задержка 2 мкс, спад. По его спаду индикатор защёлкивает выставленный регистром полубайт.

Байт передаётся двумя такими посылками. Функция LCD_Cmd() сбрасывает RS в ноль и отправляет сначала старший полубайт (Command >> 4), затем младший (Command & 0x0F). Часть команд выполняется контроллером индикатора заметно дольше остальных, поэтому для списка «медленных» кодов (0x0C, 0x01, 0x0E, 0x0F, 0x10, 0x1E, 0x18, 0x08, 0x14, 0x02) добавлена пауза 50 мс. Функция LCD_Out() устроена так же, но с RS = 1, а между полубайтами вставлена задержка 10 мкс.

Позиционирование в LCD_GOTO() сделано через базовые адреса строк: к 0x80, 0xC0, 0x94 или 0xD4 прибавляется номер колонки минус единица.

Инициализация LCD_Initialize() начинается с перевода всех трёх линий в ноль и настройки их на вывод (output_drive). После паузы 40 мс идёт классическая для HD44780 стартовая последовательность: три посылки кода 3 с интервалом 5 мс, затем код 2 — перевод в четырёхбитный режим. Дальше 0x28 задаёт формат, 0x0C включает дисплей без курсора, 0x06 — автоинкремент позиции, и завершающий 0x0C; каждая из этих команд отделена паузой 50 мс.

Подключение драйвера к проекту

Файл драйвера подключается обычной директивой:

#include <3WireLCD.c>

До подключения необходимо объявить, на каких выводах микроконтроллера сидят линия данных, линия тактирования и линия разрешения. Например, для данных на RB0, тактирования на RB1 и разрешения на RB2:

#define LCD_DATA_PIN   PIN_B0
#define LCD_CLOCK_PIN  PIN_B1
#define LCD_EN_PIN     PIN_B2

Набор доступных функций невелик:

  • LCD_Initialize(); — должна вызываться до любой другой функции драйвера.
  • LCD_GOTO(unsigned int8 col, unsigned int8 row); — установка позиции вывода. Левый верхний угол — это 1,1, а первая позиция второй строки — 1,2.
  • LCD_Out(unsigned int8 LCD_Char); — вывод символа на индикатор.
  • LCD_Cmd(unsigned int8 Command); — отправка команды индикатору.

Команды индикатора

С функцией отправки команд используются готовые константы, объявленные в начале драйвера (пример вызова: LCD_Com(LCD_CLEAR);):

  • LCD_FIRST_ROW — перевести курсор в 1-ю строку.
  • LCD_SECOND_ROW — перевести курсор во 2-ю строку.
  • LCD_THIRD_ROW — перевести курсор в 3-ю строку.
  • LCD_FOURTH_ROW — перевести курсор в 4-ю строку.
  • LCD_CLEAR — очистить дисплей.
  • LCD_RETURN_HOME — вернуть курсор в исходную позицию и вернуть сдвинутое изображение на место; содержимое display data RAM при этом не затрагивается.
  • LCD_CURSOR_OFF — выключить курсор.
  • LCD_UNDERLINE_ON — включить курсор-подчёркивание.
  • LCD_BLINK_CURSOR_ON — включить мигающий курсор.
  • LCD_MOVE_CURSOR_LEFT — сдвинуть курсор влево без изменения display data RAM.
  • LCD_MOVE_CURSOR_RIGHT — сдвинуть курсор вправо без изменения display data RAM.
  • LCD_TURN_ON — включить дисплей.
  • LCD_TURN_OFF — выключить дисплей.
  • LCD_SHIFT_LEFT — сдвинуть изображение влево без изменения display data RAM.
  • LCD_SHIFT_RIGHT — сдвинуть изображение вправо без изменения display data RAM.

Похожие материалы на сайте

Форум радиолюбителейтысячи решённых схем, вопросов и советов — спроси и найдиНа форум →


Реклама на сайте

KAZUS.RUN — 15 000 000 даташитов, поиск по электронным компонентам




© 2003—2026 «KAZUS.RUN - Электронный портал»