Печать

Использование библиотеки для работы с LCD HD44780

Автор: AntonChip Опубликовано . Опубликовано в Программирование на Си

Рейтинг:   / 26
ПлохоОтлично 

В этой статье я расскажу как с помощью достаточно распространенной библиотеки управлять LCD дисплеем на базе контроллера HD44780 и выводить на него информацию. Библиотека состоит из двух файлов lcd_lib.h и lcd_lib.c для использования с дисплеем подключенным по четырехбитной шине данных. В заголовочном файле прописываются настройки подключения дисплея к контроллеру, которые можно изменить по своему усмотрению, а также переменные и функции.

Ниже представлены базовые функции управления и вывода информации на LCD.

lcd_com – посылка команды в LCD

Пример:
lcd_com(0x01); // очистка дисплея
lcd_com(0x38); // интерфейс 8 бит 2 строки

lcd_dat – вывод одного символа в текущую позицию

Пример:
lcd_dat("U"); // вывод символа "U"
lcd_dat(0xB0); // вывод символа "Ю"(В соответствие с таблицей символов дисплея)

lcd_init – Инициализация LCD

Вот пример широко распространенной последовательности для инициализации LCD: 0x38, 0xOC, 0x06 .
0x38 устанавливает режим отображения 2-х строк с матрицей 5 х 8 точек и работу с 8-ми разрядной шиной данных;
0xOC включает отображение на экране ЖКИ-можуля, без отображения курсоров;
0x06 устанавливает режим автоматического перемещения курсора слева-направо после вывода каждого символа.

lcd_clr – очистка LCD

lcd_home – переводит курсор в начало

lcd_string – вывод строки указанной длинны в текущую позицию

Пример: lcd_string("TEST",4); // вывод строки TEST длиной 4 символа

lcd_gotoxy – перемещает курсор в указанную позицию

Пример: lcd_gotoxy(12, 1); // курсор в позиции тринадцатый разряд второй строки

copy_string_to_lcd – вывод строки из флеш-памяти в указанную позицию дисплея

Пример: copy_string_to_lcd("TEST",4,0); // вывод строки TEST в позицию пятый разряд первой строки

lcd_definechar – записывает пользовательское изображение символа в память дисплея

Чтобы вывести на экран дисплея собственный символ необходимо знать код символа, прописать этот код в памяти программ микроконтроллера (PROGMEM),  затем поместить его в свободную ячейку памяти LCD (CGRAM) и выводить его на экран при помощи функции lcd_dat().

Для программирования доступны 8 переопределяемых символов в режиме с матрицей 5х7 точек и 4 с матрицей 5х10 (в режиме 5х10 переопределяемые символы адресуются кодами DDRAM через один: 0x00, 0x02, 0x04, 0x06). Для кодирования матрицы используются горизонтально "уложенные" байты, пять младших битов которых несут информацию о рисунке (причем 1(единица) означает, что сегмент будет включен), 4-й разряд каждого из 8-ми (или 11-ти в режиме 5 х 10) байтов матрицы определяет левую колонку символа, а 0-й - правую. Старшие три бита не используются, равно как и старшие пять байтов, составляющих полную область матрицы символа (16 байтов) в режиме 5х10 (обратите внимание, что матрица программируемых символов допускает использование полной высоты строки (8 строчек для режима 5х7 и 11 строчек для режима 5х10), то есть можно размещать точки в области подчеркивающего курсора).

Создавать символ более удобно в двоичном формате, к примеру создадим символ прямоугольника, код будет таким:

const uint8_t pryamougolnik[] PROGMEM=
{
0b11111,
0b10001,
0b10001,
0b10001,
0b10001,
0b10001,
0b11111,
0b0
};

lcd_shift_right – перемещает изображение на указанное число символов вправо

lcd_shift_Left – перемещает изображение на указанное число символов влево

lcd_cursor_on – включает курсор подчеркивание

lcd_cursor_blink – включает мигающий курсор

lcd_cursor_off – выключает курсор

lcd_blank – отключает изображение, но не очищает

lcd_visible – включает изображение

lcd_cursor_left – перемещает курсор на указанное число символов влево

lcd_cursor_right – перемещает курсор на указанное число символов вправо

lcd_progress_bar - позволяет выводить на дисплей динамическую шкалу, об этой функции поговорим более подробней на практическом примере.

lcd_num_to_str - позволяет выводить на дисплей переменную до 4 разрядов

Пример: void lcd_num_to_str(ADC, 4); // Выводим переменную АЦП 4 разряда

Сделаем проект "Аналоговый вольтметр" в котором информация об измеренном напряжении будет выводится на экран в виде горизонтальной динамической шкалы. Измеряемое напряжение подается на вход ADC0, максимум 5В. без использования делителя. Используем для этого проекта микроконтроллер atmega8, который тактируется от внутреннего генератора частотой 8МГц. Дисплей подключаем по четырехбитной шине в соответствие с настройками из файла lcd_lib.h. При создании проекта в AVRSTUDIO копируем 2 файла библиотеки в папку нашего проекта, а в дереве проекта добавляем эти файлы(lcd_lib.c и lcd_lib.h).

За вывод динамической шкалы отвечает функция lcd_progress_bar(uint8_t progress, uint8_t maxprogress, uint8_t length), в зависимости от состояния переменных этой функции, шкала меняет свой уровень, progress - уровень от 0 до 255, maxprogress - максимальный уровень ограничивается числом от 0 до 255, length - длина шкалы от 0 до 16 ячеек(в зависимости от типа дисплея). Так как при максимальном напряжении на входе значение ADC равно 1024, делим это значение на 4 и присваиваем его переменной "u", а переменную "u" используем в функции вывода динамической шкалы void progress().

