реклама на сайте
подробности

 
 
> Проблема с управлением HD44780, Не удается должным образом вывести на дисплей необходимую информацию
endasm
сообщение Dec 27 2012, 12:34
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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] - для короткого!!!, форматирование
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 30)
Dust112
сообщение Dec 27 2012, 13:18
Сообщение #2


Участник
*

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



Советую проверить функцию инициализации, в частности переход на 4 разрядную шину.
Go to the top of the page
 
+Quote Post
endasm
сообщение Dec 27 2012, 13:47
Сообщение #3


Участник
*

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



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

lcd_SendCommand(0b00101000); //4-бит интерфейс, 2 строки, 5х8 точек
Go to the top of the page
 
+Quote Post
Dust112
сообщение Dec 27 2012, 14:08
Сообщение #4


Участник
*

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



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

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

Нужно проверить инициализацию.
Go to the top of the page
 
+Quote Post
endasm
сообщение Dec 27 2012, 14:54
Сообщение #5


Участник
*

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



Сейчас поправлю и отпишусь.

Не помогло.
Go to the top of the page
 
+Quote Post
Dust112
сообщение Dec 27 2012, 15:07
Сообщение #6


Участник
*

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



Значит затык в задержках. Какой конкретно ЖКИ используется?
Go to the top of the page
 
+Quote Post
endasm
сообщение Dec 27 2012, 15:15
Сообщение #7


Участник
*

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



WINSTAR WH1602B
Go to the top of the page
 
+Quote Post
Dust112
сообщение Dec 27 2012, 15:37
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 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] - для короткого!!!
Go to the top of the page
 
+Quote Post
Ruslan1
сообщение Dec 27 2012, 15:47
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025



Цитата(Dust112 @ Dec 27 2012, 16:08) *
После 5 секудного гугления:

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

? Насколько я помню, ВСЕ модули изначально после включения готовы воспринимать команды без младших битов, то есть в 4-битной моде. Никакого 8-битного режима при включении нет, иначе было бы невозможно перейти в 4-битный sm.gif

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)
Go to the top of the page
 
+Quote Post
ARV
сообщение Dec 27 2012, 15:55
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



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


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
endasm
сообщение Dec 27 2012, 16:46
Сообщение #11


Участник
*

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



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

Сообщение отредактировал endasm - Dec 27 2012, 16:47
Go to the top of the page
 
+Quote Post
Ruslan1
сообщение Dec 27 2012, 20:08
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 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 модуль, глюки компилятора...)
Go to the top of the page
 
+Quote Post
S17
сообщение Dec 27 2012, 20:11
Сообщение #13


Частый гость
**

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



Может поможет:
hd44780 online simulator: http://www.dinceraydin.com/djlcdsim/djlcdsim.html

Цитата(ARV @ Dec 27 2012, 19:55) *
и была охота велосипед изобретать? полно ведь готовых работающих библиотек...

Мне бы не помешали ссылки на работающие библиотеки...
Go to the top of the page
 
+Quote Post
ARV
сообщение Dec 28 2012, 08:10
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(S17 @ Dec 28 2012, 00:11) *
Мне бы не помешали ссылки на работающие библиотеки...

их есть у меня! http://www.simple-devices.ru/articles/7-so...r-lcd-interface
возможно, это будет "слишком много" для вас, но там действительно есть все работающее. и Proteus VSM очень-очень-очень хорошо симулирует работу ЖКИ, можно все отладить.


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
S17
сообщение Dec 28 2012, 10:28
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 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. Ваша проделанная работа вызывает уважение!
Go to the top of the page
 
+Quote Post
hd44780
сообщение Dec 28 2012, 16:03
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



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

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

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


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
ARV
сообщение Dec 28 2012, 17:18
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(hd44780 @ Dec 28 2012, 20:03) *
У меня лично лежит пара дисплеев, которые я так и не победил на 4 битах sad.gif . Один 16x2, второй 20x4.
я тоже помучился с какими-то дисплеями 20х4, но не потому, что не смог запустить, а потому, что у них распределение памяти оказалось нестандартным. пришлось буквально методом перебора адресов начала строк находить рабочий вариант


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
vgo1
сообщение Dec 28 2012, 17:33
Сообщение #18


Участник
*

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



Лет 7 назад я использовал ЖКИ модуль с Mega8. Программу писал на ассемблере. Посылаю кусок инициализации с некоторыми комментариями. Буду рад если поможет.
Прикрепленные файлы
Прикрепленный файл  LCD.txt ( 2.26 килобайт ) Кол-во скачиваний: 49
 
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Dec 28 2012, 17:47
Сообщение #19


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата(S17 @ Dec 28 2012, 00:11) *
Мне бы не помешали ссылки на работающие библиотеки...


http://forum.cqham.ru/viewtopic.php?t=17803, там архив с исходниками - файл с именем hd44780.c - для ускорения работы используется проверка готовности дисплея чтением его регистра состояни (т.е., вывод WR задействован).
Go to the top of the page
 
+Quote Post
endasm
сообщение Dec 29 2012, 13:17
Сообщение #20


Участник
*

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



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

Там всё очень сложно и запутано для меня. Ситуация такая что знакомый написал мне прошивку для проверки работоспособности LCD (выводит русский текст) - и всё нормально вывелось, т.е. косяк точно в моей программе.
Один например уже нашел:
Вместо - temp =(lcd & ~(1<<RS)) | (1<<E); //задаём тип данных, который хотим переслать
Нужно было - temp =(lcd | ~(1<<RS)) | (1<<E);
Теперь я могу вывести на экран всякую белеберду, но не то что мне нужно и не там где мне нужно.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 29 2012, 22:52
Сообщение #21


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (endasm @ Dec 29 2012, 15:17) *
Нужно было - temp =(lcd | ~(1<<RS)) | (1<<E);
Сократите это выражение до temp =lcd | ~(1<<RS) и подумайте - вы действительно этого хотели?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
endasm
сообщение Dec 30 2012, 07:53
Сообщение #22


Участник
*

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



Цитата(Сергей Борщ @ Dec 30 2012, 01:52) *
Сократите это выражение до temp =lcd | ~(1<<RS) и подумайте - вы действительно этого хотели?

Я ошибся когда писал сообщение, на самом деле там: PORTC =(lcd & ~(1<<RS)) | (1<<E);
Go to the top of the page
 
+Quote Post
Marian
сообщение Dec 30 2012, 14:08
Сообщение #23


Частый гость
**

Группа: Участник
Сообщений: 148
Регистрация: 23-02-07
Пользователь №: 25 618



Цитата(endasm @ Dec 30 2012, 10:53) *
Я ошибся когда писал сообщение, на самом деле там: 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 - Dec 30 2012, 14:24
Go to the top of the page
 
+Quote Post
ARV
сообщение Dec 30 2012, 15:28
Сообщение #24


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(Marian @ Dec 30 2012, 18:08) *
именно об этой библиотечке шла речь, когда я давал свою ссылку. только я дал ссылку на статью с библиотечкой, в которой я уже исправил найденные ошибки, и плюс ко всему по-русски описал основные макросы и функции. так же в виде бонуса рассказал о том, как использовать стандартные функции вывода а-ля printf вместе с этой библиотечкой.


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
endasm
сообщение Dec 30 2012, 21:16
Сообщение #25


Участник
*

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



Вообщем переделал я немного функции и дисплей почти корректно заработал, но вот проблема походу кроется ещё в моем компиляторе: латиницу он нормально кодирует в соответствии ACSII, а вот вместо цифр и кириллицы на дисплее отображается всякие левые символы, к примеру я программирую что бы было "абвгдеёжз", а на дисплее "аЦЩдфцищ'". с цифрами всё ещё хуже - там вообще какие то вертикальные полосочки и крестики вместо них( например int i=1; lcd_SendData(i); - на дисплее две вертикальные палочки с черточкой посередине). Судя по таблице знакогенератора () - мой компилятор не корректно кодирует ACSII в двоичный код, так как если я ввожу в программе тупо код нужного мне символа - то всё прекрасно выводится на ЖКИ. Программирую в AtmelStudio 6.0.1863. Подскажите что бы такое изменить и где в студии или же как в программе переназначить кодировки символов (цифр и кириллицы).
Вот работающий код:
CODE
#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 - Dec 31 2012, 18:06
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!, форматирование
Go to the top of the page
 
+Quote Post
S17
сообщение Dec 30 2012, 21:54
Сообщение #26


Частый гость
**

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



Цитата(endasm @ Dec 31 2012, 01:16) *
Подскажите что бы такое изменить и где в студии или же как в программе переназначить кодировки символов (цифр и кириллицы).


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

CODE
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 - Dec 31 2012, 18:07
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Dec 30 2012, 21:55
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(endasm @ Dec 30 2012, 23:16) *
а вот вместо цифр и кириллицы на дисплее отображается всякие левые символы, к примеру я программирую что бы было "абвгдеёжз", а на дисплее "аЦЩдфцищ'".

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

Цитата(endasm @ Dec 30 2012, 23:16) *
с цифрами всё ещё хуже - там вообще какие то вертикальные полосочки и крестики вместо них( например int i=1; lcd_SendData(i); - на дисплее две вертикальные палочки с черточкой посередине).

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

Цитата(endasm @ Dec 30 2012, 23:16) *
мой компилятор не корректно кодирует ACSII в двоичный код, так как если я ввожу в программе тупо код нужного мне символа - то всё прекрасно выводится на ЖКИ.

Создайте таблицу перекодировки в соответствии с рисунком. Латиницу перекодировать не надо - только то что после 0x7F.
Go to the top of the page
 
+Quote Post
endasm
сообщение Dec 30 2012, 22:18
Сообщение #28


Участник
*

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



Цитата(_Артём_ @ Dec 31 2012, 00:55) *
Видимо производитель LCD закодировал символы как ему вздумалось, а не в соответствии с существующими кодировками (а может какой-то и соответствует?).


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


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

Да, вы правы на счет цифр. Сейчас делаю таким макаром: int i=1; lcd_SendData(i+48); - подскажите всегда ли это будет работать с цифрами и какие недостатки таит в себе такой подход?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 30 2012, 22:55
Сообщение #29


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (endasm @ Dec 31 2012, 00:18) *
подскажите всегда ли это будет работать с цифрами и какие недостатки таит в себе такой подход?
Если дисплей воспринимает цифры в кодировке ASCII - всегда. Из недостатков только нечитаемость исходника. lcd_SendData(i+'0'); выглядит более понятно.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
endasm
сообщение Dec 30 2012, 23:02
Сообщение #30


Участник
*

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



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

Сообщение отредактировал endasm - Dec 30 2012, 23:08
Прикрепленные файлы
Прикрепленный файл  LCD_16x2_test.rar ( 1.62 килобайт ) Кол-во скачиваний: 24
 
Go to the top of the page
 
+Quote Post
S17
сообщение Dec 31 2012, 16:29
Сообщение #31


Частый гость
**

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



Цитата(endasm @ Dec 31 2012, 03:02) *
Вообщем всё наконец таки заработало как надо, спасибо огромное товарищу "S17".

Я рад! Всех с Новым Годом!

По курсору:

CODE
// Установить позицию курсора (начало 0, 0):
void hd44780_CursorSet(unsigned char X, unsigned char Y)
{
unsigned char StartAddr;

if(Y == 0) StartAddr = 0x00;
#if HD44780_DISPLAY_LINES==4
else if(Y == 1) StartAddr = 0x40;
else if(Y == 2) StartAddr = 0x20;
else StartAddr = 0x60;
#else
else StartAddr = 0x40;
#endif

if(X > 24) X = 24; // обрезать лишние
hd44780_goto(StartAddr+X);
};

#define HD44780_DDRAM 7 // DB7: set DD RAM address
void hd44780_goto(uint8_t pos)
{
hd44780_command((1<<HD44780_DDRAM)+pos);
}

void hd44780_command(uint8_t cmd)
{
hd44780_write(cmd,0);
}


Сообщение отредактировал IgorKossak - Dec 31 2012, 18:08
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 04:12
Рейтинг@Mail.ru


Страница сгенерированна за 0.01655 секунд с 7
ELECTRONIX ©2004-2016