lol481 0 27 декабря, 2012 Опубликовано 27 декабря, 2012 (изменено) · Жалоба Здравствуйте, несколько дней уже разбираюсь с управлением ЖКИ 16х2 на базе контроллера HD44780 по 4-битному интерфейсу. Написал по примеру несколько функций для этого. Но максимум что удалось сделать - это вывести мигающий курсор в верхнем левом углу дисплея в виде черного прямоугольника. Скорее всего в функциях есть проблема, помогите разобраться в чем дело, подключение дисплея правильное. Ниже код функций: #include <avr/io.h> #define F_CPU 4000000UL #include <avr/delay.h> #define E 0 //E = PORTC.0 - стробирующий сигнал #define RS 1 //RS = PORTC.1 - определение типа данных: команда(RS=0) или данные(RS=1) #define RW 2 //RW = PORTC.2 - выбор режима: запись(RW=0) или чтение(RW=1) void lcd_SendCommand(unsigned char lcd) //функция передачи команд в дисплей { unsigned char temp; temp =(lcd & ~(1<<RS)) | (1<<E); //задаём тип данных, который хотим переслать PORTC=temp; //выводим в порт старшую тетраду команды, сигналы RS и E PORTC=temp & ~(1<<E); //cигнал записи команды _delay_us(5); temp =((lcd*16) & ~(1<<RS)) | (1<<E); //задаём тип данных, который хотим переслать PORTC=temp; //выводим в порт младшую тетраду команды, сигналы RS и E PORTC=temp & ~(1<<E); //cигнал записи команды _delay_us(5); } void lcd_SendData(unsigned char lcd) //функция передачи данных в дисплей { unsigned char temp; temp =(lcd & (1<<RS)) | (1<<E); //задаём тип данных, который хотим переслать PORTC=temp; //выводим в порт старшую тетраду данных, сигналы RS и E PORTC=temp & ~(1<<E); //cигнал записи данных _delay_us(5); temp =((lcd*16) & (1<<RS)) | (1<<E); //задаём тип данных, который хотим переслать PORTC=temp; //выводим в порт младшую тетраду данных, сигналы RS и E PORTC=temp & ~(1<<E); //cигнал записи данных _delay_us(5); } void lcd_init(void) //функция инициализации дисплея { lcd_SendCommand(0b00101000); //4-бит интерфейс, 2 строки, 5х8 точек _delay_ms(10); lcd_SendCommand(0b00000001); //очистка дисплея, указатель встал на 0x00 DDRAM _delay_ms(10); lcd_SendCommand(0b00000110); //адресс будет инкреминтироваться, экран не движется _delay_ms(10); } int main(void) { DDRC =0b01111111; //настройка PORTC на выход PORTC=0b01111011; _delay_ms(10); lcd_init(); //инициализация дисплея lcd_SendCommand(0b00001100); //включаем дисплей, настраиваем курсор(режим: в виде подчеркивания) lcd_SendData('1'); lcd_SendData('2'); lcd_SendData('3'); lcd_SendData('4'); lcd_SendData('5'); lcd_SendData('6'); lcd_SendData('7'); lcd_SendData('8'); lcd_SendData('9'); lcd_SendData('0'); lcd_SendData('A'); lcd_SendData('B'); lcd_SendData('C'); while(1); } Изменено 27 декабря, 2012 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!!, форматирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dust112 0 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба Советую проверить функцию инициализации, в частности переход на 4 разрядную шину. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lol481 0 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба Проверил, всё правильно, биты: DL=0, N=1, F=0 lcd_SendCommand(0b00101000); //4-бит интерфейс, 2 строки, 5х8 точек Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dust112 0 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба После 5 секудного гугления: Необходимо помнить, что когда Вы объявляете режим работы с 4-х разрядной шиной, то есть выдаете команду $20, то делаете это обычно из 8-ми разрядного режима, который устанавливается автоматически после подачи напряжения питания, а значит вы не сможете адекватно объявить необходимое значение флагов N и F, располагающихся в младшей тетраде команды установки разрядности шины. Поэтому команду необходимо повторить в уже установившемся 4-х разрядном режиме путем последовательной передачи двух тетрад, то есть для 4-х разрядного режима образом. Нужно проверить инициализацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lol481 0 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба Сейчас поправлю и отпишусь. Не помогло. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dust112 0 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба Значит затык в задержках. Какой конкретно ЖКИ используется? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lol481 0 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба WINSTAR WH1602B Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dust112 0 27 декабря, 2012 Опубликовано 27 декабря, 2012 (изменено) · Жалоба А мануал на HD44780 читали? Там же есть пример инициализации. Опсс. Одел очки, посмотрел код. SendCommand LCD_PORT &= ~_BV(LCD_RS); LCD_PORT |= _BV(LCD_E); LCD_PORT &= 0xF0; LCD_PORT |= (p >> 4); _delay_ms(1); LCD_PORT &= ~_BV(LCD_E); _delay_ms(1); LCD_PORT |= _BV(LCD_E); LCD_PORT &= 0xF0; LCD_PORT |= (p & 0x0F); _delay_ms(1); LCD_PORT &= ~_BV(LCD_E); _delay_ms(1); SendData LCD_PORT |= _BV(LCD_RS) | _BV(LCD_E); LCD_PORT &= 0xF0; LCD_PORT |= (p >> 4); _delay_ms(1); LCD_PORT &= ~_BV(LCD_E); _delay_ms(1); LCD_PORT |= _BV(LCD_E); LCD_PORT &= 0xF0; LCD_PORT |= (p & 0x0F); _delay_ms(1); LCD_PORT &= ~_BV(LCD_E); _delay_ms(1); где р-данные Надеюсь будет понятна ошибка. Изменено 27 декабря, 2012 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 16 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба После 5 секудного гугления: Необходимо помнить, что когда Вы объявляете режим работы с 4-х разрядной шиной, то есть выдаете команду $20, то делаете это обычно из 8-ми разрядного режима, который устанавливается автоматически после подачи напряжения питания, ? Насколько я помню, ВСЕ модули изначально после включения готовы воспринимать команды без младших битов, то есть в 4-битной моде. Никакого 8-битного режима при включении нет, иначе было бы невозможно перейти в 4-битный :) endasm: посмотрите родную процедуру инициализации в родной документации и убедитесь что у вас ИМЕННО так, а не "похоже": http://embedded.ifmo.ru/sdk/sdk61/componen...602B-YGK-CP.pdf страница 17 (картинка "4-Bit Ineterface") Классические проблемы: 1. Некорректное питание 2. Некорректное напряжение на выводе управления контрастностью 3. подключены в качестве шины данных младшие 4 бита шины LCD (DB3-DB0), а не нужные старшие биты (DB7- DB4) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба и была охота велосипед изобретать? полно ведь готовых работающих библиотек... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lol481 0 27 декабря, 2012 Опубликовано 27 декабря, 2012 (изменено) · Жалоба Инициализировал как в даташите - не помогло: курсор мигает черным прямоугольником в конце первой строки. На счет готовых библиотек - это ещё большие дебри, пробовал парочку - ничего не выводится, скорее всего я просто неумело их использую. Там куча всяких параметров, а мне много не надо. Я хочу сам разобраться на примере простых операций. Изменено 27 декабря, 2012 пользователем endasm Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 16 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба Инициализировал как в даташите - не помогло: курсор мигает черным прямоугольником в конце первой строки. В даташите на LCD модуль, который я Вам советовал открыть, первая команда инициализации: RS R/W DB7 DB6 DB5 DB4 0 0 0 0 1 1 В Вашем коде: void lcd_init(void) //функция инициализации дисплея { lcd_SendCommand(0b00101000); Дальше читать не стал. Так как не смог сопоставить передаваемый Вами бит с нужным модулю нибблом 0b0011 Приведите 1. Схему подключения ЖКИ модуля к процессору и источнику питания 2. исходный код процедуры инициализации, соответствующий документации на модуль 3. Функцию вывода одного символа. 4. Ваше утверждение что оно не работает. То есть последовательность сброс/подача_питания -> вызов (2) -> вызов (3) не приводит к появлению символа на экране. Чудес не бывает, где-то ошибка. 99.99%- в Вашем железе или программе, 0.01% - где-то еще (плохой LCD модуль, глюки компилятора...) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
S17 1 27 декабря, 2012 Опубликовано 27 декабря, 2012 · Жалоба Может поможет: hd44780 online simulator: http://www.dinceraydin.com/djlcdsim/djlcdsim.html и была охота велосипед изобретать? полно ведь готовых работающих библиотек... Мне бы не помешали ссылки на работающие библиотеки... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 28 декабря, 2012 Опубликовано 28 декабря, 2012 · Жалоба Мне бы не помешали ссылки на работающие библиотеки... их есть у меня! http://www.simple-devices.ru/articles/7-so...r-lcd-interface возможно, это будет "слишком много" для вас, но там действительно есть все работающее. и Proteus VSM очень-очень-очень хорошо симулирует работу ЖКИ, можно все отладить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
S17 1 28 декабря, 2012 Опубликовано 28 декабря, 2012 · Жалоба их есть у меня! http://www.simple-devices.ru/articles/7-so...r-lcd-interface возможно, это будет "слишком много" для вас, но там действительно есть все работающее. и Proteus VSM очень-очень-очень хорошо симулирует работу ЖКИ, можно все отладить. Роман! Благодарю Вас за ссылку – для меня там много полезного и не только по LCD. Ваша проделанная работа вызывает уважение! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться