Компьютерные подсказки

Вылетает Сталкер: Зов Припяти Программа икс рей 1

Stalker lost alpha гид по прохождению

Pony Express отслеживание почтовых отправлений

Pony Express – время и сроки доставки с Алиэкспресс в Россию

Застряли посылки с Алиэкспресс со статусом Hand over to airline: что делать?

РФ (Nigma) — интеллектуальная поисковая система

Данные для семантики — Яндекс Вордстат

Пиар ВКонтакте при помощи бирж: особенности и использование

Почему я не могу отправить сообщение?

Предупреждение «Подключение не защищено» в Google Chrome по протоколу https Нарушена конфиденциальность данных яндекс браузер

Всё что известно о смартфоне Samsung Galaxy S9 Аккумуляторная батарея Galaxy S9 и мощность

Темы оформления и русификация форума SMF, а так же установка компонента JFusion в Joomla

Автоматическое определение движка форума Позже board powered by smf

Коды в игре скайрим - зелья, ингредиенты, заклинания Код на ингредиенты скайрим

Подробная инструкция, как в "скайриме" открыть дверь золотым когтем

Управление ЖК дисплеем с помощью функций CodeVisionAVR. Работа с символьным ЖКИ на базе контроллера HD44780 Библиотека для работы с lcd дисплеями

