Библиотека для работы с HD44780
В прошлой статье мы рассмотрели теоретические основы управления LCD дисплеем на базе контроллера HD44780. Но разумеется теория без практики ничего не значит, а поэтому я предлагаю побаловаться с этим дисплеем вживую. Дисплей стоит не дорого, что-то в районе 6$, лично я экспериментировал с дисплеем под названием ACM1602K-FL-YTH-02. Редкостный отстой скажу я вам, не покупайте такой. Некоторые символы в левой половине экрана плохо видны, хотя первое время дисплей работал без проблем. Кстати точно такой-же дисплей пришлось вернуть обратно в магазин, у него полностью не работала левая его часть. Лучше купить на бакс подороже и не иметь проблем в будующем, мне например понравились наши отечественные МЭЛТовские дисплеи они кстати лишены некоторых проблем с русскими символами (об этом подробнее позже). Для того чтоб использовать ваш дисплей совместно с моей программой не производя ни каких изменений в коде, вы должны подключить его к контроллеру STM32 следующим образом:
Сразу хочу сказать, что код рассчитан на двухстрочный 16-ти символьный дисплей, хотя я почти уверен что он заработает и с дисплеем 8х2 без всяких изменений, да и с однострочными наверное тоже.
Как использовать библиотеку
Первым делом нужно скопировать папку hd44780_driver вместе со всем её содержимым в директорию с файлами своего проекта. Файлов там всего два: Один заголовочный, с кучей малопонятных дефайнов, а другой непосредственно с кодом который реализует функционал. Если вы подключили дисплей к тому же самому порту и к тем же самым его выводам, то ничего изменять в заголовочном файле (который с расширением .h) не надо. Если же вы ради удобства разводки платы или по каким либо другим причинам решили пересадить дисплей на другие выводы то нужно их указать в заголовочном файле. Первым делом указываем порт. У меня указан порт С. После порта идет описание того к каким ножкам порта С подключены определённые ноги дисплея. Напомню, что вывод дисплея R/W я всегда жестко сажаю на землю, так как ничего из дисплея я не читаю, а только пишу в него.
На этом настройка заканчивается и теперь можно использовать функции библиотеки предварительно конечно же добавив в файл main.c строчку
Теперь посмотрим что за функции есть в этой библиотеке, и начнем с инициализации дисплея. Она происходит после вызова функции lcd_init(). Первым делом происходит настройка ног порта которые определены в заголовочном файле. Если этот порт уже был настроен каким либо образом, то настройки других ног не перетираются. Именно для этого служат все эти адские конструкции из директив препроцессора в заголовочном файле. После настройки ног выполняется непосредственно сама инициализация. По умолчанию дисплей настраивается следующим образом: 4-х битный режим, включен курсор, при поступлении данных счетчик адреса увеличивается на единицу, дисплей чист, курсор в позиции X0, Y0. Для очистки дисплея используется функция lcd_clear(), с ней я думаю всё понятно. После её вызова очищается DDRAM и курсор встаёт в позицию с координатами 0,0. Если же вам требуется просто переместить курсор без очистки дисплея, то на этот случай в библиотеке имеется своя функция lcd_set_xy(x,y), где x и y координаты курсора на экране. Так же присутствует функция lcd_set_state для управления отображением курсора и состоянием самого дисплея. При помощи неё можно прятать и показывать курсор и заставлять его мигать. Так же существует возможность выключать/включать LCD дисплей. Возможен вызов данной функции со следующими параметрами:
- lcd_set_state(LCD_DISABLE, CURSOR_DISABLE, NO_BLINK); - дисплей ничего не показывает, даже если данные в DDRAM есть. Если в качестве первого параметра выступает LCD_DISABLE, то по идее вторые два вообще не важны, так как ни какого курсора при выключенном дисплее мы не увидим.
- lcd_set_state(LCD_ENABLE, CURSOR_DISABLE, NO_BLINK); - дисплей включен, курсора нет, ничего не мигает
- lcd_set_state(LCD_ENABLE, CURSOR_DISABLE, BLINK); - дисплей включен, курсора нет, но мигает все знакоместо (черным квадратом)
- lcd_set_state(LCD_ENABLE, CURSOR_ENABLE, NO_BLINK); - дисплей включен, есть не мигающий курсор
- lcd_set_state(LCD_ENABLE, CURSOR_ENABLE, BLINK); - дисплей включен, курсор есть, мигает всё знакоместо.
При помощи функции lcd_out можно вывести строку текста в текущую позицию курсора, которая может быть установлена вызовом функции lcd_set_xy. В функцию lcd_out следует передавать указатель на строку (строка разумеется должна заканчиваться нульсимволом). Следующая функция lcd_send принимает два параметра: Первый - байт данных, второй - COMMAND или DATA. Не трудно догадаться, что она служит для передачи в дисплей байта данных или команды. И наконец функция lcd_set_user_char предназначена для того чтоб записать пользовательский символ в CGRAM память дисплея. Подробнее о том как это сделать, будет написано в примере.
Пример использования библиотеки
Для того чтоб показать как оно работает я написал простенький пример который использует функции из этой библиотеки. Собственно вот он:
В результате выполнения этого кода на дисплее появится надпись и наша рыба которую мы изобразили. Если этот пример не запустился, пишете в комментариях и попробуем разобраться.
Вместо заключения
Библиотека так себе, написал её буквально за полтора вечера, особо ничего не оптимизировал, поэтому прошу не пинать меня ногами если вы увидите в ней что-то вырвиглазное :-) Несмотря на это она таки работает! Хочу отметить два важных момента: Во-первых - чтоб работал русский язык нужно перекодировать русскую фразу. Т.е. написать lcd_out("Привет мир"); не получится, вместо русских букв там будут каракули,не не совпадает кодировка. Кстати МЭЛТовские дисплеи имеют команду для смены кодировки, и тогда можно отправлять в дисплей русские буквы так как они есть без перекодирования. В интернетах имеются спец программы позволяющее это сделать, просто надо немного погуглить. Кстати можно просто допилить функцию lcd_out чтоб она сама выполняла перекодировку русских символов. Возможно я улучшу её позже, сейчас в этом нет необходимости. Во-вторых в библиотеке есть функция предназначенная для создания небольшой задержки. Если ваш контроллер работате на каких-то запредельных частотах - просто увеличте значение tmpvar раза в полтора. Если у вас не работает конечно. Сделать это можно в файле hd44780_driver.c строка номер 5. Ну и собственно прикладываю архив со своим проектом в кокосе.