Полный текст программы выкладываю ниже:

//******Применение библиотек для работы с LCD HD44780*****
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "lcd_lib.h"

const uint8_t simbol_1[] PROGMEM= 
{0b00000,0b10001,0b01010,0b00100,0b01010,0b10001,0b00000,0b0};
const uint8_t simbol_2[] PROGMEM= 
{0b00100,0b00100,0b00100,0b11111,0b00100,0b00100,0b00100,0b0};

char u;

//********************************************************
void progress(void) // функция вывода шкалы
{
lcd_gotoxy(0, 0);
lcd_string("0......05......1",16);
lcd_gotoxy(0, 1);
lcd_progress_bar(u, 255, 16);
}

//********************************************************
int main(void)
{
/***Настройка АЦП***/ 
ADCSRA |= (1 << ADEN) //Включение АЦП
|(1 << ADPS1)|(1 << ADPS0);	// предделитель преобразователя на 8
ADMUX |= (0 << REFS1)|(0 << REFS0) // внешний ИОН
|(0 << MUX0)|(0 << MUX1)|(0 << MUX2)|(0 << MUX3); // вход PC0
_delay_ms(100);

lcd_init();// инициализация LCD
lcd_clr();// очистить LCD
_delay_ms(10);

lcd_definechar(simbol_1, 6); // определяем собств. символ 1
lcd_definechar(simbol_2, 7); // определяем собств. символ 2

for(char a=0; a<10; a++) // цикл приветствия
{
lcd_gotoxy(0, 0);
lcd_dat(6);
_delay_ms(100);
lcd_gotoxy(0, 0);
lcd_dat(7);
_delay_ms(100);
lcd_gotoxy(3, 0);
lcd_string("AЅa»oґoіГ№",10); // Аналоговый
lcd_gotoxy(3, 1);
lcd_string("іo»Дїјeїp",9); // вольтметр
}
_delay_ms(1000);
lcd_clr();// очистить LCD

while(1)
{
progress();
ADCSRA |= (1 << ADSC);	//Начинаем преобразование
while ((ADCSRA&(1 << ADIF))== 0); //Ждем флага окончания преобразования    
u = ADC/4; 
}
}

Файлы:
Библиотека для работы с LCD, проект в AVRSTUDIO, Proteus
Дата 12.02.2012 Размер файла 2.84 KB Закачек 4367

Комментарии  

0 #21 Igor22131 05.08.2014 22:38
Скажите, почему у меня при компиляции приведенного кода в AVR Studio 5 компилятор ругается :
"region 'text' overflowed by 2142 bytes" ?
Сообщить модератору
0 #22 Виктор 25.09.2014 17:26
:cry: Добавьте пожалуйста функцию вывода плавающей запятой. Или подскажите пример для вывода АЦП от ноля до 50 вольт, к примеру. Не могу придумать как делить и раскладывать по разрядам :oops: Спасибо
Сообщить модератору
0 #23 Виктор 25.09.2014 19:40
:sigh: А как сделать чтобы прогресс бар начинался не с ноля и до какого то числа, 0-255, а к примеру 100-230? Что то в этом роде...
Сообщить модератору
0 #24 Виктор 25.09.2014 19:43
:-* То есть, получается, нужен minprogres.
Сообщить модератору
0 #25 AntonChip 25.09.2014 21:08
Цитирую Виктор:
:sigh: А как сделать чтобы прогресс бар начинался не с ноля и до какого то числа, 0-255, а к примеру 100-230? Что то в этом роде...

Вариант, преобразовывать переменную чтобы минимум шкалы был при 100 а максимум при 230, или менять саму функцию progressbar
Сообщить модератору
0 #26 sascha69 22.12.2014 00:07
Здравствуйте. Пишу в atmel studio 6, выдаёт 18 ошибок типа "Error 6 undefi ned reference to `lcd_clr' подскажите, что не так. И еще почему после добавления библиотеки нужно всегда перезапустить студию, иначе не видит библиотеку.
Спасибо.
Сообщить модератору
0 #27 Артем1 10.05.2015 15:58
если использовать дисплей в две строки на 40 символов.как необходимо будет переделать код?
Сообщить модератору
0 #28 Юра 24.05.2016 07:30
Какие пределы измерений у данного вольтметра? И можно ли им измерять свое питание (Использовать как индикатор заряда у питающей атмегу батареи)?

Спасибо!
Сообщить модератору
+1 #29 AntonChip 24.05.2016 07:56
Цитирую Юра:
Какие пределы измерений у данного вольтметра? И можно ли им измерять свое питание (Использовать как индикатор заряда у питающей атмегу батареи)?

Спасибо!

предел 0-5 Вольт, если напряжение питания 5 Вольт
Измерять свое напряжения питания можно если использовать внутренний ИОН, подробнее тут rlocman.ru/.../...
Сообщить модератору
0 #30 Юра 24.05.2016 22:02
Просто огромнейшее спасибо за ссылку! 8)

А можно ли как нибудь измерить при помощи МК какой ток потребляет вся схема? Хотелось бы обойтись без посторонних микросхем. (Я себе часы наручные делаю, очень поможете)

Заранее спасибо
Сообщить модератору
0 #31 иван русев 07.12.2016 21:09
подскажите а чем отличается библиотека 16x2 на 20х4
Сообщить модератору

Рекомендуем посмотреть