AVR. Учебный курс. Подключение к AVR LCD дисплея HD44780Print This Post

Автор DI HALT
Опубликовано 23 Сен 2008 
Рубрики: AVR. Учебный курс
Метки: , , ,

Сегодня разменял четверть века
Сегодня разменял четверть века!
Так случилось, что прикупил я тут себе поприколу LCD дисплейчик две строки по восемь символов. Валялся он в ящике валялся, да чегото поперло меня и решил я его заюзать, попутно вкурив в его работу. О том как подключить к AVR LCD дисплей я вам сейчас и поведаю.

Для начала оговорюсь сразу, что речь тут пойдет о LCD индикаторах на контроллере HD44780, который стал промышленным стандартом де-факто на рынке цифро-буквенных дисплеев. Продается везде где только можно, стоит недорого (8х2 мне обошелся порядка 150 рублей), а также под него написана куча кода. Я же, как обычно, решил изобрести велосипед и сварганить свою собственную тру-библиотеку для работы с этим типом индикаторов. Разумеется на ассемблере, а на чем же еще? ;)

Подключение.
LCD на базе HD44780 подключается к AVR микроконтроллеру напрямую к портам. Есть два способа подключения - на 8 бит и на 4 бита. В восьмибитном режиме немножко проще закидывать байты - не нужно сдвигать байт, зато в четырех битном резко нужно тратить на целых четыре ножки контроллера меньше. Есть еще одна особенность работы в 8-битном режиме — к некоторым контроллерам можно подрубить этот дисплей как внешнее ОЗУ и засылать данные простыми командами пересылки. Лично я подключил его в режиме полного порта у меня один фиг выводы уже девать некуда было, так что не жалко.
  • Выводы DB7…DB0 это шина данных/адреса.
  • E — стробирующий вход. Дрыгом напряжения на этой линии мы даем понять дисплею что нужно забирать/отдавать данные с/на шину данных.
  • RW — определяет в каком направлении у нас движутся данные. Если 1 - то на чтение из дисплея, если 0 то на запись в дисплей.
  • RS — определяет что у нас передается, команда (RS=0) или данные (RS=1). Данные будут записаны в память по текущему адресу, а команда исполнена контроллером.

Со стороны питания все еще проще:

Подключение дисплея
Подключение дисплея
Видимая и скрытая область экранной памяти
Видимая и скрытая область экранной памяти
Структура адресации контроллера HD44780
Структура адресации контроллера HD44780
Формирование символа в ячейке CGRAM
Формирование символа в ячейке CGRAM

  • GND — минус, он же общий.
  • Vcc — плюс питания, обычно 5V
  • V0 — вход контрастности. Сюда нужно подавать напряжение от нуля до напряжения питания, тем самым задается контрастность изображения. Можно поставить переменный резистор, включенный потенциометром и крутить в свое удовольствие. Главное поймать значение максимального контраста, но чтобы не было видно знакомест (серый ореол из квадратов вокруг символа). Если же выставить слишком малый контраст, то символы будут переключаться лениво и задумчиво. Примерно как в калькуляторе у которого сели батарейки.
  • А - это вход Анода светодиодной подсветки. Короче плюс.
  • К - соответственно Катод, он же минус. Подсветка хавает примерно 100мА и поэтому нужно выставить туда токоограничительный резистор на 100 Ом. Кстати, многие ЖК дисплеи имеют на плате пятачки для припайки резисторов. Если прозвонить, то можно убедиться в том, что эти линии ведут на входы питания LCD, поэтому, впаяв резисторы, можно не заморачиваться на запитку подстветки, она будет подключена к питанию контроллера.

Логическая структура LCD контроллера HD44780

Контроллер имеет свой блок управления, который обрабатывает команды и память. Она делится на три вида:

DDRAM - память дисплея. Все что запишется в DDRAM будет выведено на экран. То есть, например, записали мы туда код 0×31 — на экране выскочит символ “1″ т.к. 0х31 это ASCII код цифры 1. Но есть тут одна особенность - DDRAM память гораздо больше чем видимая область экрана. Как правило, DDRAM содержит 80 ячеек — 40 в первой строке и 40 во второй, а на дисплей может двигаться по этой линейке как окошко на логарифмической линейке, высвечивая видимую область. То есть, например, можно засунуть в DDRAM сразу пять пунктов меню, а потом просто гонять дисплей туда сюда, показывая по одному пункту. Для перемещения дисплея есть спец команда. Также есть понятие курсора — это место в которое будет записан следующий символ, т.е. текущее значение счетчика адреса. Курсор не обязательно может быть на экране, он может располагаться и за экраном или быть отключен вовсе.

CGROM - таблица символов. Когда мы записываем в ячейку DDRAM байт, то из таблицы берется символ и рисуется на экране. CGROM нельзя изменить, поэтому важно, чтобы она имела на борту русские буквы. Если, конечно, планируется русскоязычный интерфейс.

CGRAM - тоже таблица символов, но ее мы можем менять, создавая свои символы. Адресуется она линейно, то есть вначале идет 8 байт одного символа, построчно, снизу вверх — один бит равен одной точке на экране. Потом второй символ тем же макаром. Поскольку знакоместо у нас 5 на 8 точек, то старшие три бита роли не играют. Всего в CGRAM может быть 8 символов, соответственно CGRAM имеет 64 байта памяти. Эти программируемые символы имеют коды от 0х00 до 0х07. Так что, закинув, например, в первые 8 байт CGRAM (первый символ с кодом 00) какую нибудь фигню, и записав в DDRAM нуль (код первого символа в CGRAM) мы увидим на экране нашу хрень.

Доступ к памяти.
Тут все просто. Мы командой выбираем в какую именно память и начиная с какого адреса будем писать. А потом просто шлем байты. Если указано, что записываем в DDRAM то на экран (или в скрытую область) полезут символы, если в CGRAM то байты полезут уже в память знакогенератора. Главное потом не забыть переключится обратно на область DDRAM

Система команд.
Система команд проста как мычание. О том, что передается команда контроллеру дисплея сообщит нога RS=0. Сама команда состоит из старшего бита, определяющего за что отвечает данная команда и битов параметров, указывающих контроллеру HD44780 как дальше жить.

Таблица команд:

DB7DB6DB5DB4DB3DB2DB1DB0Значение
00000001Очистка экрана. Счетчик адреса на 0 позицию DDRAM
0000001-Адресация на DDRAM сброс сдвигов, Счетчик адреса на 0
000001I/DSНастройка сдвига экрана и курсора
00001DCBНастройка режима отображения
0001S/CR/L--Сдвиг курсора или экрана, в зависимости от битов
001DLNF--Выбор числа линий, ширины шины и размера символа
01AGAGAGAGAGAGПереключить адресацию на SGRAM и задать адрес в SGRAM
1ADADADADADADADПереключить адресацию на DDRAM и задать адрес в DDRAM

Теперь поясню что значат отдельные биты:
  • I/D - инкремент или декремент счетчика адреса. По дефолту стоит 0 - Декремент. Т.е. каждый следующий байт будет записан в n-1 ячейку. Если поставить 1 - будет Инкремент.
  • S - сдвиг экрана, если поставить 1 то с каждым новым символом будет сдвигаться окно экрана, пока не достигнет конца DDRAM, наверное удобно будет когда выводишь на экран здоровенную строку, на все 40 символов, чтобы не убегала за экран.
  • D - включить дисплей. Если поставить туда 0 то изображение исчезнет, а мы в это время можем в видеопамяти творить всякие непотребства и они не будут мозолить глаза. А чтобы картинка появилась в эту позицию надо записать 1.
  • С - включить курсор в виде прочерка. Все просто, записали сюда 1 - включился курсор.
  • B - сделать курсор в виде мигающего черного квадрата.
  • S/C сдвиг курсора или экрана. Если стоит 0, то сдвигается курсор. Если 1, то экран. По одному разу за команду
  • R/L - определяет направление сдвига курсора и экрана. 0 - влево, 1 - вправо.
  • D/L - бит определяющий ширину шины данных. 1-8 бит, 0-4 бита
  • N - число строк. 0 - одна строка, 1 - две строки.
  • F - размер символа 0 - 5х8 точек. 1 - 5х10 точек (встречается крайне редко)
  • AG - адрес в памяти CGRAM
  • АD - адрес в памяти DDRAM

Я сам долго тупил в эту табличку, пытаясь понять, что же от меня хотят. Видимо был невыспавшийся, но и вправду, она на первый взгляд не очевидна, поэтому подкреплю все примером.

Задача:

  1. Включить дисплей.
  2. Очистить содержимое.
  3. Сдвинуть курсор на одну позицию.
  4. И записать туда “1″.
Решение (последовательность команд):

Первым делом Инициализация дисплея без которой большая часть дисплеев на HD44780 просто откажется работать. Некоторые виды имеют дефолтные состояние (шина 8 бит, курсор в 0) и им только дисплей включить. Но все же ее лучше сделать, мало ли что там намудрил разработчик. Лишней не будет.

  1. 00111000 Шина 8 бит, 2 строки
  2. 00000001 Очистка экрана
  3. 00000110 Инкремент адреса. Экран не движется

  1. 00001100 Включили дисплей (D=1)
  2. 00000001 Очистили дисплей. Указатель встал на DDRAM
  3. 00010100 Сдвинули курсор (S/C=0) вправо (R/L=1)
  4. 00110001 - это мы уже записали данные (ножка RS=1) код “1″ 0х31

Жирным шрифтом выделен идентификатор команды, ну а остальное по таблице увидите.

Задача: создать свой символ. С кодом 01 и вывести его на экран.
Считаем, что дисплей у нас уже инициализирован и готов к приему данных.

Решение:

  1. 01001000      Выбираем в CGRAM адрес 0х08 - как раз начало второго символа (напомню, что на один символ уходит 8 байт)
  2. 00000001     Это пошли 8 байт данных. (RS=1)
  3. 00000010     Рисуем значок молнии, ну или
  4. 00000100     ССовскую Зиг руну, кому как
  5. 00001000     больше нравится.
  6. 00011111     Старшие три бита не действуют
  7. 00000010     Туда можно писать что угодно, на
  8. 00000100     результат влиять не будет.
  9. 00001000     Последний байт данных  
  10. 10000000      А это уже команда - переключение адреса на DDRAM и указатель на адрес 0000000 - первый символ в первой строке.
  11. 00000001      И снова данные (RS=1), код 01 - именно в него мы засунули нашу молнию.
Опа и он на экране!

Так, с логикой разобрались, пора вкуривать в физику протокола общения. Код я приведу несколько позже, когда вылижу свою библиотеку и заоптимизирую до состояния идеала. Пока же дам алгоритм, а его уж на любом языке программирования реализовать можно. Хоть на ассемблере, хоть на Сях, да хоть на Васике :)

Алгоритм чтения/записи в LCD контроллер HD44780
Направление, а также команда/данные определяются ножками, а чтение и запись осуществляется по переходу строба (вывод Е) из 1 в 0

Инициализация портов

  1. RS, RW, E - в режим выхода.
  2. DB7..DB0 в режим входа. Впрочем, можно их не трогать, дальше переопределим.


Ожидание готовности, чтение флага занятости.
  1. Порт данных на вход с подтяжкой (DDR=0, PORT=1)
  2. RS=0 (команда)
  3. RW=1 (чтение)
  4. E=1 (Готовьсь!!!)
  5. Пауза (14 тактов процессора на 8МГЦ хватало)
  6. Е=0 (Пли!)
  7. Читаем из порта. Если бит 7 (Busy flag) установлен, то повторяем все заново, пока не сбросится.


Запись команды
  1. Ожидание готовности
  2. RS=0 (команда)
  3. RW=0 (запись)
  4. Е=1 (Готовьсь!!!)
  5. Порт на выход
  6. Вывести в порт код команды
  7. Пауза
  8. Е=0 (Пли!)
  9. Орудие на плечо Порт на вход, на всякий случай.


Запись Данных
  1. Ожидание готовности
  2. RS=1 (Данные)
  3. RW=0 (запись)
  4. Е=1 (Готовьсь!!!)
  5. Порт на выход
  6. Вывести в порт код команды
  7. Пауза
  8. Е=0 (Пли!)
  9. Порт на вход, на всякий случай.


Чтение команды
  1. Ожидание готовности
  2. Порт данных на вход с подтяжкой (DDR=0, PORT=1)
  3. RS=0 (команда)
  4. RW=1 (чтение)
  5. Е = 1 (Готовьсь! В этот момент данные из LCD вылазят на шину)
  6. Пауза
  7. Считываем данные с порта
  8. E=0 (Ать!)


Чтение Данных
  1. Ожидание готовности
  2. Порт данных на вход с подтяжкой (DDR=0, PORT=1)
  3. RS=1 (Данные)
  4. RW=1 (чтение)
  5. Е = 1 (Готовьсь! В этот момент данные из LCD вылазят на шину)
  6. Пауза
  7. Считываем данные с порта
  8. E=0 (Ать!)

С четырех разрядной шиной все точно также, только там каждая операция чтения/записи делается за два дрыга строба.

Запись:

  1. E=1
  2. Пауза
  3. Выставили в порт старшую тетраду
  4. E=0
  5. Пауза
  6. Е=1
  7. Пауза
  8. Выставили в порт младшую тетраду
  9. Е=0


Чтение
  1. E=1
  2. Пауза
  3. Читаем из порта старшую тетраду
  4. Е=0
  5. Пауза
  6. Е=1
  7. Пауза
  8. Читаем из порта младшую тетраду
  9. Е=0

Ждите код :) Скоро будет :)
UPD:
А вот и код!

Комментарии

