Форум myROBOT.ru » Роботы и робототехника » Делимся опытом » подключение ЖКИ к микроконтроллеру

Страниц (2): [1] 2 »
 

1. Artem - 13 Июня, 2013 - 10:45:53 - перейти к сообщению
Доброго времени суток Улыбка
Возникла потребность выводить значения некоторых переменных на экран, да и вобще для общего развития можно попробовать подключить дисплей к микроконтроллеру.
Купил я дисплей, программу взял вот от сюда: http://radioparty.ru/prog-avr/pr...-lcd-avr-lesson1
Включаю и ничего, только чёрные квадратики, а месте которых должны быть символы, по всему экрану. Может быть кто-нибудь сталкивался с этим, что это такое? Ошибка в программе или я что-то не так спаял?
Помогите!
Заранее спасибо Улыбка
2. Роботов - 13 Июня, 2013 - 14:31:29 - перейти к сообщению
Если черные квадратики, значит контрастность надо крутить. (на схеме по ссылке R2)
3. Artem - 13 Июня, 2013 - 14:59:06 - перейти к сообщению
Да! а я наоборот его крутил так чтобы они были не в себе
Щас попробуем сделать.
(Добавление)
Не работает рёв в три ручья

Покрутил ручку, квадратики пропали, а текст не появился.
Не понимаю почему. всё сделал как там сказано Замешательство
4. morokoriss - 13 Июня, 2013 - 18:31:20 - перейти к сообщению
Правильно ли ты подключил его? Программу сам писал или скетч ардуиновский? Если подключал по статье с нета о подключении ЖКД к ардуино то там указаны иные пины чем в тестовом скетче, проверь ещё раз. Если квадраты появились то питание есть, просто многие ЖКД требуют двуполярного питания (которые способны работать при сильно отрицательных температурах например).
(Добавление)
"Типовая схема подключения LCD к МК показана на рис.3. Именно она и будет использоваться для первой тестовой проверки LCD с выведением на экран знаменитой фразы "Hello, world!" ("Здравствуй, мир!"Подмигивающий." Если ты об этом то так и есть, вот распиновка из скетча, не совпадает со схемой

The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)

А по схеме Enable RW RS на ADC висят, а в программе на digital. А если код на Си залил который в примере тогда ХЗ товарищ майор)
(Добавление)
Дисплей точно такой же? Там пины расписаны? Если он на HD44780 собран то это не обязательно что должно совпасть. Если нет там обозначений тогда даташит надо найти.
5. mihail - 13 Июня, 2013 - 18:52:54 - перейти к сообщению
Artem

Вы смогли откомпилировать код по ссылке?

Не зная название используемого дисплейчика ничего конкретного сказать нельзя.

http://chipenable.ru/index.php/p...-rezultatov.html
6. Artem - 13 Июня, 2013 - 19:23:01 - перейти к сообщению
morokoriss пишет:
Правильно ли ты подключил его?

Да, я в этом уверен, по даташиту проверял, дисплей WH1602B всё проверил 10 раз.
mihail пишет:
скетча

Можно узнать что это такое?
mihail пишет:
Вы смогли откомпилировать код по ссылке?

Да смог, никаких ошибок не выдало.
7. mihail - 14 Июня, 2013 - 01:17:52 - перейти к сообщению
Скетч (sketch) это общее название программ для ардуино. Принято у ардуинщиков код скетчами обзывать Улыбка

Artem пишет:
WH1602B

Их много (WH1602B-AEI-CTV, WH1602B-CFH-CT, WH1602B-NYG-CT, WH1602B-REI-CTV, WH1602B-YEI-CTV, WH1602B-YGK-CTK).

А вообще в этих экранчиках используется KS0066 или HD44780. У них инициализация немного отличается. Посмотрите datasheet на эти микросхемки.

Artem пишет:
никаких ошибок не выдало

Странно. Копипаста кода и последующая попытка компиляции в AVR Studio закончилась:
Цитата:
avr-gcc -mmcu=atmega8a -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT lcd_0.o -MF dep/lcd_0.o.d -c ../lcd_0.c
../lcd_0.c:3:10: error: #include expects "FILENAME" or <FILENAME>
../lcd_0.c:4:56: error: #include expects "FILENAME" or <FILENAME>
../lcd_0.c: In function 'lcd_com':
../lcd_0.c:13:1: error: 'PORTC' undeclared (first use in this function)
../lcd_0.c:13:1: note: each undeclared identifier is reported only once for each function it appears in
../lcd_0.c:13:17: error: 'PC0' undeclared (first use in this function)
../lcd_0.c:14:16: error: 'PC2' undeclared (first use in this function)
../lcd_0.c:15:1: error: 'PORTD' undeclared (first use in this function)
../lcd_0.c:16:1: warning: implicit declaration of function '_delay_us' [-Wimplicit-function-declaration]
../lcd_0.c: In function 'lcd_dat':
../lcd_0.c:25:1: error: 'PORTC' undeclared (first use in this function)
../lcd_0.c:25:16: error: 'PC0' undeclared (first use in this function)
../lcd_0.c:25:26: error: 'PC2' undeclared (first use in this function)
../lcd_0.c:26:1: error: 'PORTD' undeclared (first use in this function)
../lcd_0.c: In function 'main':
../lcd_0.c:53:1: error: 'DDRC' undeclared (first use in this function)
../lcd_0.c:53:15: error: 'PC2' undeclared (first use in this function)
../lcd_0.c:53:26: error: 'PC1' undeclared (first use in this function)
../lcd_0.c:53:37: error: 'PC0' undeclared (first use in this function)
../lcd_0.c:54:1: error: 'PORTC' undeclared (first use in this function)
../lcd_0.c:55:1: error: 'DDRD' undeclared (first use in this function)
../lcd_0.c:56:1: error: 'PORTB' undeclared (first use in this function)
Build failed with 17 errors and 1 warnings...