По просьбе трудящихся, да и моим обещаниям решил я описать работу с знаковым ЖК 16х2 в среде CodeVisionAVR. Начнем с описания самого ЖК. Алфовитно-цифровой ЖК дисплей со встроенным чипом HD44780 фирмы Hitachi может выводить символы в одну, две или четыре сроки по 8, 16, 20 или 40 символов в каждой. В данной статье я буду рассматривать ЖК 16х2 (16 символов, 2 строки) . Данный дисплей для физического подключения к МК имеет 16 выводов (расположение выводов зависит от фирмы изготовителя) . Давайте посмотрим на эти выводы. Не мудрствуя лукаво я спер табличку в МЭЛТе. В принципе она подходит для любого ЖК.
Ну я думаю что объяснять не нужно для чего нужен тот или иной пин. Там все написано по русски. Но есть несколько небольших но. 1) ЖК дисплеи могут быть выпущены в двух вариантах на 5 вольт, либо на 3,3. 2) В цепи питания не всегда установлен токоограничивающий резистор. Смотрите внимательно, может стоять просто перемычка. (Я так спалил подсветку на двух дисплеях.) 3) Схема включения резистора для регулировки контрастности.
Так, ну теперь как сие чудо подключить к МК. Работать будем с ATmega8 и кварцем на 4 МГц. Вот собственно и схема.
Как видите ничего сложного нет. Первые три разряда порта D служат для управления, а последние четыре для данных. Также можно работать с этими дисплеями по 8-и битной шине, но я думаю отдавать лишние 4 ноги это расточительство. Поэтому будем работать по 4-х битной шине. Со схемой разобрались, теперь давайте с программной частью. Для инициализации дисплея и перевод его в 4-х битный режим нужно выполнить несколько команд. Но перед этим я хочу разъяснить как работают управляющие биты. Бит RS отвечает за то что будет принимать ЖК. Если RS = 0 , то мы передаем команду, а если 1 то данные. Если бит RW = 0 , то мы записываем в ЖК, а если 1 , то читаем. Бит Е просто строб. То есть как только мы захотим ввести команду или данные, то после того как выставили все биты на ножках просто выставляем в 1 бит Е , а потом опять роняем в 0 . 1 - Включить питание 2 - Выдержать паузу не менее 20 мс 3 - Команда для 4-х бит. шины 4 - Выдержать паузу не менее 40 мкс 5 - Команда для 4-х бит. шины (RS=0), (RW=0), (D7=0), (D6=0), (D5=1),(D4=1) 6 - Выдержать паузу не менее 40 мкс 7 - Команда для 4-х бит. шины (RS=0), (RW=0), (D7=0), (D6=0), (D5=1),(D4=1) 8 - Выдержать паузу не менее 40 мкс 9 - Команда для 4-х бит. шины (RS=0), (RW=0), (D7=0), (D6=0), (D5=1),(D4=0) 10 - Выдержать паузу не менее 40 мкс 11 - Выставить параметры (RS=0), (RW=0), (D7=0), (D6=0), (D5=1),(D4=0) (RS=0), (RW=0), (D7=1), (D6=0), (D5=0),(D4=0) 12 - Выключаем дисплей (RS=0), (RW=0), (D7=0), (D6=0), (D5=0),(D4=0) (RS=0), (RW=0), (D7=0), (D6=0), (D5=1),(D4=0) 13 - Очищаем экран (RS=0), (RW=0), (D7=0), (D6=0), (D5=0),(D4=0) (RS=0), (RW=0), (D7=0), (D6=0), (D5=0),(D4=1) 14 - Режим ввода данных (RS=0), (RW=0), (D7=0), (D6=0), (D5=0),(D4=0) (RS=0), (RW=0), (D7=0), (D6=1), (D5=1),(D4=0) О как. Теперь после этой абракадабры наш дисплей готов принимать данные. Что дальше. А дальше давайте ка рассмотрим команды ЖК. Для передачи команд/данных в ЖК по 4-х битной шине требуется два захода. Первым передаем старшие 4 байта, а вторым передаем младшие 4 байта. Дальше все команды я буду писать парами. Команда очистки индикатора и постановка курсора в левый верхний угол. RS=0, RW=0, D4=0, D5=0, D6=0, D7=0 (E=1 потом 0) RS=0, RW=0, D4=0, D5=0, D6=0, D7=1 (E=1 потом 0) Команда перемещения курсора в левую позицию. (Х-значит пофик какое значение) RS=0, RW=0, D4=0, D5=0, D6=0, D7=0 (E=1 потом 0) RS=0, RW=0, D4=0, D5=0, D6=1, D7=Х (E=1 потом 0) Команда устанавливает направление сдвига курсора(ID=0/1 влево/вправо). Так же разрешение сдвига дисплея (SH=1) при записи в DDRAM. RS=0, RW=0, D4=0, D5=0, D6=0, D7=0 (E=1 потом 0) RS=0, RW=0, D4=0, D5=1, D6=ID, D7=SH (E=1 потом 0) Команда включения дисплея (D=1) и выбора курсора (A, B). A=0, B=0 Курсора нет, ничего не мигает A=0, B=1 Курсора нет, мигает весь символ A=1, B=0 Курсор в виде подчеркивания, не мигает A=1, B=1 Курсор в виде подчеркивания и мигает RS=0, RW=0, D4=0, D5=0, D6=0, D7=0 (E=1 потом 0) RS=0, RW=0, D4=1, D5=D, D6=A, D7=B (E=1 потом 0) Команда сдвига дисплея/курсора(SC=0/1 курсор/дисплей RL=0/1 влево/вправо). RS=0, RW=0, D4=0, D5=0, D6=0, D7=1 (E=1 потом 0) RS=0, RW=0, D4=SC, D5=RL, D6=X, D7=X (E=1 потом 0) Команда установки разрядности шины(DL=0/1 4/8 бит) А так же страници знакогенератора Р. RS=0, RW=0, D4=0, D5=0, D6=1, D7=DL (E=1 потом 0) RS=0, RW=0, D4=1, D5=0, D6=Р, D7=0 (E=1 потом 0) Команда установки адреса следующей операции с установкой туда курсора и выбора области CGRAM(Свои придуманные символы). RS=0, RW=0, D4=0, D5=1, D6=ACG, D7=ACG (E=1 потом 0) RS=0, RW=0, D4=ACG, D5=ACG, D6=ACG, D7=ACG (E=1 потом 0) Команда установки адреса последующей операции и выбор области памяти DDRAM (Знакогенератор). RS=0, RW=0, D4=0, D5=1, D6=ADD, D7=ADD (E=1 потом 0) RS=0, RW=0, D4=ADD, D5=ADD, D6=ADD, D7=ADD (E=1 потом 0) Команда Записи данных в текущую область. RS=1, RW=0, D4=DATA, D5=DATA, D6=DATA, D7=DATA (E=1 потом 0) RS=1, RW=0, D4=DATA, D5=DATA, D6=DATA, D7=DATA (E=1 потом 0) Команда Чтения данных в текущую область. RS=1, RW=1, D4=DATA, D5=DATA, D6=DATA, D7=DATA (E=1 потом 0) RS=1, RW=1, D4=DATA, D5=DATA, D6=DATA, D7=DATA (E=1 потом 0) Вот собственно и все команды. Есть еще команда чтения флага занятости, но я ей не пользуюсь, а просто выдерживаю между каждой командой не менее 40 мкс. Вот и все. А теперь после прочтения этого трактата, выпейте чашку чая или кофе и забудьте про все это. Так как всю эту муру на себя берут функции из библиотеки CodeVisionAVR. Создаем новый проект как это было уже рассказано. Для тех кто не в курсе идем сюда , остальные заходят в код-генераторе на вкладку LCD и выбирают PORTD . Что мы этим сделали. Первое мы сказали программе что хотим работать с ЖК дисплеем (выбрав вкладку LCD ). Потом мы сказали что подключим его к порту D . Ниже выпадающий список дает возможность выбрать количество символов в строке. Так как по умолчанию стоит 16 , а мы хотим работать с ЖК 16х2, то ничего менять не надо. Ниже для подсказки расписаны ножки порта для правильного подключения ЖК к МК. Все, сохраняем проект и смотрим на свеже-сгенерированный код. Первое на что надо обратить внимание - это на кусок кода после директивы препроцессора #include Вот на этот: // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x12 ;PORTD #endasm #include > Давайте его разберем построчно. Первая строка комментарий в котором говорится о том что мы подключили заголовочный файл с функциями для работы со знаковым ЖК. Второй строкой мы открываем блок для ввода ассемблерных команд. Следующая строка присваивает порт к которому подключен ЖК. Команда .equ в ассемблере делает тоже самое что команда #include в C. Если вы случайно в генераторе кода выбрали не тот порт, то его можно всегда поменять в этой строке. Номер порта всегда можно узнать в файле инициализации МК. Он всегда подключается в самой первой строке. В нашем случае это mega8.h . Следующая строка закрывает блок ассемблерного кода. И последняя строка как раз и подключает все необходимое для работы с ЖК. Теперь давайте пробежимся по основным функциям. Первая функция которую необходимо вызвать до того как вы начали мучать ЖК - это конечно же функция инициализации дисплея. Выглядит она так: void lcd_init(unsigned char lcd_columns) Данная функция инициализирует дисплей, а передаваемым параметром должно быть количества символов в строке. Мотаем нашу программу в самый низ и перед основным циклом видим две строки следующего содержания: // LCD module initialization lcd_init(16); Вот те самые 16 строк которые были выбраны в списке код-генератора программа и запихнула аргументом в функцию. Здесь также если вы с перепугу забыли что у вас ЖК 8 или 20 символов на строку, то просто поменяйте значение аргумента в этой функции. void lcd_gotoxy(unsigned char x, unsigned char y) Эта функция, судя из ее названия, переводит курсор в позицию x, y . Здесь x - это буковка. Слева направо от 0 до 15/19/39 (зависит от количества букв в строке) . А y - это строка. Сверху вниз от 0 до 0/1/3 (зависит от количества строк) . void lcd_putchar(char c) Эта функция выводит один символ в текущую позицию. Пример: lcd_putchar("A") или lcd_putchar(0x41) что на выходе даст один и тот же результат. То есть параметр может быть как символ, так и его код. lcd_gotoxy(0,0); lcd_putchar("A"); lcd_gotoxy(0,1); lcd_putchar(0x41); Я думаю комментарии здесь излишне, давайте посмотрим на результат.
Следующая функция. void lcd_puts(char *str) Эта функция выводит строку расположенную в SRAM начиная с текущей позиции. Пример: lcd_gotoxy(0,0); lcd_puts("СТРОКА"); Видим:
Следующая функция. void lcd_putsf(char *str) Эта функция выводит строку расположенную во FLASH начиная с текущей позиции. Пример: lcd_gotoxy(0,0); lcd_putsf("СТРОКА"); Видим:
Ну и замыкает все это безобразие функция "Ластик" void lcd_clesr(void) Вызвав данную функцию вы сотрете все что есть на дисплее, а курсор встанет в крайнее левое положение верхней строки. Вот так для начала можно выводить слова и цифры на ЖК дисплей при помощи готовых функций. Теперь давайте поговорим о том как выводить значение переменных. Для этих целей нам понадобится еще одна библиотека. Ну те кто программировал на С под ПК про нее должны знать. Называется она stdio.h Поднимаемся на самый верх программы и после директивы препроцессора #include добовляем #include В итоге наш код примет вид. // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x12 ;PORTD #endasm #include #include Теперь давайте познакомимся с функцией, которая занимается форматированием текста. void printf(char flash *fmtstr [,arg1, arg2, ...]) Как она работает. В char flash *fmtstr задается формат выводимого значения, а в аргументы arg1, arg2, ... имя переменной. Пример. unsigned char temp = 123; printf("temp = %05d\n", temp); Что означает эта абра-кадабра. Первая строка создает переменную и присваевает ей значение. Тут все понятно, а вот что делает вторая. Все по порядку. Сначала выводится запись temp = , затем 00123 . Почему выводится 00123 . А потому что у нас есть условие %05d\n которое говорит: 1) % - будем форматировать значения первого аргумента 2) 0 - будем выводить n знаков, пустые забьем нулями 3) 5 - выводим 5 знаков, если число меньше 5 знаков, то заполнить пустышки нулями. Об этом говорит пункт 2. Число будет выровнено по правому краю. 4) d - выводим число в десятичном формате. 5) \n - Заставит после вывода символа перейти на другую строку. Следующая функция. void sprintf(char flash, char flash *fmtstr [,arg1, arg2, ...]) Вот эта функция нам наиболее интересна. Она форматирует строку и записывает ее в массив. После мы можем смело массив вывести на экран. Как она работает. unsigned char temp = 123; unsigned char string; sprintf(string, "temp = %05d\n", temp); lcd_puts(string); Вот как это выглядит в живую.
Вот мы и научились выводить форматированный текст на ЖК. Далее кратко пробегусь по типам преобразования. i d - Для вывода десятичной целой со знаком u - Для вывода десятичной целой без знака e -d.d e-d E - Для вывода вещественного с плавающей точкой вида -d.d E-d f - Для вывода вещественного с плавающей точкой вида -d.d x - Для вывода в шеснадцатеричном виде маленькими буквами X - Для вывода в шеснадцатеричном виде большими буквами c - Для вывода в символа Если написать %-05d то знак "-" заставит выравнивать по левому краю, а пустышки нулями забиваться не будут. Если вы попытаетесь напечатать число с плавающей точкой, то сильно удивитесь. Число не напечатается. Во засада)) Проблема кроется в настройках компилятора. Для того чтобы компилятор начал понимать формат float нужно его немного настроить. Для этого заходим Project->Configure и заходим во вкладку C Compiler . В своистве (s)printf Features: выбираем float, width, precision . Вот и все. Пробуйте, экспериментируйте. Возникнут вопросы, пишите на форуме. Удачи!