145 комментариев на «AVR. Учебный курс. Подключение к AVR LCD дисплея HD44780»


  1. Fi5t 23 Сен 2008 0:50

    Однако познавательно! Как только появится свободное время, надо будет это все расковырять =) Как раз 8ю атмегу в ДИПе достану и панельу к ней. Надо будет спаять какую-нить полезную хреновину =) В любом случае спасибо автору. Он и на этот раз не подвел. Толковые вещи пишешь =)


  2. Stanislaw K 23 Сен 2008 2:24

    C днем рождения!

    DI HALT

    Спасибо!


  3. Cyber_RAT 23 Сен 2008 10:59

    Поздравляю с четвертью века!
    Хороший курс, желаю всяческих идей и возможностей для его развития!!!! ну и здоровья конечно же! куда ж без него.


  4. Dghost 23 Сен 2008 11:44

    DI-halt и от меня прими поздравления! Желаю всего перечисленного выше, а также не останавливаться на достигнутом!


  5. Димка 23 Сен 2008 12:25

    Поздравляю с Днём Рождения!!!
    Успехов тебе в твоих начинаниях!
    Пишешь очень интересно и понятно.
    Читаю все твои статьи с огромным интересом. Особенно порадовала серия рассказов “Последний Герой труда”.


  6. devmind.livejournal.com 23 Сен 2008 12:43

    Поздравляю! Всех благ!


  7. winmike 23 Сен 2008 14:15

    0×19! :-)

    nwanomaly

    +1

    есть минивопрос - имеются ли в реальности лсд-дисплеи на 3 вольта?

    зы! прошёлся по питерским магазам типа микроники и чипидипа - у них не бывает. а сами дисплеи на 2 строки начинаются от 400 рублей (

    DI HALT

    Вот такие хз. А вот от Nokia 3310 как раз по моему от 3.3 вольта работает.

    Хренасе у вас цены. Я могу пойти и Элемент и взять там 16х2 за 180р.

    nwanomaly

    может просто неудачный день. хотя тут же на днях покупал мегу8535 - 170рэ, а с буковкой L - ровно в 2 раза дороже. это с учётом того, что зимой мне знакомый из москвы из по 100рублей привозил … (

    Elementus

    Привет всем !!!
    приходи к нам мы привезём
    ATmega8535L-8PU ATMEL DIP40 110.00
    привезём , под заказ ,если сделаете заказ до четверга во вторник на следующей нидели получите.

    DI HALT

    Расслабься, ему из Казахстана ехать дороже выйдет :)

    nwanomaly

    эта мега мне не нужна уже )
    а про 3В спросил вот почему - как раз с мегой (которая L, которая на 3В) достал корпус, который выглядит, как старый большой калькулятер.

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

    минус - на сайте ихнем не написан вольтаж, а матчастью по этому поводу я не знаком, так что поиски по времени ещё больше удлиняются (

    DI HALT

    Никто тебе не запрещает запустить низковольтную мегу от 5вольт. Это ее штатное напряжение.

    nwanomaly

    у меня питание - две батарейки по полтора вольта

    Mazayac

    Работать напрямую от батареек будет, но недолго :D
    Напряжение разряженной батареи - 1В, девайс сдохнет задолго до конца ее разряда.
    Для батарейного питания ставят повышающие DC-DC преобразователи типа MAX1674-MAX1676.

    nwanomaly

    это в смысле с 3В будет постоянно 5В пока току в батарейке достаточно?

    Mazayac

    На входе - от 0.7В до 3В, на выходе - стабильные 3.5В или 5В, нужное напряжение выбирается.

    nwanomaly

    спасиб за инфу

    real13

    а под заказ можете привезти плату для мини-атс панасоник (плата kx-ta 30674) ?

    arkamax

    Бывают, но их сложно найти. Я видел на eBay и на http://www.crystalfontz.com.

    XDN

    Попробуйте МЭЛТ - они могут работать на трёшке, но с более длинными таймаутами.
    Но учтите, что инициализация несколько отличается от чистого hd44780, в остальном они совместимы.

    Cluster

    Эээ… Я в ЧипеДипе свои 24*2 покупал за 300 рублей.

    nwanomaly

    вот конкретно сегодня в одном из их магазов - не было (


  8. BaN 23 Сен 2008 17:00

    Почти во всех ЖКИ-модулях, в том числе и в ЖКИ-модулях с HD44780, перед началом работы, обязательно необходима начальная инициализация, без этого он просто не будет работать. Мб автор просто забыл про это, а может просто взял какой-то левый даташит на HD44780, тк встречал я один даташит на русском по HD44780, там было указано, что активируется ЖКИ-модуль вращением подстроечного резистора, что не является правильным, поэтому я бы посоветовал читать оригинальные даташиты, а не переведённые непонятно кем, если это было так.

    DI HALT

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

    arkamax

    Согласен полностью про баги… особенно это относится к китайским даташитам, и особенно на LCD.


  9. arkamax 23 Сен 2008 18:40

    Поздравляю с днем рождения, желаю творческих успехов, и восхищаюсь терпением излагать всю эту информацию подробно и доходчиво! Сам занимаюсь AVR-ами примерно два года, и если бы кто-нибудь тогда мне все вот так расписал… :)


  10. arkamax 23 Сен 2008 18:47

    Еще покомментирую. Дисплеи на HD44780 бывают очень разные по времени реакции на строб. Обычно дисплеи, рассчитанные на 3В, более медленные, чем на 5В, и требуют более длинных задержек при работе с ними. Удивительно, но по сравнению с HD44780 те же графические контроллеры KS0713 несмотря на бОльший объем передаваемой информации, оказались гораздо быстрее в работе - обновление монохромного экрана 128х64 занимает совсем не много времени. Очень рекомендую внимательно присмотреться к этому семейству… туда можно вывести значительно больше информации, чем на любой текстовый дисплей. И само собой, они прекрасно интерфейсятся с АВР-ами :)


  11. Susanin 23 Сен 2008 19:55

    С Днём Рождения!


  12. XDN 23 Сен 2008 19:58

    Мои поздравления!


  13. SiNil 23 Сен 2008 23:02

    С Днем рождения, DI HALT!
    Спасибо за тексты, очень интересно и познавательно.

    А элементус - это представитель “Элемента”?

    DI HALT

    Да это он. Который на Южная 2А сейчас расположен.


  14. SiNil 23 Сен 2008 23:23

    аха, только я их что то там не нашел :-/
    обошел всё здание. На днях еще попробую, может тогда еще не успели переехать.

    DI HALT

    Они там уже года два как - там раньше их оптовая база была. С торца здания 2А есть здоровенная железная дверь, похожая на гараж. Вот в нее и сразу же направо. Я тоже первый раз долго искал.


  15. SiNil 23 Сен 2008 23:43

    о_О
    Ясно, спасибо большое :)
    Ещё раз с Днём рождения!


  16. VBKesha 24 Сен 2008 4:01

    Поздравляю!!!


  17. Spir0 26 Сен 2008 12:34

    Тут спрашивали по поводу 3.3В дисплеев, HD44780 может работать и от 3.3В , но только сам контроллер, для того чтобы было видно что то на дисплее, надо подавать отрицательное напряжение на вход управления контрастом. Или брать расчитанный на 3.3В изначально (по опыту поиска огромный дефицит :) )
    Можно еще использовать от Nokia дисплеи (3310, 3410), но они графические поэтому для вывода символа надо писать свою библиотеку (в инете полно готовых), еще очень хорошие TIC32 и TIC149 тоже графические но работают как от 3.3 так и от 5В.
    Буква L в индексе контроллера указывает что он может работать от 3В , от 5В он тоже работает нормально :)


  18. BaN 01 Окт 2008 21:38

    Есть такой вопрос, может кто-нибудь сталкивался:
    Работаю с МЭЛТ’овским ЖКИ-модулем MT-16S2R, у него контроллер КБ1013ВГ6 (аналог HD44780 и KS0066).

    При работе с ним выявилась проблема, заключающаяся в том, что флаг занятости как бы зависает после команд записи в DDRAM. Т.е. я записываю какие-то данные в DDRAM и проверяю в цикле флаг ожидания, и пока он не станет равен нулю, те контроллер не будет готов выполнить следующую команду, дальше ничего не делаю.
    Но дело в том, что этот флаг после записи данных в DDRAM не устанавливается в 0 сколько не жди, т.е. все время показывает, будто контроллер занят. Хотя если сделать не проверку флага занятости, а просто задержку времени в 40мкс (это максимальное время записи в DDRAM по документации), то он нормально записывает данные в DDRAM и готов выполнить следующую команду.
    Но тот же флаг занятости при выполнении обычной команды, которая не изменяет DDRAM, нормально показывает занят контроллер или нет.
    Флаг занятости также как и в случае с записью в DDRAM, не изменяется после выполнения команды установки адреса для последующих операций и выбора области DDRAM.
    Похоже, что флаг занятости не изменяется контроллером, если выполнялось какое-то изменение в DDRAM.
    В документации на ЖКИ-модуть и на контроллеры КБ1013ВГ6 и HD44780 (на KS0066 я не смотрел) ничего об этом не сказано, поэтому я и хотел спросить, не встречался ли кто с подобным?
    Если кто-то сталкивался с подобным, я был бы очень признателен за разъяснение этой ситуации.

    Сам просто стал проверять флаг занятости только после команд, не изменяющих DDRAM, а для тех, что изменяют DDRAM делал задержку.
    Собственно кусок кода проверки флага занятости:
    8-битный интерфейс. PORTA - шина данных, PINC5 - RS, PINC6 - R/W, PINC7 - E:

    CBI PORTC, 5
    L0:
    SBI PORTC, 6
    SBI PORTC, 7
    NOP
    NOP
    IN TMP_PRG, PORTA
    ANDI TMP_PRG, 0B10000000
    CBI PORTC, 7
    CBI PORTC, 6
    CPI TMP_PRG, 0
    BRNE L0

    XDN

    Я работаю с МЭЛТами. Ничего подобного за ними не замечал. Флаг занятости успешно выставляется как после записи в DDRAM, так и при любой другой операции.
    Нет возможности проверить на другом модуле?

    BaN

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

    BaN

    Проверять на другом модуле не пришлось, нашел ошибку у себя в коде )
    Нужно было правильно сделать проверку флага занятости так:
    CLR TMP_PRG
    OUT DDRA,TMP_PRG
    OUT PORTA,ZERO
    Label:
    SBI PORTC, 6
    SBI PORTC, 7
    NOP
    NOP
    IN TMP_PRG, PINA
    ANDI TMP_PRG, 0B10000000
    CBI PORTC, 7
    CBI PORTC, 6
    CPI TMP_PRG, 0
    BRNE Label
    SER TMP_PRG
    OUT DDRA,TMP_PRG
    А я забыл очистить содержимое порта, после того, как выводил в ЖКИ команды установки адреса для последующих операций и выбора области DDRAM и после записи данных в DDRAM, поэтому бит занятости оставался равным единице все время.


  19. RA3PKJ 04 Окт 2008 22:47

    to DI HALT
    Здравствуйте!
    Однако давно ищу код для сопряжения AVR c HD44780, так как сам начинающий и не могу это осилить. Буду ждать.
    ——————
    Николай RA3PKJ

    DI HALT

    Если хошь, то могу тебе замылить бета версию. Там все работает, но реализована только передача по 8разрядной шине. Нужно будет только чуток переделать :)

    RA3PKJ

    OK!
    Годится на передачу только.
    Спасибо.
    ————
    Николай.
    ra3pkj—yandex.ru

    DI HALT

    http://easyelectronics.ru/files/MultiDebug2.rar
    вот держи. Думаю догнишь что там к чему. Расчитано изначально на мегу8535


  20. RA3PKJ 05 Окт 2008 0:50

    Получил. У меня AT90S8515.
    Буду разбираться. Еще раз спасибо.

    DI HALT

    Выложил полную версию либы.
    http://easyelectronics.ru/avr-uchebnyj-kurs-biblioteka-dlya-lcd-na-baze-hd44780.html


  21. penzet 11 Окт 2008 15:29

    Управление LCD-дисплеем HD44780 по одному проводу
    Автор Noureddine Benabadji
    18.03.2008 г.
    LCD-дисплеи с контроллером HD44780 являются пожалуй одними из самых популярных символьных дисплеев для встраиваемых систем. Единственным их недостатком можно считать необходимость задействования для управления дисплеем шести I/O-линий микроконтроллера в 4-разрядном режиме либо одиннадцати I/O-линий в 8-разрядном режиме. Для сокращения числа управляющих линий можно использовать преобразователи последовательного кода в параллельный на основе стандартной логики. Однако, управлять HD44780-совместимыми LCD-дисплеями можно даже по одной линии. Такую функцию гораздо удобнее возложить не на микросхемы жёсткой логики, а на программируемый микроконтроллер, сократив, таким образом, стоимость и занимаемую схемой на печатной плате площадь. Этим целям в полной мере удовлетворяют микроконтроллеры Microchip серии PIC10F в миниатюрном корпусе SOT23–6.

    Схемотехническое решение, показанное на рисунке, может оказаться полезным для многих встраиваемых систем с ограниченным числом выводов, потому как способно управлять HD44780-совместимыми LCD-дисплеями посредством однопроводной линии передачи данных, задействуя простой асинхронный RS232 протокол на скорости 9600baud. В схеме применён PIC10F202, но подойдёт любой микроконтроллер из этого семейства, потому что хорошо оптимизированный программный код (прошивка 1) состоит из всего лишь 256 слов. Увеличить скорость выше 9600baud не представляется возможным, так как PIC10F202 содержит внутренний RC-генератор с точностью 1%, а LCD-дисплей требует задержку длиной 1.6ms для некоторых инструкций, таких как «очистка дисплея». Программный код представлен в виде исходников с комментариями для LCD232 модуля; основная программа состоит из дисплейной заставки на 2 секунды и дальнейшего бесконечного цикла для ожидания 1 байта команды, максимум 16 байт данных и нуля ASCII. В тестовых целях сопряжения дисплея с внешней встраиваемой PIC-системой можно воспользоваться простой прошивкой на ассемблере (прошивка 2).


  22. Andrew 13 Фев 2009 9:51

    Может, кому поможет, чтоб не искать алгоритмы. Тут нарыл деление числа на цифры, для вывода на ЖКИ http://elm-chan.org/cc_e.html


  23. RA3PKJ 13 Фев 2009 12:55

    Спасибо.
    Мне нужно.
    Буду смотреть.


  24. RA3PKJ 13 Фев 2009 13:19

    Что-то пока не разберусь где смотреть на этой страничке.
    У меня 8-разрядный режим.

    DI HALT

    В самом низу записи ссылка на вторую часть.
    http://easyelectronics.ru/avr-uchebnyj-kurs-biblioteka-dlya-lcd-na-baze-hd44780.html


  25. xrayman 20 марта 2009 5:22

    Как раз вчера-позавчера ковырял индикатор BC1602, долго думал почему он у меня не хочет работать, заодно нашел опечатку в статье.

    >># 01001001 Выбираем в CGRAM адрес 0х09 - как раз начало второго символа (напомню, что на один
    >>символ уходит 8 байт)

    Начало второго символа это 1000, а не 1001. Т.е. первый символ - 01000000, второй - 01001000, третий 01010000 и т.д.

    А у меня не работал потому, что я на ногу контрастности подавал 2,5В, а он, сцуко, после ~1,1В перестает показывать. Два дня парился, пока не догадался подключить переменный резистор на контрастность… :(

    P.S.
    >>Всего в CGRAM может быть 8 символов, соответственно CGRAM имеет 64 байта памяти. Эти программируемые символы имеют коды от 0х00 до 0х08.

    Если их 8, то от 0х00 до 0х07


  26. rootofevil 08 июня 2009 1:08

    Приветствую! Прекрасная статья по LCD!

    Теперь по теме:

    В тексте
    >I/D - инкремент или декремент счетчика адреса. По дефолту стоит 0 - инкремент. Т.е. >каждый следующий байт будет записан в n+1 ячейку. Если поставить 1 - будет декремент.

    присутствует ошибка.
    Все наоборот.
    I/D=1 - инкремент (0 - декремент)

    Обоснование - пример из datasheet на KS0066U (Samsung):

    I/D: Increment / decrement of DDRAM address (cursor or blink)
    When I/D = “ High” , cursor/blink moves to right and DDRAM address is increased by 1.
    When I/D = “ Low” , cursor/blink moves to left and DDRAM address is decreased by 1.

    DI HALT

    Спасибо. Fixed


  27. triton 10 июня 2009 2:21

    а где схема в lay формате, хотелось бы собрать такой прибор.

    DI HALT

    Какого прибора?

    triton

    как какого, как подключить дисплей к avr+ кнопки.

    DI HALT

    Так сам разведи, там же сложного ничего нет - подвести линии от дисплея до МК и на кнопки вывести.

    triton

    просто я новичек и не очень понимаю, хотя бы принципиальную схему, более точную.

    DI HALT

    http://easyelectronics.ru/files/AVR/LCD.lay
    вот можешь тут поглядеть. Там все просто.


  28. dobry_bobr 10 июля 2009 20:55

    а кто-нибудь с MT-16S2D работал?
    накидал код (могу сюда закопипастить), модель протеусовская работает, а на реальном железе - нет.

    dobry_bobr

    delay_ms(100);
    lcd_com(0b00111111);
    delay_ms(10);
    lcd_com(0b00111111);
    delay_ms(10);
    lcd_com(0b00111111);
    delay_ms(10);
    lcd_com(0b00111000);
    delay_ms(1);
    busy();
    lcd_com(0b00001000); /*!!!*/
    delay_ms(1);
    busy();
    lcd_com(0b00000001);
    delay_ms(1);
    busy();
    lcd_com(0b00000110);
    delay_ms(1);
    busy();
    lcd_com(0b00001100); /*vkl*/
    busy();

    dansar

    У меня в протеусе тоже криво работает. LCD не меняет бит, который говорит, что LCD занят. Убери в коде цикл ожидания этого бита, просто поставь задержку.

    dobry_bobr

    уже всё пофиксил, уже всё работает))


  29. SHALIAN 27 июля 2009 18:45

    Народ, часом не юзал ли кто вот такую платку: http://www.platan.ru/cgi-bin/qwery.pl/id=560075685&group=50236 вроде по минимуму все есть и цена приемлемая? Вот хочу с нее попробовать начать :)

    DI HALT

    Платка как платка. Мощная аврка, да интерфейсы. В принципе, самому такую спаять не сложно.


  30. SHALIAN 27 июля 2009 21:11

    Спасибо, DI! Умеешь ты оптимизму добавить. :)) Думаю мне ее на доооолго хватит. Пока порты не выпалю. :))))

    DI HALT

    Или пока фузы не залочишь ;)

    Мой те совет — шей ее через бутлоадер STK500 (написано что она уже прошита им). В таком случае убить ее надо постараться. Бутлоадер ничего критичного сделать с МК не сможет.


  31. SHALIAN 27 июля 2009 22:19

    Эх, я с МК очччень на ВЫ. И есче не очень разобрался как шить через бутлоадер, да и вообще что это такое. :))))))

    DI HALT

    Бутлоадер это такая микропрошивка (не более 2кб) распологается в специальной области памяти. При старте вначале стартует бут, он по UART (Com порт или USB2COM) засасывает в себя прошивку и сам ее размещает в памяти.

    После прошивки бут стартует МК уже с залитого кода.


  32. SHALIAN 27 июля 2009 23:07

    Я так понимаю эт надо STK500 покурить? Бутлоадер под нее ведь написан. Как процик в бут загнать? Опять же интерфейс….. Пока тока вопросы. :)

    DI HALT

    МК с бутом подключается к COM порту (реальному или виртуальному) и AVR Studio почуяв его позывные говорит, мол О! У нас есть STK500!


  33. SHALIAN 28 июля 2009 0:26

    Тоесть специально проц в бут загонять не надо? AVR Studio сама сканит СОМ на наличие бута в процике?


  34. SHALIAN 28 июля 2009 0:29

    А если прошка в проце уже есть перешить тоже тока через бутлоадер?

    DI HALT

    Да нет, взял подключился обычным программатором по ISP и снес бут вместе со всей прошивкой нахрен. Ну или обратно его вернул. Или вообще другой поставил. Но я тебе пока это не рекомендую — одно неосторожне движение с fuse и ты заблокировал кристал наглухо.


  35. SHALIAN 28 июля 2009 0:31

    Я к тому что обойти его уже ни как?


  36. DI HALT 28 июля 2009 0:44

    Да, бутлоадер при старте слушает порт. Если в течении какого то времени не произошло ничего - стартует основную прошивку.

    А студия отслеживает наличие ответа бута на порту.

    Обычно делается как. Ты жмешь на контроллере RESET и в течении секунды-двух тебе надо нажать на кнопку в студии (или наоборот) и тогда бут и студия найдут и поймут друг друга.

    SHALIAN

    Дааа! Бутлоадер избавляет от оч многих заморочек!


  37. SHALIAN 28 июля 2009 0:57

    Не, DI. Тебе явно надо в преподы идти, причем к олегофренам.:))))))))))) Так мне даже в живую никто не обьяснял. Я про сайт вообще и про МК в частности! Спасибо большое!!! :)

    DI HALT

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

    dima_m

    Ты был преподавателем? Прикольно. Что преподавал то? Ассемблер? Да современным преподам тяжело, сегодня в этой сфере нужно иметь нервы еще те (железные). Новое поколение становится все более деградированное. Если не построить сразу, потом на шею сядут и на голову все вместе.

    Прикупил сегодня дисплей на 2×16. 270 руб. Будем запускать по написанному… в космос…

    DI HALT

    Электронику и микропроцессорные системы. В том числе и ассемблер.


  38. roan 06 Сен 2009 0:56

    А можно проконсультроваться? Нашел тут схемку для подключения HD44780 с управлением контрастностью и подсветкой через контроллер:

    http://www.harbaum.org/till/lcd2usb/schematic.gif

    Был бы очень признателен за комментарий относительно корректности данного решения (контрастность - через LC контур, подсветка - через транзистор и токоограничительные резисторы). Особенно интересует LC контур: вроде бы понятно, что он там для сглаживания сигнала с PWM, но к сожалению, ограниченные знания не позволяют дотумкать, почему сам контроллер фактически включен _внутрь_ контура.

    DI HALT

    Вполне корректно. НА контраст таким образом подается ШИМ напряжение сглаженное LC фильтром. Вместо индуктивности там, думаю, можно вкрутить сопротивление на 1К, должно работать не хуже.

    А с LC как получается - чтобы не пожечь выход МК надо ограничивать ток заряда/разряда конденсатора. Тут индуктивность ограничивает ток, а кондер гладит напряжение.


  39. maxisize 07 Окт 2009 5:10

    Полезная статья!
    а вот Мой случай.
    Купил как то
    HY-1601C-405… дальше не важно…
    Как видно 16 символов 1 строка
    Как ни бьюсь, не могу включить
    вторые восемь символов.
    После установки в FUNCTION Set
    еденицы, отвечающей за 2 строки
    Инициализация проходит так что
    на экране и первая строка
    пропадает.
    Может кто сталкивался с
    таким индикатором?

    SAShA_II

    Во-во. И у меня такая проблема. Экран WM С-1601 шестнадцать символов, одна строка. Влкючаются только первые восемь символов. Экран на HD44780. Работаю по 8бит. Может быть такое, что для инициализации однострочных экранов какие-то другие каманды? Или экран битый? Если он не правильно инициализирован при регулировке контраста должны быть видны все символы? У меня только 8 видно? В чем может быть проблемма?

    P.S. АВТОРУ САЙТА: Сайт классный, читаю не нарадуюсь. Всё разжевано до нельзя. Так держать. Молодец!!!!!!!!!!!

    DI HALT

    Эмм… почитай документацию на контроллер. Попробуй взять и забить последовательно ему всю видеопамять. МОжет у него она как то хитро на куски побита?

    SAShA_II

    Всем спасибо, разобрался. Перед инициализацией поставил задержку, загорелись обе половинки. А он оказывается устроен полностью как двухстрочный. Первые 8 символов - 1я первая строка, вторые 8 символов - 2я строка. Блин. Это дибилизм какой-то. Очень не удобно работать когда 9-ый символ находится почти в 40-а ячейках от восьмого. О чем думали создатели…


  40. SAShA_II 18 Окт 2009 0:03

    А можно как-то прошить русские символы в неруссифицированный экран, кроме как запись своих символов в CGRAM (маловато там свободного места слишком)?

    DI HALT

    Нельзя

    Dimas D

    Если особо запариться то можно, каждый раз эти 8 символов перезаписывать теми буквами которых не хватает. А если еще немного запариться то можно 16 перезаписывать, только прога будет постоянно занята работой с дисплейем.
    См. комент ниже Dimas D 13 Дек 2009 12:33


  41. dudnik_m 22 Окт 2009 0:44

    Здравствуйте.
    Долго изучал Ваши материалы. Все. Спасибо за работу и желание поделиться с другими. Но, сегодня встретился с проблемой решение которой пока не нашел, поэтому обращаюсь к Вам. Подскажите, пожалуйста, как организовать обмен информацией между AG12232A и ATmega8535 - 16PU. Буду благодарен за любую информацию.
    С уважением, MiD


  42. Name4Me 20 Ноя 2009 17:40

    интерисует вопрос есть ли возможность проверить дисплей а то ни какой реукции на команди нет на екране сплошние чорние квадратики…

    DI HALT

    Попробуй сделать инициализацию дисплея не сразу, а спустя 100ms после старта МК. Или запусти всю плату, а потом сделай сброс контроллеру, чтобы дисплей успел инициализироваться.

    Вообще если квадратики есть, значит вроде как рабочий. Если нигде не затупил с кодом, то должно работать.

    Можешь мою либу попробовать подключить. Я ей уже производителей 5 разных дисплеев опробовал - везде работает четко ,как надо.


  43. Name4Me 20 Ноя 2009 18:59

    Ммм Благодаря танцам с бубном вопрос снят но для меня загадка (почему :) так как ни инициализация с даной статьи ни с дататашита 2 дня не проходила :) а сегодня сцуко взяло и заработало хотя со вчера ни чего не менял кроме как устанувил ожидание нажатия кнопки перед каждим шагом инициализации… Имхо проблема что вибрал слишком маленькие паузи между шагами… хотя хз)


  44. Name4Me 20 Ноя 2009 22:53

    Автору респект биг спс за статьи!
    Имхо в макросах в макросе WR_CGADR
    Лучше указать LDI R17,(1<<LCD_CGRAM)|(@0*8)

    И ещо подскажите как вивесть строку я вивожу таким макросом:
    .MACRO WR_MSG
    LDI ZH,High(@0*2)
    LDI ZL,Low(@0*2)
    WR_MSG_Load: LPM R17, Z+
    CPI R17,0
    BREQ WR_MSG_End
    RCALL DATA_WR
    RJMP WR_MSG_Load

    WR_MSG_End:
    .ENDMACRO

    Собствено сам вивод:
    msg: .db “Ready”,0
    WR_MSG msg

    Всё виводит но интересует может есть более оптимальний способ

    Name4Me

    .MACRO WR_MSG
    LDI ZH,High(@0*2)
    LDI ZL,Low(@0*2)
    RCALL MSG_WR
    .ENDMACRO

    .MACRO WR_NewS ; Position, symbol
    WR_CGADR @0
    LDI ZH,High(@1*2)
    LDI ZL,Low(@1*2)
    RCALL MSG_WR
    .ENDM

    MSG_WR: LPM R17, Z+
    CPI R17,0
    BREQ MSG_WR_End
    RCALL DATA_WR
    RJMP MSG_WR
    MSG_WR_End: RET

    Собственно работает так
    msg: .db “Ready”,0
    s1: .db 1,2,4,31,2,4,8,16,0,0 ; символ Flash
    sii: .db 32,32,10,32,4,4,4,32,0,0 ; символ ї

    WR_MSG msg

    WR_NewS 0,s1
    WR_NewS 1,sii

    LCD_COORD 0,1
    WR_DATA 0
    WR_DATA 1


  45. Dimas D 13 Дек 2009 12:33

    По поводу 3В питания:
    есть у меня дисплей WH1602B-YGK-CTK WINSTAR(2 строки по 16 символов), расчитанный на 5В, но я особо не парился и всегда его подключал на 3.3В по стандартной схеме и сопротивление контрастности тоже включал между 3.3 и 0. Работает замечательно.

    Еще на нем график рисовал (можно вообще любой рисунок делать), для этого есть графические дисплеи, но они дороже:
    суть следующая можно просто в перезаписываемые символы занести то что надо и отобразить, но их всего 8(, а хотелось как минимум 16. Для этого поступал сдедующим образом:
    в первой строке 8 символов, а во второй отображал 8 черных квадратов, перезаписывал символы
    и делал наоборот: в первой стороке черные а во второй записанные символы.
    Потом настраиваем контрастность так что бы фон черного квадрата не был видет, при этом выглядит это не плохо, от обычных символо трудно отличить.
    Зы: можно сделать и 24 спецсимвола но контрастность будет не очень, а при 32 вообще фигня.
    Только обязательно заменять черным квадратом, если белым менять то в символах точки получались с разным оттенками)

    DI HALT

    Вот у меня как раз сейчас в плате стоит этот дисплей. Именно йгк стк не хочет он работать от 3.3 вольт :(

    Dimas D

    может быстро данные передаешь.
    у меня msp430 на 1МГц, работала все нормально было, задержка была только при включении
    что бы дисплей успел загрузиться.

    Dimas D

    Но на 2МГц не работал, даже когда задержки поставил, лень было разбираться, и так устраивало.

    DI HALT

    У меня даже дисплей не стартует, не появляются квадратики символьные.

    Dimas D

    Я ошибся немного, сейчас посмотрел у меня было 3.6В.
    но скоро хочу еще одну схему собирать, теперь похоже придется ее тоже от 3.6 питать.
    Думаю до нового года помучать дисплей, посмотреть что его устраивает.


  46. Ageofenigma 21 Дек 2009 12:23

    Блин, не могу понять каким образом можно выводить данные с АЦП (непрерывный режим) на этот дисплей……Кто нибудь знает как енто огранизовать?


  47. AiEX 12 Янв 2010 21:00

    Доброе время суток!
    Может я немного не по теме, но собрал я тут одну приколюху для подключения
    LCD дисплея к компу по USB на меге-8
    http://www.harbaum.org/till/lcd2usb/index.shtml
    Всё чудесно кроме отображения русских символов.
    Дисплей с русским знакогенератором.Может его инициализировать както по другому надо?
    Не подскажете? Исходники прошивки и драйвера имеются.

    DI HALT

    Проблема тут в том, что коды русских символов в дисплее не совпадают ни с одной из комповых кодировок. Есть специальные программки перекодировщики.


  48. Igor 24 Янв 2010 3:53

    Доброе время суток!
    У меня возникла проблема с ЛСД.Первый ряд подмигивает а второй маргает .Общую частоту
    задержек пробовал именять чуть луше стало.В противном случае реже маргает или второй
    ряд становится блеклым.4 бита система контрасность на максимуме


  49. Stalker46 30 Янв 2010 21:08

    Написал программу. Тут и инициализация и заносим некоторые данные.
    Помогите ее довести до ума. Чего не хватает, что где добавить и почему так.
    Я только учусь ассемблеру.
    И зачем считывать флаг занятости и что это вообще и для чего он нужен.
    ЗАРАНЕЕ ОГРОМНОЕ СПАСИБО!!!
    Итак, код:

    ; LCD
    ————————————–
    ; Инициализация дисплея
    ————————————–
    .def Temp=R16
    .def Temp1=R17
    .def Temp2=R18
    .def Temp3=R19
    .def Temp4=R20

    .cseg
    .org 0

    ; RS = 0bits portc
    ; E = 1bits portc
    ; RW = 2bits portc

    ; Подключили питание
    rcall delay1s ; Выжидаем 1 секунду
    ldi Temp, 0b11111111
    out ddrc, temp ; Настройка портов C
    ldi Temp1, 0b11111111
    out ddrd, temp1 ; Настройка портов D

    sbi portc, 1 ; Устанавливаем Е в 1 (пока что готовимся)
    cbi portc, 2 ; Сбрасываем RW в 0 (режим записи)
    cbi portc, 0 ; Сбрасываем RS в 0 (режим занесения команд)

    ldi temp1, 0b00110000 ; загружаем настройки разрядности
    out portd, temp1 ; выводим ее в lcd
    cbi portc, 1 ; Поехала первая команда в LCD
    rcall delay50mks ; Ждем 50мкс (немного выше, чем нижний предел)

    sbi portc, 1 ; опять строб на 1

    ldi temp1, 0b00110000 ; Снова настройки разрядности
    out portd, temp1 ; выводим в LCD
    cbi portc, 1 ; выдаем в дисплей, строб
    rcall delay50mks ; снова ждем 50мкс

    sbi portc, 1 ; опять строб на 1

    ldi temp1, 0b00110000 ; Снова настройки разрядности
    out portd, temp1 ; выводим в LCD
    cbi portc, 1 ; выдаем в дисплей, строб
    rcall delay50mks ; снова ждем 50мкс

    sbi portc, 1 ; опять строб на 1

    ldi temp1, 0b00111000 ; устанавливаем 8разр. шина данных, две строки, размер матрицы - 5х8т
    out portd, temp1; Выводим
    cbi portc, 1 ; Пли!!! Строб
    rcall delay50mks ; Пауза

    sbi portc, 1 ; опять строб на 1

    ldi temp1, 0b00001000 ; Выключаем дисплей
    out portd, temp1 ; Выводим
    cbi portc, 1 ; Пли!!! Строб
    rcall delay50mks ; Пауза

    sbi portc, 1 ; опять строб на 1

    ldi temp1, 0b00000001; Очистка дисплея
    out portd, temp1 ; Выводим
    cbi portc, 1 ; Пли!!! Строб
    rcall delay1ms ; Пауза в 1 милисекунду

    sbi portc, 1 ; опять строб на 1

    ldi temp1, 0b00000110 ; Курсор сдвигается вправо, без сдвига экрана
    out portd, temp1 ; Выводим
    cbi portc, 1 ; Пли!!! Строб
    rcall delay50mks ; Пауза

    ;————————————–
    ;Инициализация, конец
    ;————————————–

    ;————————————–
    ;Что-нибудь выведем
    ;————————————–

    sbi portc, 1 ; опять строб на 1
    sbi portc, 0 ; Теперь работаем с данными

    ldi temp1, 0b10100101 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;
    sbi portc, 1 ;
    ldi temp1, 0b10111011 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1 ;
    ldi temp1, 0b11000100 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1 ;
    ldi temp1, 0b10111000 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1 ;
    ldi temp1, 0b10111101 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1 ;
    ldi temp1, 0b01000101 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1 ;
    ldi temp1, 0b10110011 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1 ;
    ldi temp1, 0b10110100 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1 ;
    ldi temp1, 0b01100101 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1 ;
    ldi temp1, 0b10111101 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1 ;
    ldi temp1, 0b110111000 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1 ;
    ldi temp1, 0b10111001 ;
    out portd, temp1 ;
    cbi portc, 1 ;
    rcall delay50mks ;

    sbi portc, 1;

    cbi portc, 0 ; работа с командами:

    ldi temp1, 0b00001100 ; Включаем дислпей
    out portd, temp1 ; Выводим
    cbi portc, 1 ; Пли!!! Строб
    rcall delay50mks ; Пауза

    sbi portc, 1; Е в 1

    DI HALT

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


  50. Stalker46 30 Янв 2010 21:29

    Это, например, в том случае, если задержку сделал меньше минимально допустимой, например, 30мкс, вместо 40мкс?

    Приведи пример кода, как и КОГДА надо проверять флаг занятости…

    И что с кодом - все правильно?

    DI HALT

    В целом да, достаточно просто подождать, чтобы гарантированно быть уверенынм, что дисплей прожевал данные.

    Код не смотрел.


  51. Stalker46 30 Янв 2010 23:41

    Посмотри, пожалуйста. Внеси изменения, если таковы требуются. Если, конечно же у тебя есть время))) (надеюсь будет).
    Просто я пытаюсь учить ассемблер путем изобретания велосипедов :)

    DI HALT

    У тебя код нечитаем совершенно. Мне проще с нуля его написать, чем разбирать. Биты неименованные. Привыкай использовать макроопределения везде где можно.


  52. Stalker46 31 Янв 2010 0:44

    ; RS = 0bits portc
    ; E = 1bits portc
    ; RW = 2bits portc
    к порту д я подключил шину данных.

    А я как то не могу разобраться в твоих библиотеках, т.к там нет коментариев…

    DI HALT

    поглядел lcd4.asm прокомментирована там чуть ли не каждая строчка.


  53. Stalker46 31 Янв 2010 2:31

    … так это же код для 8 битного подключения! а у меня 8 битное…

    DI HALT

    так разница там минимальная. Только в строке инициализации дисплея команды чуток другие и все.


  54. Stalker46 31 Янв 2010 15:06

    Вообщем, положу я пока дисплей в сторону, т.к. там еще надо высчитывать периоды сигналов Е, и других…


  55. Maxim123 08 Фев 2010 20:32

    Здравствуйте.
    Что это за проводки такие в розовой изоляции? Вижу из повсюду, но только на фотках, на радиорынке не встречал :( Мне кто-то говорил, что они какие-то там специальные и дорогие очень, лапши навешали? Они как-то особо называются?

    DI HALT

    Это МГТФ. Провод не дешевый (метр стоит около 10-15р), но очень мягкий, гибкий и прочный на излом (правда не в месте пайки, там ломается быстрей обычного т.к. ворсинки тонкие и их просто вырывает при жеской фиксации. Надо фиксировать отдельно чуть подаль от пайки, как у меня на фотке)


  56. jon_m 16 Фев 2010 22:05

    здравствуйте, пытаюсь освоить AVR+LCD использую Atmega8 внутренний генератор 8Мгц, 8 проводов, дисплей WH1601L-YGH-CT[1] снял с принтера чеков, там работает, только иногда портит данные из CGRAM (выводит не то что записано) индикация нормальная.
    Извеняюсь за тупой вопрос, подобное тут уже было, но я не понял.
    вопщем пытаюсь вывести при помощи такого кода:
    .include “m8def.inc”
    .include “F:\AVR\Projects\LCD\LCD_macro.inc”
    .MACRO outi
    LDI R16,@1
    OUT @0,R16
    .ENDMACRO
    .ORG INT_VECTORS_SIZE
    Reset:
    OUTI spl,LOW(RAMEND)
    OUTI sph,HIGH(RAMEND)
    INIT_LCD
    LCDCLR

    WR_DATA ‘E’
    WR_DATA ‘B’
    WR_DATA 0xa1
    WR_DATA ‘E’
    WR_DATA ‘H’
    WR_DATA 0xa5
    WR_DATA 0xa6
    WR_DATA 0×20
    WR_DATA ‘E’
    WR_DATA ‘B’
    WR_DATA 0xa1
    WR_DATA ‘E’
    WR_DATA ‘H’
    WR_DATA 0xa5
    WR_DATA 0xa6
    Loop:
    RJMP Loop
    .include “F:\AVR\Projects\LCD\LCD.asm”
    ваводится только 8 разрядов, как остальное вывести?
    и еще после wr_data ставлю r20 предварительно записав данные при помощи ldi r20,0xa6
    чет не выводит. Помогите начинающему сдвинуться с мертвой точки.

    DI HALT

    Он у тебя продолжает выводить, но в невидимую часть экрана. У твоего дисплея поди хитро разбит экран. Т.е. первые два символа на одной строке, вторые на другой (под строкой я имею ввиду тут строки видеопамяти)

    Тебе надо курсор сместить на нужное число позиций. Заюзай для этого спец макрос.

    А как выяснить куда? А это просто. Тупо гони в видеопамять аски коды от позиции 00 до тех пока вся видео память не заполнится (скажем по коду в секунду) скоро ты увидишь как у тебя начнет заполняться твои другие 8 символов.

    Ну или даташит погляди ;)

    jon_m

    спасибо за подсказку, индикатор какой то странный, он как двустрочный, но в одну строку, с первого адреса по восьмой отражает, потом до 40 нет после 40 по 48 опять в тоже место.
    поэкспериментировал с командой LCD_COORD Х,У, Выводит во вторую половину полько при значениях 40,2.
    Подскажите, а что эту команду только 1раз можно использовать?
    Сделал так:
    WR_DATA ‘E’
    WR_DATA ‘B’
    WR_DATA 0xa1
    WR_DATA ‘E’
    WR_DATA ‘H’
    lcd_coord 8,1
    WR_DATA ‘-’
    lcd_coord 40,2
    WR_DATA ‘E’
    WR_DATA ‘B’
    WR_DATA 0xa1
    WR_DATA ‘E’
    WR_DATA ‘H’
    между 7 и 9 символом ни чего не появилось.
    И еще ткните, как мне данные из регистра на экран вывести, у вас написано использовать r17,
    делаю так: ldi r17,r20
    wr_data r17
    на экране ни чего, и ошибок нет.
    Может по электронке пообщаться, чтоб глупостями не засорять?

    DI HALT

    Ну у него адресация только до 40, дальше заново.

    Вроде бы можно сколько угодно раз. Она же только СГ рам счетчик меняет и все.


  57. R_ura 14 марта 2010 15:34

    Di, прошу прощения, если не в ту тему вопрос, но как-то сложно по сайту ориентироваться.
    Решил я немного разобраться с Си. Решил начать с подключения ЖКИ. У меня собрана макетная плата устройства. Есть там и ЖКИ. Причем все рабочее на 100%, т.к. на асме все прекрасно работает. Нашел несколько примеров простеньких программ. Но нихрена не работает. Единственное отличие у меня от взятых примеров - RS подключен к PD2, E к PD3, остальные же DB4, DB5, DB6, DB7 к старшим ьитам того же порта D. Ну так я RS, E и переопределил соответственно со своей схемой. Да, еще у меня индикатор не 2 строчный (как в примере) а 4 строчный по 20 знаков. Уже убиваю второй выходной - не могу понять, почему выдается какая-то белиберда на все строчки. Помнится мне с асмовским вариантом разобрался максимум за час. Вот что здесь не так? Если не трудно - взгляни навскидку.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    
    #include          //Библиотека ввода-вывода =4
    #define RS PD2    //Условное имя для сигнала RS (ЖКИ) =5   
    #define EN PD3     //Условное имя для сигнала E (ЖКИ) =6   
    #define TIME 2 //Задержки на 20 мкс при частоте 1 МГц =7
    //-------------Функция задержки времени-------------- =8
    void pause(unsigned int a) //"a" - длительность паузы =9
    { unsigned int cn;           //"c" - счетчик времени =10
      for (cn=a; cn > 0; cn--);  //Цикл задержки времени =11
    }                        //Окончание функции "pause" =12
    //---------Функция записи команды в ЖКИ------------- =13
    void lcd_com(unsigned char p)   //"p" - байт команды =14
    { PORTD &= ~_BV(RS);                       //Сигнал RS=0 =24
      PORTD |= _BV(EN);                        //Сигнал EN=1  =25
      PORTD &= 0x0F; PORTD |= (p & 0xF0);    //Старший ниббл =26
      pause(TIME);                 //Длительность сигнала EN =27
      //_delay_loop_2(3000);
      PORTD &= ~_BV(EN);   //EN=0, фронт записи команд в ЖКИ =28
      pause(TIME);                 //Длительность сигнала EN =29
      //_delay_loop_2(3000);
      PORTD |= _BV(EN);                        //Сигнал EN=1 =30
      PORTD &= 0x0F; PORTD |= (p << 4);      //Младший ниббл =31
     pause(TIME);                 //Длительность сигнала EN =32
      //_delay_loop_2(3000);
      PORTD &= ~_BV(EN);   //EN=0, фронт записи команд в ЖКИ =33
      pause(5*TIME);          //Пауза для выполнения команды =34
    }//_delay_loop_2(3000);  //Окончание функции "lcd_com" =35
    //---------Функция записи данных в ЖКИ-------------- =22
    void lcd_dat(unsigned char p)    //"p" - байт данных =23
    { PORTD |= _BV(RS) | _BV(EN);       //Сигналы RS=1, EN=1 =38
      PORTD &= 0x0F; PORTD |= (p & 0xF0);    //Старший ниббл =39
      pause(TIME);                 //Длительность сигнала EN =40
      PORTD &= ~_BV(EN);   //EN=0, фронт записи данных в ЖКИ =41
      pause(TIME);                 //Длительность сигнала EN =42
      PORTD |= _BV(EN);                        //Сигнал EN=1 =43
      PORTD &= 0x0F; PORTD |= (p << 4);      //Младший ниббл =44
      pause(TIME);                 //Длительность сигнала EN =45
      PORTD &= ~_BV(EN);   //EN=0, фронт записи данных в ЖКИ =46
      pause(5*TIME);          //Пауза для выполнения команды =47
    }                          //Окончание функции "lcd_dat" =48
    //---------Функция инициализации ЖКИ---------------- =30
    void lcd_init(void)   //Режим 8 бит, мигающий курсор =31
    { lcd_com(0x33);
     pause(500*TIME);           //Подготовка =51
      lcd_com(0x32); 
      lcd_com(0x28);        //4 бит, 2 строки =52
     lcd_com(0x08);             //Полное выключение дисплея =53
     lcd_com(0x01);
     pause(1000*TIME);     //Очистка дисплея =54
      lcd_com(0x06);                  //Сдвиг курсора вправо =55
      lcd_com(0x0D);    //Включение дисплея, мигающий курсор =56
    }                         //Окончание функции "lcd_init" =57
    //==============ОСНОВНАЯ ПРОГРАММА================== =40
    int main(void)      //Проверка знакогенератора 0-255 =41
    { unsigned char cifra=0, b;               //Счетчикм =42
      PORTB = DDRD = 0xFF; //В=входы с резист., D=выходы =42
      PORTC = 0xF8; DDRC = 0x07;  //PC0-3 выходы с лог.0 =43
      lcd_init();      //Инициализация ЖКИ (8 бит, 16х2) =44
      while (1)                       //Бесконечный цикл =45
    {	lcd_com(0x0C);      //Удаление видимости курсора =46
      lcd_com(0x86);    //Курсор на шестое слева место =47
      lcd_dat(cifra/100 + 0x30);               //Сотни =48
        lcd_dat((cifra/10)%10 + 0x30);         //Десятки =49
        lcd_dat(cifra%10 +0x30);               //Единицы =50
     lcd_dat('=');                    //Знак равенста =51
        lcd_dat(cifra);     //Содержимое знакогенератора =52
     for (b=0; b &lt; 10; b++) pause(25000); //Пауза 1 с =53
     lcd_com(0x80);    //Курсор на шестое слева место =54
     for (b=0; b< 5; b++) lcd_dat(' ');    //Очистка =55
     cifra++;      //Следующий символ знакогенератора =56
    		}           //Окончание функции "while" =57
    }       //WinAVR-20050214, длина HEX-кода 340 байтов =58

    Еще вопрос - в симуляторе AVRStudio паузы почему-то добавляют по времени какую-то ерунду - несколько микросекунд. И в этом примере и в другом тоже. Это симулятор их не понимает или они просто не работают??

    DI HALT

    Есть большое подозрение что оптимизатор сожрал твою функцию задержки как не несущую никаких функций.

    DI HALT

    А ну и еще прикол. ЕМНИП 4 на 20 содержит в себе два контроллера HD44780 он как бы из двух половинок. Но надо бы уточнить, т.к. я точно не уверен.


  58. R_ura 14 марта 2010 16:55

    Спасибо за ответ. ))))) Пардон за иронию, это что же за компилятор такой умный, что жрет ТАКИЕ вещи???)))) Как же на нем что-то сделать можно? Может ему еще что по вкусу придется, прерывания например. В WinAwr оптимизация установлена - s -минимальная длина кода. Попробую изменить..

    DI HALT

    Какие такие? Пустые циклы? Так это в порядке вещей. Оптимизатор вообще такой затейник…

    Порой целые куски кода выбрасывает. Знаешь какие только извраты приходится делать чтобы проверить какую нибудь функцию. Т.е. написал ты функцию, хочешь проверть по быстрому что она тебе выдает. Пишешь

    u08 i;

    i=myFunc(Y);
    Запускаешь под отладчиком, чтобы прям там поглядеть на выход в переменной i .. и получаешь облом. Т.к. i нигде дальше не участвует то оптимизатор взял и выбросил ее и функцию на которую идет отсыл. Приходится делать что то вроде
    UDR = myFunck(Y);
    такое уже не проигнорируешь.

    Поставь О0 и замени на стандартную задержку вида _delay_ms - она очень быстрая и компактная, т.к. на инлайновом ассемблере писана.


  59. R_ura 14 марта 2010 16:59

    Di, извини за тупые вопросы, но из мелочей и складывается картина. А при чем тут оптимизатор? Я же в симуляторе смотрю текст на Си, а не скомпилированый код. Это же, если я не ошибаюсь, как смотреть ассемблерный код до компиляции - чисто исходный текст.

    DI HALT

    А он выполняется? Или ты его там только видишь? Если трассировать оптимизированный код по исходному тексту, то можно умом тронуться, т.к. ходит оно как то на так… =)

    Для просмотра ассемблерного результата там есть опция Toggle disassembler или как то так в меню View. Там же где watch, memory и прочие. Там будет ассемблерный код и его выполнение.


  60. R_ura 14 марта 2010 21:38

    К сожалению сайт больше не работает, чем работает.
    Ты был прав - оптимизация “съела” паузы. Индикатор заработал. Но с другой программой не работает, даже с учетом исправленых в первом случае косяков. ))) Си по отношению к асму навеял аналогию - можно неторопясь проехать сотню км на велосипеде (асм), а можно и на самолете (Си) - и быстрее и комфортнее. Только пока разберешься со всем этим самолетным
    управлением, всеми прибамбасами, человек на велике успеет не один раз обернуться туда-назад.)))
    Забавный этот Си.))) Сейчас отказывается работать простейшая кнопка со светодиодом..)))
    while (1)
    {
    if (bit_is_set(PINC,PC3)) PORTA |= _BV(PA3);
    else PORTA &= ~_BV(PA3);
    }

    DI HALT

    Макросы bit_is_set ЕМНИП были упразднены в WinAVR начиная с какой то версии. _BV тоже рекомендую нахуй. Сегодня есть завтра нет.

    Попробуй такой расклад:

    1
    2
    3
    4
    5
    
    while (1)
    {
    if (PINC & 1<<PA3) PORTA |= 1<<PA3;
    else PORTA &=~(1<<PA3);
    }

  61. R_ura 15 марта 2010 1:03

    Di, спасибо за внимание. Это же надо, сколько нюансов, о которых нигде не прочтешь.
    А что такое ЕМНИП ? ))) Стыдно, но первый раз слышу!!

    DI HALT

    Часть нюансов расписываю я по ходу пьесы.

    ЕМНИП это аббревиатура “Если Мне Не Изменяет Память”. Из той же оперы что и IMHO


  62. R_ura 15 марта 2010 9:22

    ))) ИМХО знаю. Буду знать теперь и ЕМНИП.))) Di, а тебе нельзя отослать кусок своей программы? Просто глянуть и навскидку сказать, много ли там баранины? Не в смысле логики работы, конечно, а в части правильности оформления что-ли? Я же так - по собственному наитию, может все не так совсем должно быть и выглядеть.

    dima_m

    А шо такое ИМХО?

    DI HALT

    погугли

    dima_m

    Выяснил


  63. dima_m 31 мая 2010 11:02

    А чем отличаются графические жидкокристаллические индикаторы от знакосинтезирующих жидкокристаллических индикаторов? Цена у них реально разная. Типа на графическом можно картинку нарисовать движущуюся, а на знакосинтезирующих только вывести цифры и буквы?

    DI HALT

    Именно так. На знаковом только текст и 8 произвольных значков 8х8 пикселов. А на графическом у тебя поле их NxM точек и чо хошь там то и рисуй. Движущуюся, кстати, сложно будет сделать, они весьма тормозные.

    dima_m

    OK! Спасибо.

Оставьте свой отзыв

Вы должны войти, чтобы оставлять комментарии.


Материалы сайта являются авторскими. Копирование и публикация материалов без активной ссылки на первоисточник запрещено.

Реклама: