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

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

А незабываемый AVRLib - http://www.procyonengineering.com/embedded/avr/avrlib/ пробовали?

 

Ещё имейте в виду, что некоторые дисплеи некорректно работают с 4-бит режимом. Даже если Вы домучаете свой конкретный экземпляр, можете поиметь проблемы переносимости (в смысле работоспособности на разных модулях LCD).

У меня лично лежит пара дисплеев, которые я так и не победил на 4 битах :( . Один 16x2, второй 20x4.

 

Попробуйте ещё встроенную библиотеку CvAVR. Она только в 4-бит режиме и работает.

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


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

У меня лично лежит пара дисплеев, которые я так и не победил на 4 битах :( . Один 16x2, второй 20x4.
я тоже помучился с какими-то дисплеями 20х4, но не потому, что не смог запустить, а потому, что у них распределение памяти оказалось нестандартным. пришлось буквально методом перебора адресов начала строк находить рабочий вариант

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


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

Лет 7 назад я использовал ЖКИ модуль с Mega8. Программу писал на ассемблере. Посылаю кусок инициализации с некоторыми комментариями. Буду рад если поможет.

LCD.txt

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


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

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

 

http://forum.cqham.ru/viewtopic.php?t=17803, там архив с исходниками - файл с именем hd44780.c - для ускорения работы используется проверка готовности дисплея чтением его регистра состояни (т.е., вывод WR задействован).

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


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

http://forum.cqham.ru/viewtopic.php?t=17803, там архив с исходниками - файл с именем hd44780.c - для ускорения работы используется проверка готовности дисплея чтением его регистра состояни (т.е., вывод WR задействован).

Там всё очень сложно и запутано для меня. Ситуация такая что знакомый написал мне прошивку для проверки работоспособности LCD (выводит русский текст) - и всё нормально вывелось, т.е. косяк точно в моей программе.

Один например уже нашел:

Вместо - temp =(lcd & ~(1<<RS)) | (1<<E); //задаём тип данных, который хотим переслать

Нужно было - temp =(lcd | ~(1<<RS)) | (1<<E);

Теперь я могу вывести на экран всякую белеберду, но не то что мне нужно и не там где мне нужно.

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


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

Нужно было - temp =(lcd | ~(1<<RS)) | (1<<E);
Сократите это выражение до temp =lcd | ~(1<<RS) и подумайте - вы действительно этого хотели?

 

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


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

Сократите это выражение до temp =lcd | ~(1<<RS) и подумайте - вы действительно этого хотели?

Я ошибся когда писал сообщение, на самом деле там: PORTC =(lcd & ~(1<<RS)) | (1<<E);

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


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

Я ошибся когда писал сообщение, на самом деле там: PORTC =(lcd & ~(1<<RS)) | (1<<E);

Посмотрите LCD library for HD44870 based LCD's

 

Как что установить помощь

 

в lcd.h назначаете порты и выводы.

 

#define LCD_PORT         PORTA        /**< port for the LCD lines   */
#define LCD_DATA0_PORT   LCD_PORT     /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT   LCD_PORT     /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT   LCD_PORT     /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT   LCD_PORT     /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN    0            /**< pin for 4bit data bit 0  */
#define LCD_DATA1_PIN    1            /**< pin for 4bit data bit 1  */
#define LCD_DATA2_PIN    2            /**< pin for 4bit data bit 2  */
#define LCD_DATA3_PIN    3            /**< pin for 4bit data bit 3  */
#define LCD_RS_PORT      LCD_PORT     /**< port for RS line         */
#define LCD_RS_PIN       4            /**< pin  for RS line         */
#define LCD_RW_PORT      LCD_PORT     /**< port for RW line         */
#define LCD_RW_PIN       5            /**< pin  for RW line         */
#define LCD_E_PORT       LCD_PORT     /**< port for Enable line     */
#define LCD_E_PIN        6            /**< pin  for Enable line     */

 

Используете так

#include "lcd.h"

// main 
int main(void)
{
    lcd_init(LCD_DISP_ON);                    // инициализация LCD
    lcd_clrscr();                            // очищаем индикатор
    
    lcd_puts("Proba Linia1");
    lcd_gotoxy(0,1);
    lcd_puts("      Linia2");
    while(1)
    {
    }
}

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

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


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

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

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


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

Вообщем переделал я немного функции и дисплей почти корректно заработал, но вот проблема походу кроется ещё в моем компиляторе: латиницу он нормально кодирует в соответствии ACSII, а вот вместо цифр и кириллицы на дисплее отображается всякие левые символы, к примеру я программирую что бы было "абвгдеёжз", а на дисплее "аЦЩдфцищ'". с цифрами всё ещё хуже - там вообще какие то вертикальные полосочки и крестики вместо них( например int i=1; lcd_SendData(i); - на дисплее две вертикальные палочки с черточкой посередине). Судя по таблице знакогенератора (02_codes.JPG) - мой компилятор не корректно кодирует ACSII в двоичный код, так как если я ввожу в программе тупо код нужного мне символа - то всё прекрасно выводится на ЖКИ. Программирую в AtmelStudio 6.0.1863. Подскажите что бы такое изменить и где в студии или же как в программе переназначить кодировки символов (цифр и кириллицы).

Вот работающий код:

#define E  4			//E  = PORTC.4 - стробирующий сигнал
#define RS 5				//RS = PORTC.5 - определение типа данных: команда(RS=0) или данные(RS=1)
#define RW 6				//RW = PORTC.6 - выбор режима: запись(RW=0) или чтение(RW=1)

void lcd_SendCmd(unsigned char lcd)		//функция передачи команд в дисплей
{
_delay_us(15);
PORTC  = (lcd>>4 & ~(1<<RS) & ~(1<<RW)) | (1<<E);
//задаём тип данных, который хотим переслать, выводим в порт старшую тетраду команды, сигналы RS и E
_delay_us(15);
PORTC &= ~(1<<E);
//cигнал записи команды

_delay_us(15);
PORTC  = (lcd & ~(1<<RS) & ~(1<<RW)) | (1<<E);
//задаём тип данных, который хотим переслать, выводим в порт младшую тетраду команды, сигналы RS и E
_delay_us(10);
PORTC &= ~(1<<E);		//cигнал записи команды
_delay_us(15);
}

void lcd_SendData(unsigned char lcd)		//функция передачи данных в дисплей
{
_delay_us(15);
PORTC  = ((lcd>>4) | (1<<RS) | (1<<E)) & ~(1<<RW);
//задаём тип данных, который хотим переслать, выводим в порт старшую тетраду данных, сигналы RS и E
_delay_us(15);
PORTC &= ~(1<<E);		//cигнал записи данных

_delay_us(15);
PORTC  = (lcd | (1<<RS) | (1<<E)) & ~(1<<RW);
//задаём тип данных, который хотим переслать, выводим в порт младшую тетраду данных, сигналы RS и E
_delay_us(15);
PORTC &= ~(1<<E);		//cигнал записи данных
_delay_us(15);
}

void lcd_init(void)				//функция инициализации дисплея
{	
lcd_SendCmd(0b00101000);		//4-бит интерфейс, 2 строки, 5х8 точек
_delay_ms(3);
lcd_SendCmd(0b00000110);		//адресс будет инкреминтироваться, экран не движется
_delay_ms(3);
lcd_SendCmd(0b00000001);		//очистка дисплея, указатель встал на 0x00 DDRAM
_delay_ms(5);
lcd_SendCmd(0b00001100);		//включаем ЖКИ, без отображения курсора
_delay_ms(3);
}

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

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


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

Подскажите что бы такое изменить и где в студии или же как в программе переназначить кодировки символов (цифр и кириллицы).

 

Коды кирилических символов в LCD не соответствуют кодам ASCII: буквы, одинаковые по написанию используются в обоих алфавитах. Т.е. нужна перекодировка. Хорошо бы заставить это сделать компилятор, но можно и в "реальном времени":

 

void hd44780_putc(char c)
{
if ((c >= 'А') && (c <= 'я')) 
{
	c = cyrillic[ c - 'А' ].code;
}
else if (c == 'ё') 
{
	c = 0xB5;
}
else if (c == 'Ё')
{
	c = 0xA2;
}

// ... вывод на LCD ...
}


typedef struct {
char symbol;
uint8_t code;
}symbol_table_t;


static const symbol_table_t cyrillic[66] = {	
					{'А', 0x41},	//'A'
					{'Б', 0xA0},	
					{'В', 0x42},	//'B'
					{'Г', 0xA1},	
					{'Д', 0xE0},	
					{'Е', 0x45},	//'E'	
					{'Ж', 0xA3},	
					{'З', 0xA4},	
					{'И', 0xA5},	
					{'Й', 0xA6},	
					{'К', 0x4B},	//'K'
					{'Л', 0xA7},	
					{'М', 0x4D},	//'M'
					{'Н', 0x48},	//'H'
					{'О', 0x4F},	//'O'
					{'П', 0xA8},	
					{'Р', 0x50},	//'P'
					{'С', 0x43},	//'C'
					{'Т', 0x54},	//'T'
					{'У', 0xA9},	
					{'Ф', 0xAA},	
					{'Х', 0x58},	//'X'
					{'Ц', 0xE1},	
					{'Ч', 0xAB},	
					{'Ш', 0xAC},	
					{'Щ', 0xE2},	
					{'Ъ', 0xAD},	
					{'Ы', 0xAE},	
					{'Ь', 0x62},	//'b'
					{'Э', 0xAF},	
					{'Ю', 0xB0},	
					{'Я', 0xB1},

					{'а', 0x61},	//'a'
					{'б', 0xB2},	
					{'в', 0xB3},	
					{'г', 0xB4},	
					{'д', 0xE3},	
					{'е', 0x65},	//'e'	
					{'ж', 0xB6},	
					{'з', 0xB7},	
					{'и', 0xB8},	
					{'й', 0xB9},	
					{'к', 0xBA},	
					{'л', 0xBB},	
					{'м', 0xBC},	
					{'н', 0xBD},	
					{'о', 0x6F},	//'o'
					{'п', 0xBE},	
					{'р', 0x70},	//'p'
					{'с', 0x63},	//'c'
					{'т', 0xBF},	
					{'у', 0x79},	//'y'
					{'ф', 0xE4},	
					{'х', 0x78},	//'x'
					{'ц', 0xE5},	
					{'ч', 0xC0},	
					{'ш', 0xC1},	
					{'щ', 0xE6},	
					{'ъ', 0xC2},	
					{'ы', 0xC3},	
					{'ь', 0xC4},	
					{'э', 0xC5},	
					{'ю', 0xC6},	
					{'я', 0xC7},

					{'Ё', 0xA2},
					{'ё', 0xB5}		};

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

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


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

а вот вместо цифр и кириллицы на дисплее отображается всякие левые символы, к примеру я программирую что бы было "абвгдеёжз", а на дисплее "аЦЩдфцищ'".

Видимо производитель LCD закодировал символы как ему вздумалось, а не в соответствии с существующими кодировками (а может какой-то и соответствует?).

 

с цифрами всё ещё хуже - там вообще какие то вертикальные полосочки и крестики вместо них( например int i=1; lcd_SendData(i); - на дисплее две вертикальные палочки с черточкой посередине).

А что вы там ждёте? Задали дисплею выдать байт 0x00 - он и выдал что-то непечатное. Вам надо преобразовать число к печатному виду. Или вы думаете в дисплее printf реализован который за вас это сделает?

 

мой компилятор не корректно кодирует ACSII в двоичный код, так как если я ввожу в программе тупо код нужного мне символа - то всё прекрасно выводится на ЖКИ.

Создайте таблицу перекодировки в соответствии с рисунком. Латиницу перекодировать не надо - только то что после 0x7F.

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


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

Видимо производитель LCD закодировал символы как ему вздумалось, а не в соответствии с существующими кодировками (а может какой-то и соответствует?).

 

 

А что вы там ждёте? Задали дисплею выдать байт 0x00 - он и выдал что-то непечатное. Вам надо преобразовать число к печатному виду. Или вы думаете в дисплее printf реализован который за вас это сделает?

 

 

Создайте таблицу перекодировки в соответствии с рисунком. Латиницу перекодировать не надо - только то что после 0x7F.

Да, вы правы на счет цифр. Сейчас делаю таким макаром: int i=1; lcd_SendData(i+48); - подскажите всегда ли это будет работать с цифрами и какие недостатки таит в себе такой подход?

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


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

подскажите всегда ли это будет работать с цифрами и какие недостатки таит в себе такой подход?
Если дисплей воспринимает цифры в кодировке ASCII - всегда. Из недостатков только нечитаемость исходника. lcd_SendData(i+'0'); выглядит более понятно.

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


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

Вообщем всё наконец таки заработало как надо, спасибо огромное товарищу "S17". Понимаю что С++ надо учить и учить что бы так свободно с ним обращаться как Вы. Спасибо всем, на днях напишу ещё свои функции для других операций с ЖКИ (в планах функция установки курсора в произвольное место DDRAM с координатами x,y и т.д), думаю сам справлюсь. Благодарю за помощь.

Фото ЖКИ

LCD_16x2_test.rar

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

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


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

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

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

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

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

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

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

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

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

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