Работа с дисплеем 16x2 на контроллере HD44780 в Bascom-AVR


Жидкокристаллические дисплеи на контроллере HD44780 (а также совместимом с ним KS0066) очень распространены благодаря простому методу работы с ними, а так же небольшой цене. В зависимости от исполнения дисплея, они позволяют выводить от 8-и до 40-ка символов в каждой строке, строк может быть одна, две или четыре. Чаще всего встречаются 8*2 (восемь символов*две строки), 16*2 и 20*4.

Для примера рассмотрим распиновку индикатора 16*2 (у всех дисплеев на контроллере HD44780 она похожа)

У каждого дисплея на контроллере HD44780 для подключения имеется 14 выводов + 2 вывода для подсветки (если она имеется):

  1. Земля, GND
  2. Напряжение питания, Vcc (+5V)
  3. Настройка контрастности, Vo
  4. Выбор регистра, R/S
  5. Чтение/запись, R/W
  6. Сигнал разрешения чтения/записи, E
  7. Bit 0, D0
  8. Bit 1, D1
  9. Bit 2, D2
  10. Bit 3, D3
  11. Bit 4, D4
  12. Bit 5, D5
  13. Bit 6, D6
  14. Bit 7, D7
  15. Питание подсветки для дисплеев с подсветкой, LED +
  16. Питание подсветки для дисплеев с подсветкой, LED -


Данные в дисплей загружаются по шине данных (D0-D7), при этом контроллер поддерживает как 8-и, так и 4-х битное подключение. 4-х битное подключение экономит ножки микроконтроллера и чаще всего достаточно для многих задач (при 8и битном подключении можно быстрее загружать данные в контроллер дисплея, но нам пока это ни к чему, поэтому не будем его рассматривать). Для 4-х битного подключения используются 4 последних бита шины (D4-D7).

В качестве примера будем использовать дисплей 20х4, подключенный к микроконтроллеру ATmega8 по 4х битному интерфейсу по схеме ниже



Дисплей требует для питания 5 вольт, делителем на резисторе R1 настраивается контрастность отображаемых символов, вывод R/W подключается к земле (т.е. выбрана постоянная запись в дисплей). Подключать оставшиеся выводы можно к любым свободным ножкам микроконтроллера. Конфигурация ножек для подключения дисплея у микроконтроллера ATmega8 будет выглядеть следующим образом:

$regfile = "m8def.dat"
$crystal = 1000000 "частота работы 1 МГц

Config Lcd = 20 * 4


Config Lcdpin = Pin , Db4 = PortB . 3 , Db5 = PortB . 2 , Db6 = PortB . 1 , Db7 = PortB . 0 , E = PortB . 4 , Rs = PortB . 5

CLS - очистка дисплея

LCD - вывести данные на дисплей (пример: Lcd "Hello world" выведет надпись Hello world )

А теперь напишем вот такую небольшую программку, которая выведет надпись на дисплей:

$regfile = "m8def.dat" "выбранный тип микроконтроллера
$crystal = 1000000 "частота работы 1 МГц

Config Lcd = 20 * 4 "указываем какой у нас дисплей
"и конфигурируем ножки для подключения
Config

Cursor Off
Cls "очистим дисплей

Lcd "LCD 20*4 HD44780"
Locate 2 , 8 "переводим курсор на вторую строку, восьмое знакоместо
Lcd "сайт" "выводим текст

End

в результате на дисплее получим следующее:

Также в Bascom-AVR есть еще несколько дополнительных команд для работы с дисплеями:

HOME - также возвращает курсор на верхнюю строчку, но в отличии от команды UPPERLINE эта команда может принимать дополнительные значения: если после нее поставить букву L , T или F то курсор переместится в начало строчки, название которой начинается с соответствующей буквы (пример: для того чтобы переместить курсор в начало третьей строки, нужно написать команду HOME T )

пример кода для вывода информации на дисплей с использованием этих команд:

$regfile = "m8def.dat" "выбранный тип микроконтроллера
$crystal = 1000000 "частота работы 1 МГц

Config Lcd = 20 * 4 "указываем какой у нас дисплей
"и конфигурируем ножки для подключения
Config Lcdpin = Pin , Db4 = Portb . 3 , Db5 = Portb . 2 , Db6 = Portb . 1 , Db7 = Portb . 0 , E = Portb . 4 , Rs = Portb . 5

Cursor Off "выключим отображение курсора
Cls "очистим дисплей

Lcd "*** HD44780 LCD ***" "выводим текст в первой строке
Lowerline "переходим на вторую строку
Lcd "Line number 2" "выводим текст
Thirdline "переходим на третью строку
Lcd "AaBbCcDdEeFfGgHfIiJj" "выводим на третьей строке
Fourthline "переходим на четвертую строку
Lcd "1234567890" "печатаем на четвертой строчке

End "конец программы


и пример того как использовать сдвиг текста:

$regfile = "m8def.dat" "выбранный тип микроконтроллера
$crystal = 1000000 "частота работы 1 МГц

Dim A As Byte "переменная для организации цикла

Config Lcd = 20 * 4 "указываем какой у нас дисплей
"и конфигурируем ножки для подключения
Config Lcdpin = Pin , Db4 = Portb . 3 , Db5 = Portb . 2 , Db6 = Portb . 1 , Db7 = Portb . 0 , E = Portb . 4 , Rs = Portb . 5

Cursor Off "выключим отображение курсора
Cls "очистим дисплей

Locate 1 , 11 "устанавливаем курсор на первой строке, десятом знакоместе
Lcd "Bascom-AVR" "выведем текст

"цикл сдвига влево
For A = 1 To 10 "повторяем этот цикл пока переменная А не достигнет значения 10
Shiftlcd Left "сдвинем текст влево
Waitms 300 "задержка 300 миллисекунд
Next A
"цикл сдвига вправо
For A = 1 To 10 "повторяем цикл пока переменная А не достигнет значения 10
Shiftlcd Right "теперь сдвинем текст вправо
Waitms 300 "задержка 300 миллисекунд
Next A "увеличиваем значение переменной А на 1

"продолжаем выполнение программы
Wait 1 "задержка 1 секунда

Home F "устанавливаем курсор на нижнюю строчку

Lcd "END PROGRAM" "и выводим надпись

End "конец программы

Читатель нашего блога Михаил (mishadesh ) создал отличную библиотеку для работы с LCD и предложил написать статью для демонстрации ее возможностей. Собственно, сегодня именно об этом и пойдет речь 😉 Разберем, какие реализованы функции, а также в конце статьи будет выложен пример для работы с дисплеем.

Как обычно начнем с обсуждения железа… А тут на самом деле и не о чем говорить. Как и в первой статье, посвященной работе с дисплеями (), мы будем использовать отладочную плату Mini STM32 . Собственно, подключение дисплея, основные команды для записи данных, последовательность инструкций для инициализации – все это там есть =) Поэтому сейчас переходим сразу к обсуждению библиотеки для работы с графическими дисплеями.

Вот полный список функций с пояснениями:

Следующая функция, как видно из ее названия, меняет ориентацию экрана. Возможно два положения экрана, соответственно два возможных значения параметра orientation :

  • Orientation_Portrait
  • Orientation_Album

Функция отрисовывает на графическом дисплее символ, располагая его по переданным в функцию координатам, а также задавая его цвет. Начертание символа соответствует шрифту, определенному в файле font.c (файл идет в составе библиотеки).

Из функции LCD_DrawChar() плавно вытекает следующая функция:

void LCD_DrawString(char * s, uint16_t x, uint16_t y, uint16_t color, uint16_t backColor, uint8_t isTransparent) ;

Тут понятно и без лишних слов 😉 Функция печатает на LCD строку текста. Базой для этой функции является предыдущая – LCD_DrawChar() .

Помимо символов и текста, конечно же, необходимо иметь возможность нарисовать основные графические примитивы, например линию или круг. Для этого реализовано следующее:

void LCD_drawLine ( int x1, int y1, int x2, int y2, uint16_t color) ; void LCD_DrawRect ( int x1, int y1, int x2, int y2, uint16_t color, uint8_t filled ) ; void LCD_DrawEllipse(uint16_t X1, uint16_t Y1, uint16_t R, uint16_t color) ;

Для рисования линии нужно передать в функцию координаты начальной точки, координаты конечной точки, а также нужный цвет. Для прямоугольника – координаты верхнего левого угла и координаты правого нижнего угла (!). Последний параметр filled – определяет, необходимо ли выполнять заливку фигуры. Единица – значит да, фигура будет закрашена выбранным цветом, ноль – будет нарисован только контур фигуры. С этим понятно) Осталась только окружность – функция DrawEllipse() . Здесь вместо координат начала и конца (верхнего/нижнего углов) передаем в качестве аргументов центр окружности и радиус.

Ну и напоследок еще одна функция:

void LCD_FillScr(uint16_t color) ;

Функция позволяет залить экран сплошным цветом.

Все перечисленные функции реализованы в файле GUI_DRV.c .

Помимо них библиотека включает в себя функции для записи данных в дисплей (LCD_DRIVER.c ) а также уже упомянутые шрифты (font.c ). Как видите, все четко отсортировано по разным файлам, так что в принципе все очень понятно, поэтому давайте перейдем к практическому примеру!

Давайте разбираться! Идем в файл main.c … Не буду приводить полный код функций инициализации периферии и дисплея, все это можно посмотреть непосредственно в файле, либо в предыдущей статье, ссылка на которую была в начале этой статьи 😉 Функция main() :

int main(void ) { initPeriph() ; initFSMC() ; initLCD() ; delay(10000 ) ; LCD_FillScr(0xFFFF ) ; delay(100 ) ; LCD_SetOrient(Orientation_Album) ; delay(100 ) ; LCD_DrawString("Библиотека для LGDP4532" , 30 , 30 , 0x888F , 0x0000 , 0 ) ; LCD_DrawRect(100 , 100 , 200 , 200 , 0x0000 , 0 ) ; LCD_DrawRect(120 , 120 , 180 , 180 , 0xFF00 , 1 ) ; LCD_DrawEllipse(150 , 150 , 50 , 0xF000 ) ; while (1 ) { } }

Начинаем с инициализации, закрашиваем экран белым цветом и устанавливаем альбомную ориентацию экрана. И теперь переходим к отрисовке графики)

Выводим на экран строку, а также два прямоугольника и круг. Результат налицо:

Очевидно, что все работает отлично 😉

Итак, на этом на сегодня заканчиваем, огромное спасибо Михаилу за проделанную работу и приведенные материалы. Вот контакты автора библиотеки:

Skype – mishadesh

Mail – [email protected]

На этом все, спасибо за внимание, до скорых встреч!

Урок 12

Часть 5

LCD индикатор 16×2

Сегодня мы продолжим изучение жидкокристаллического индикатора символьного , который способен выводить определённые символы в две строки по 16 символов в каждую.

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

Теперь пришло время написать функцию вывода на экран целой строки, так как выводить посимвольно не совсем удобно, хотелось бы работать со строками. Добавим данную функцию прямо перед функцией main() и передавать мы ей будем массив символов неопределённой размерности

//—————————————-

void str_lcd ( char str1 )

{

}

//—————————————-

Вызовем данную функцию в main(), удалив перед этим весь код посимвольного вывода на дисплей

LCD_ini (); //Инициализируем дисплей

setpos (0,0);

str_lcd ( "Hello World!" );

Дальше начнём писать тело функции вывода строки. Объявим в теле функции переменную для символа. Переменная у нас будет несколько иного типа. Как правило с таким типом лучше распознаются коды символов. Вы можете, конечно, поэксперементировать с другими типами

void str_lcd ( char str1 )

wchar_t n ;

Далее мы, соответственно, организуем цикл и будем попеременно перебирать все переданные символы в массиве и выводить их на дисплей. Применим также мы вариант представления нулевого симвлова "n" и именно до него мы и будем перебирать символы

Wchar_t n ;

for ( n =0; str1 [ n ]!=""; n ++)

sendchar ( str1 [ n ]);

Соберём код и проверим в протеусе работу кода

Теперь можно попробовать вывести строку ещё и в другое место экрана. Напишем код в main()

str_lcd ( "Hello World!" );

setpos (2,1);

str_lcd ( "String 2" );

while (1)

Соберём код и посмотрим результат

Всё работает! Отлично!

Ну конечно нужно ещё помотреть, как будет код работать на живом дисплее с живым контроллером. Для этого мы прошьём контроллер

Оформляем функции в отдельный модуль

Дошли мы с кодом до такого состояния, что наш главный и единственный файл с кодом переполнился до того, что в нём теперь тяжело уже вообще что-то найти. Как же мы с этим можем боротья? Бороться с этим мы будем путём оформления кода функций для отдельно взятого устройства или шины или какой-то технологии в отдельный модуль. Грамотный модуль состоит как правило из заголовочного файла и файла реализации функций. Поэтому давайте для нашего LCD дисплея мы так и поступим. Также это всё дело нужно для того, что если мы будем писать новый проект, то мы данные файлы будем просто к нему подключать, если нам потребуется воспользоваться LCD дисплеем. Это будет нашей так называемой библиотекой для дисплея. Конечно, библиотеки обычно пишутся и компилируются в отдельный файл lib, но в этом случае обычно нет исходного кода и данные библиотеки не могут быть подправлены. А наша библиотека будет вполне исправимой и нам ещё ой как пригодится в будущем.

Но прежде, чем создать данную библиотеку, мы создадим главный заголовочный файл и назовём его main.h, чтобы убрать в данный файл все подключенные библиотеки, различные глобальные переменные и макроподставновки

Для этого мы в дереве проектов щёлкаем правой кнопкой по нашему проекту Test09 и выбираем в контекстном меню субменю Add , а в нём уже выбираем пункт New Item

И в открывшемся диалоге выбираем тип файла, который мы будем создавать, "Include File " И внизу в имени файла меняем IncFile1 на main , затем жмём кнопку Add.

Соответственно, у нас создастся файл main.c вот с таким содержимым

#ifndef MAIN_H_

#define MAIN_H_

#endif /* MAIN_H_ */

Это очень хорошо. Например. в Keil, когда мы занимается программированием контроллеров STM, мы должны это всё писать в ручную. Здесь данная директива говорит о том, что, если файл уже подключался в исполняемый код, чтобы прероцессор его повторно не включал.

В данный файл мы посместим подключения всех заголовочных файлов библиотек и все макроподстановки, а в файле Test09.c всё это, конечно, мы удалим

#ifndef MAIN_H_

#define MAIN_H_

#define F_CPU 8000000UL

#include

#include

#include

#include

#include

//—————————————-

#define e1 PORTD |=0b00001000 // установка линии E в 1

#define e0 PORTD &=0b11110111 // установка линии E в 0

#define rs1 PORTD |=0b00000100 // установка линии RS в 1 (данные)

#define rs0 PORTD &=0b11111011 // установка линии RS в 0 (команда)

//—————————————-

#endif /* MAIN_H_ */

Но недостаточно данный заголовочный файл подключить в Solution Explorer, его также мы должны в файле Test09.c подключить в самом начале в код

#include "main.h"

//—————————————-

Соберём проект, ещё раз проверим его работоспособность.

Теперь начнём создавать нашу библиотеку для дисплея.

Для этого мы таким же образом, как и main.h, создадим заголовочный файл lcd.h

#include

#include "lcd.h"

И наоборот, в файл lcd.h мы подключим файл main.h

#ifndef LCD_H_

#define LCD_H_

#include "main.h"

Насчет того, что получится какое-то перекрёстное зацикливание, можно не беспокоиться — директивы не дадут такому случиться.

Также все макроподстановки из файла main.h мы заберём в файл lcd,h, а в main.h удалим

#include "main.h"

//—————————————-

void LCD_ini ( void );

void setpos ( unsigned char x , unsigned y );

void str_lcd ( char str1 );

void sendchar ( unsigned char c );

//—————————————-

А, чтобы забрать все функции по работе с дисплеем из файла Test09.c, мы создадим теперь уже другой файл — lcd.с . В нём и будет код реализации всех функций

Создаётся файл точно таким же образом, только вместо "Include File" мы выбираем тип файла "C File".

Файл lcd.c создан. В нём уже не будет никаких директив, единственное, будет авторский комментарий, который мы удалим, чтоб не мешался.

В данном файле мы также подключим заголовочный файл lcd.h

#include "lcd.h"

//—————————————-

Теперь мы в данный файл перенесём полностью все функции, предназначенные для работы с дисплеем, из файла Test09.c. В нём останутся только две фунции — port_ini и main() .

Тем самым мы очень серьёзно разгрузим главный файл приложения, сделав его удобочитаемым.

Но этого нам недостаточно. Ни одна функция теперь не будет "видна" в файле Test09.c. Поэтому те функции, которые мы будем использовать в других файлах, мы обязаны объявить, или, как говорят в народе, создать на них прототипы. Делается это обычно в заголовочном файле. Поэтому мы создадим прототипы в заголовочном файле lcd.h. Прототип делается очень легко. Пишется, или обычно копируется заголовок функции со всеми аргументами (всё кроме тела) и в конце ставится точка с запятой. Нам нужны будут функции инициализации дисплея, позиционирования на дисплее и вывода строки на дисплее. Символы мы отдельно пока выводить не будем, поэтому на соответствующую функцию мы прототип не создаём. Вот наши прототипы

#include "main.h"

//—————————————-

void LCD_ini ( void );

void setpos ( unsigned char x , unsigned y );

void str_lcd ( char str1 );

//—————————————-

#define e1 PORTD |=0b00001000 // установка линии E в 1

Теперь соберём файл, запустим его в протеусе, и проверим его работоспособность. Также проверим на практике. Если всё работает, то мы всё сделали правильно. Проект на весь урок приложен внизу и доступен по ссылке "Исходный код".

Таким образом, в сегодняшнем уроке мы много чему научились. Мы научились работать с символьным дисплеем и подключать его к контроллеру AVR. Также мы в рамках данного урока научились грамотному оформлению кода и использованию модульного программирования.

Post Views: 11 438

В этой статье я расскажу как с помощью достаточно распространенной библиотеки управлять 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" используем в функции вывода динамической шкалы progress() .

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

//******Применение библиотек для работы с LCD HD44780***** #include #include #include #include "lcd_lib.h" const uint8_t simbol_1 PROGMEM= {
0b00000,0b10001,0b01010,0b00100,0b01010,0b10001,0b00000,0b00000
};
const uint8_t simbol_2 PROGMEM= {
0b00100,0b00100,0b00100,0b11111,0b00100,0b00100,0b00100,0b00000
}; unsigned 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; } }

Вам также будет интересно:

Читы и консольные команды для Counter-Strike: Global Offensive Команда в кс го чтобы летать
В этой статье мы рассмотрим некоторые из наиболее полезных и забавных консольных команд в...
Arduino и четырехразрядный семисегментный индикатор Семисегментный индикатор 4 разряда распиновка
В сегодняшней статье поговорим о 7-сегментных индикаторах и о том, как их «подружить» с...
«Рабочие лошадки» Hi-Fi: собираем бюджетную систему Хороший бюджетный hi fi плеер
Выбор плеера - это сложный процесс, иногда человек желает получить не просто коробочку,...
Как правильно пользоваться сургучными печатями
На самом деле, сургуч - это смесь смол, окрашенная в определенный цвет. Если у вас на руках...
Лагает fallout 4 как снизить графику
10 ноября состоялся релиз долгожданной игры на ПК, PlayStation 4 и Xbox One, и постепенно...