Перейти к содержанию
    

Проблема с управлением HD44780

Здравствуйте, несколько дней уже разбираюсь с управлением ЖКИ 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);
}

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!, форматирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Советую проверить функцию инициализации, в частности переход на 4 разрядную шину.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проверил, всё правильно, биты: DL=0, N=1, F=0

 

lcd_SendCommand(0b00101000); //4-бит интерфейс, 2 строки, 5х8 точек

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

После 5 секудного гугления:

 

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

 

Нужно проверить инициализацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А мануал на 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
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

После 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)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и была охота велосипед изобретать? полно ведь готовых работающих библиотек...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Инициализировал как в даташите - не помогло: курсор мигает черным прямоугольником в конце первой строки.

На счет готовых библиотек - это ещё большие дебри, пробовал парочку - ничего не выводится, скорее всего я просто неумело их использую. Там куча всяких параметров, а мне много не надо. Я хочу сам разобраться на примере простых операций.

Изменено пользователем endasm

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Инициализировал как в даташите - не помогло: курсор мигает черным прямоугольником в конце первой строки.

В даташите на 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 модуль, глюки компилятора...)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может поможет:

hd44780 online simulator: http://www.dinceraydin.com/djlcdsim/djlcdsim.html

 

и была охота велосипед изобретать? полно ведь готовых работающих библиотек...

Мне бы не помешали ссылки на работающие библиотеки...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне бы не помешали ссылки на работающие библиотеки...

их есть у меня! http://www.simple-devices.ru/articles/7-so...r-lcd-interface

возможно, это будет "слишком много" для вас, но там действительно есть все работающее. и Proteus VSM очень-очень-очень хорошо симулирует работу ЖКИ, можно все отладить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

их есть у меня! http://www.simple-devices.ru/articles/7-so...r-lcd-interface

возможно, это будет "слишком много" для вас, но там действительно есть все работающее. и Proteus VSM очень-очень-очень хорошо симулирует работу ЖКИ, можно все отладить.

Роман! Благодарю Вас за ссылку – для меня там много полезного и не только по LCD. Ваша проделанная работа вызывает уважение!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...