|
Проблема с управлением HD44780, Не удается должным образом вывести на дисплей необходимую информацию |
|
|
|
Dec 27 2012, 12:34
|
Участник

Группа: Участник
Сообщений: 40
Регистрация: 9-07-12
Пользователь №: 72 673

|
Здравствуйте, несколько дней уже разбираюсь с управлением ЖКИ 16х2 на базе контроллера HD44780 по 4-битному интерфейсу. Написал по примеру несколько функций для этого. Но максимум что удалось сделать - это вывести мигающий курсор в верхнем левом углу дисплея в виде черного прямоугольника. Скорее всего в функциях есть проблема, помогите разобраться в чем дело, подключение дисплея правильное. Ниже код функций: CODE #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); }
Сообщение отредактировал IgorKossak - Dec 27 2012, 17:45
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!, форматирование
|
|
|
|
|
Dec 27 2012, 13:18
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-06
Пользователь №: 15 890

|
Советую проверить функцию инициализации, в частности переход на 4 разрядную шину.
|
|
|
|
|
Dec 27 2012, 13:47
|
Участник

Группа: Участник
Сообщений: 40
Регистрация: 9-07-12
Пользователь №: 72 673

|
Проверил, всё правильно, биты: DL=0, N=1, F=0
lcd_SendCommand(0b00101000); //4-бит интерфейс, 2 строки, 5х8 точек
|
|
|
|
|
Dec 27 2012, 14:08
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-06
Пользователь №: 15 890

|
После 5 секудного гугления:
Необходимо помнить, что когда Вы объявляете режим работы с 4-х разрядной шиной, то есть выдаете команду $20, то делаете это обычно из 8-ми разрядного режима, который устанавливается автоматически после подачи напряжения питания, а значит вы не сможете адекватно объявить необходимое значение флагов N и F, располагающихся в младшей тетраде команды установки разрядности шины. Поэтому команду необходимо повторить в уже установившемся 4-х разрядном режиме путем последовательной передачи двух тетрад, то есть для 4-х разрядного режима образом.
Нужно проверить инициализацию.
|
|
|
|
|
Dec 27 2012, 14:54
|
Участник

Группа: Участник
Сообщений: 40
Регистрация: 9-07-12
Пользователь №: 72 673

|
Сейчас поправлю и отпишусь.
Не помогло.
|
|
|
|
|
Dec 27 2012, 15:07
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-06
Пользователь №: 15 890

|
Значит затык в задержках. Какой конкретно ЖКИ используется?
|
|
|
|
|
Dec 27 2012, 15:15
|
Участник

Группа: Участник
Сообщений: 40
Регистрация: 9-07-12
Пользователь №: 72 673

|
WINSTAR WH1602B
|
|
|
|
|
Dec 27 2012, 15:37
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-06
Пользователь №: 15 890

|
А мануал на 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); где р-данные Надеюсь будет понятна ошибка.
Сообщение отредактировал IgorKossak - Dec 27 2012, 17:46
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Dec 27 2012, 15:47
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
Цитата(Dust112 @ Dec 27 2012, 16:08)  После 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)
|
|
|
|
|
Dec 27 2012, 16:46
|
Участник

Группа: Участник
Сообщений: 40
Регистрация: 9-07-12
Пользователь №: 72 673

|
Инициализировал как в даташите - не помогло: курсор мигает черным прямоугольником в конце первой строки. На счет готовых библиотек - это ещё большие дебри, пробовал парочку - ничего не выводится, скорее всего я просто неумело их использую. Там куча всяких параметров, а мне много не надо. Я хочу сам разобраться на примере простых операций.
Сообщение отредактировал endasm - Dec 27 2012, 16:47
|
|
|
|
|
Dec 27 2012, 20:08
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
Цитата(endasm @ Dec 27 2012, 18:46)  Инициализировал как в даташите - не помогло: курсор мигает черным прямоугольником в конце первой строки. В даташите на 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 модуль, глюки компилятора...)
|
|
|
|
|
Dec 27 2012, 20:11
|
Частый гость
 
Группа: Участник
Сообщений: 105
Регистрация: 22-06-05
Пользователь №: 6 228

|
Может поможет: hd44780 online simulator: http://www.dinceraydin.com/djlcdsim/djlcdsim.htmlЦитата(ARV @ Dec 27 2012, 19:55)  и была охота велосипед изобретать? полно ведь готовых работающих библиотек... Мне бы не помешали ссылки на работающие библиотеки...
|
|
|
|
|
Dec 28 2012, 10:28
|
Частый гость
 
Группа: Участник
Сообщений: 105
Регистрация: 22-06-05
Пользователь №: 6 228

|
Цитата(ARV @ Dec 28 2012, 12:10)  их есть у меня! http://www.simple-devices.ru/articles/7-so...r-lcd-interfaceвозможно, это будет "слишком много" для вас, но там действительно есть все работающее. и Proteus VSM очень-очень-очень хорошо симулирует работу ЖКИ, можно все отладить. Роман! Благодарю Вас за ссылку – для меня там много полезного и не только по LCD. Ваша проделанная работа вызывает уважение!
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|