Причина в невнимательности автора статьи. Статья опубликована 28.02.2011. Почему никто не обратил на это внимание Замешательство

По приведенной мной ссылке программа намного лучше.
8. cjA - 14 Июня, 2013 - 01:28:24 - перейти к сообщению
mihail пишет:
По приведенной мной ссылке программа намного лучше.

-----
А кто спорит? модераторов на сайте нет, куда делись?
(Добавление)
нель зя эт овсе на Си?
9. Artem - 16 Июня, 2013 - 22:36:07 - перейти к сообщению
Короче, посмотрел я я этот даташит, к сожалению в английском небельмес Улыбка
Поэтому пользовался услугами переводчика Гугл, из криво написанных фраз понял, как нужно производить инициализацию, нужно, чтобы на каждой ноге дисплея в определённый момент был определённый сигнал, и комбинация этих сигналов и определяет настройку дисплея. И ещё нужно паузы делать между этими комбинациями.
Я тут подумал, а можно это не через функции делать, а самому, ну точнее, просто программа, которая дёргает ножками микроконтроллера в нужный момент? Я понимаю, что это не очень разумно, но мне кажется, что так у меня лучше получиться не в себе
И ещё такой момент: я не до конца понял, как туда записывается то, что будет выводиться на экран. И того что прочитал, понял, что в памяти дисплея уже хранятся некоторые символы и мы просто вызываем их из памяти ( до конца этот процесс я так и не понял), а как быть с теми символами, которых нет в памяти?
(Добавление)
И ещё такой вопрос: вот даташит на дисплей: http://www.compel.ru/datapdf/win...12b46af5b91e.pdf
Там на 18-ой странице есть алгоритм инициализации дисплея, в первый раз, когда мы выставляем нужные биты на нужные порты-всё понятно (я так понял, что звёздочки-это значит, что без разницы какой там бит?), а во второй раз, там каждому порту соответствует ещё и буква какая-то?
10. mihail - 18 Июня, 2013 - 19:13:29 - перейти к сообщению
Artem пишет:
как быть с теми символами, которых нет в памяти?
Их экранчик не показывает. Все что душе угодно показывают графические экранчики.
Artem пишет:
звёздочки - это значит, что без разницы какой там бит?
Да.

Для начала попробуйте работать с дисплеем через восмибитную шину данных. Ниже приведен пример тестового кода для аналогичного экранчика. За основу взят код с http://chipenable.ru

/* AVR GCC, ATmega8, WH1602B */

#include <avr/io.h>
#include <util/delay.h>

// порт к которому подключена шина данных ЖКД
#define PORT_DATA PORTD
#define PIN_DATA PIND
#define DDRX_DATA DDRD

// порт к которому подключены управляющие выводы ЖКД
#define PORT_SIG PORTB
#define PIN_SIG PINB
#define DDRX_SIG DDRB

// номера выводов к которым подключены управляющие выводы ЖКД
#define RS 4
#define RW 5
#define EN 6

// макросы для работы с битами
#define ClearBit(reg, bit) reg &= (~(1<<(bit)))
#define SetBit(reg, bit) reg |= (1<<(bit))

// функция записи команды
void LcdWriteCom(unsigned char data)
{
ClearBit(PORT_SIG, RS); // установка RS в 0 - команды
PORT_DATA = data; // вывод данных на шину индикатора
SetBit(PORT_SIG, EN); // установка EN в 1
_delay_us(2); // ждем 2 мкс
ClearBit(PORT_SIG, EN); // установка EN в 0
_delay_us(40); // ждем 40 мкс
}

// функция записи данных
void LcdWriteData(unsigned char data)
{
SetBit(PORT_SIG, RS); // установка RS в 1 - данные
PORT_DATA = data; // вывод данных на шину индикатора
SetBit(PORT_SIG, EN); // установка EN в 1
_delay_us(2); // ждем 2 мкс
ClearBit(PORT_SIG, EN); // установка EN в 0
_delay_us(40); // ждем 40 мкс
}

// функция очистки дисплея
void Lcd_Clear(void)
{
LcdWriteCom(0x01);
_delay_ms(2); // ждем 2 мс
}

// позиционирование курсора
void LCD_Goto(unsigned char x, unsigned char y)
{
LcdWriteCom(((((y)& 1)*0x40)+((x)& 15))|128);
}

// функция инициализации
void InitLcd(void)
{
DDRX_DATA = 0xff;
PORT_DATA = 0xff;
DDRX_SIG = 0xff;
PORT_SIG |= (1<<RW)|(1<<RS)|(1<<EN); // установка RW, RS, EN в 1
ClearBit(PORT_SIG, RW); // установка RW в 0

_delay_ms(40); // ждем 40 мс
LcdWriteCom(0b00111000); // 8 разрядная шина, 5*8, 2 строки
LcdWriteCom(0b00001100); // дисплей включен, курсор выключен, мерцание выключено
LcdWriteCom(0b00000001); // очистка дисплея
_delay_ms(2); // ждем 2 мс
LcdWriteCom(0b00000110); // курсор движется вправо, сдвига нет
}

// основная функция программы
int main( void )
{
InitLcd();

LcdWriteData('T');
LcdWriteData('e');
LcdWriteData('s');
LcdWriteData('t');
LcdWriteData('.');

_delay_ms(3000);

Lcd_Clear();

LcdWriteData('0');
LcdWriteData('1');
LcdWriteData('2');
LcdWriteData('3');
LcdWriteData('4');
LcdWriteData('5');
LcdWriteData('6');
LcdWriteData('7');

_delay_ms(3000);

LCD_Goto(0,1);

LcdWriteData('8');
LcdWriteData('9');
LcdWriteData('.');
LcdWriteData('1');
LcdWriteData(' ');
LcdWriteData('e');
LcdWriteData('f');
LcdWriteData('g');

while(1);

return 0;
}
11. Artem - 21 Июня, 2013 - 21:19:30 - перейти к сообщению
Я попробую использовать этот код. Только мне не понятна запись:
CODE:
#define PORT_DATA PORTD
и все остальные записи такого типа что это такое?
Ну я примерно понимаю, что это что-то вроде имён для каких либо регистров.
CODE:
#define ClearBit(reg, bit) reg &= (~(1<<(bit)))
и ещё вот эта строчка, даже не представляю что это Замешательство
И ещё, я написал автору статьи (ссылку я приводил), мне ответили, что нужно поэкспериментировать с задержками в функции инициализации.
12. Predator - 22 Июня, 2013 - 18:26:39 - перейти к сообщению
Цитата:
CODE:
#define PORT_DATA PORTD

это сообщение компилятору о том, что если где-то в тексте встретится слово PORT_DATA, то под этим словом понимать PORTD.

Цитата:
CODE:
#define ClearBit(reg, bit) reg &= (~(1<<(bit)))

это сообщение компилятору о том, что если где-то в тексте встретится слово ClearBit, то ему в скобках должны быть указаны параметры reg, bit и с ними надо произвести вот такую операцию: reg &= (~(1<<(bit))).
13. mihail - 23 Июня, 2013 - 01:09:23 - перейти к сообщению
И я немного расскажу про эти конструкции.

Директива #define обязывает компилятор (точнее препроцессор) заменять в тексте программы один фрагмента кода на другой. Это могут быть символьные константы
#define PORT_DATA	PORTD

После этой директивы, в программе PORT_DATA заменяется на PORTD. Например,
PORT_DATA = 0xff;

становится
PORTD = 0xff;


Еще с помощью этой директивы можно определять макросы. Они похожи на функции, но в их основе также лежит замена кода. В программе, после этой конструкции
#define ClearBit(reg, bit)	reg &= (~(1<<(bit)))

код
ClearBit(PORT_SIG, RS);

заменяется на
PORTB &= (~(1<<(4)));

с учетом замен символьных констант.

Это все используется для удобства программиста и экономии ресурсов микроконтроллера. Часто является причиной ошибок. Подробнее об этой директиве можете прочитать на 134 странице книги Шпак Ю.А. Программирование на яз ыке C для AVR и PIC микроконтрол леров . Еще http://chipenable.ru/index.php/p...predeleniya.html
14. cjA - 30 Июня, 2013 - 13:05:40 - перейти к сообщению
mihail, а ты не учителем работаешь?

и еще,
этот PORTD на самом деле r38
(сами даташидьте, если ошибся)
15. Artem - 19 Июля, 2013 - 23:06:44 - перейти к сообщению
На днях решил ещё раз попробовать подключить дисплей, но не пойму, как определить работает ли предыдущий? При подаче на него питания, без микроконтроллера, что должно произойти, и что должно происходить когда я кручу ручку переменного резистора, должны ли появляться чёрные квадратики?