Страница 26 из 123

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Пт дек 31, 2010 11:56:47
Arlleex
Здравствуйте, akl.
На самом же деле не надо ничего выдерживать.
ведь я проверяю флаг занятости BF.
а это означает - что не надо вводить никаких задержек.

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Пт дек 31, 2010 16:29:40
akl
Не надо ничего выдерживать - значит не надо. :shock: С Новым годом!

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Пт дек 31, 2010 16:42:02
Arlleex
Вас тоже с наступающим!
Насчет lcd. В описании же ведь написано, что при условии чтения флага занятости hd44780 задержки вводить не надо.

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Пт дек 31, 2010 18:08:21
akl

Код: Выделить всё

read_BF:
sbi portd, 2 ; E=1
in r18, pinc ; Считывание данных в r18
cbi portd, 2 ; E=0
ret
Вот фрагмент Вашего чтения BF. Предварительно линии шины контроллера переведены на ввод.
Что делает контроллер
- принимает и следующим тактом, т.е. уже при выборке команды IN R18,PINC выставляет E=1
- через 1 мкс (при тактовой 1МГц) записывает состояние шины в регистр
- снимает сигнал E=0
Вроде, все правильно, но... Вы уверены, что линия управления E успеет передать изменение логических уровней 0->1->0 и за это время выходной драйвер HD44780 успеет выставить состояние регистра состояния с учетом параметров шины ( паразитных емкостей печати, шлейфа; плохом, в лучшем случае, согласовании импедансов линии - тут будет и "звон" и "отражение"). Я не уверен. Поэтому и ставлю задержки типа

Код: Выделить всё

write_lcd:
out portc, r16 ; Запись в lcd
;здесь нужна задержка
	RCALL W
	sbi portd, 2 ; E=1
	RCALL W
	cbi portd, 2 ; E=0
	RCALL W
	out portd, r17 ; Data????????????????? line Hi-Z
W:
	ret
Намеренно не везде их проставил, чтобы Вы осознанно подошли к этому и далее проставили их самостоятельно. Я правильно сделал? :oops:

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Пт дек 31, 2010 20:29:36
Arlleex
Вроди бы правильно...
Только чтение флага занятости занимает 0мкс для hd44780

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Сб янв 01, 2011 20:12:40
Arlleex
Между командами надо выдерживать паузы.
А между командами записи данных в DDRAM???? и сколько?

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Вс янв 02, 2011 00:15:04
Babayjon
Уважаемые коты и кошки помогите разобраться с LM016 в протэусе. Имеется вот такая схема "Матричная клавиатура 4х4 динамическое считывание данных с портов" Изображение. К схеме имеется готовая прошивка, но с индикатором WH1602. Собрал схему в протэусе, но вместо WH1602 я присоединил LM016. Вставил прошивку в МК. Запустил, ноги индикатора пинингуются, он загорается но при нажатии любой клавиши, на индикаторе ничего не появляется. Создавал еще несколько проектов в протеусе с заменой ЖКИ, тоже самое. Подсказали что, время задерки кажется не совподает. Я новичек, так что прошу сильно не бить. А вот и прошивка.

#include <avr/io.h>
#include <avr/interrupt.h>

#define NUMBER_SIZE 6 //Максимальная разрядность числа

#define RS 2 //RS=PD2
#define E 3 //E=PD3

#define TIME 10 //временная константа для ЖКИ
//Тактовая частота 4Mhz

unsigned char key_code[4][4]={{'C','D','E','F'},
{'B','3','6','9'},
{'A','2','5','8'},
{'0','1','4','7'}}; //Коды клавиш

unsigned char row[NUMBER_SIZE]={}; //массив, который содержит нажатые клавиши
unsigned char row_counter=0; //количество нажатых клавиш

unsigned long int number=0; //Число морганий курсора

void pause (unsigned int a)
{ unsigned int i;

for (i=a;i>0;i--)
;
}

//Передача команды ЖКИ
void lcd_com (unsigned char lcd)
{ unsigned char temp;

temp=(lcd&~(1<<RS))|(1<<E); //RS=0 – это команда
PORTD=temp; //Выводим на portD старшую тетраду команды, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи команды

temp=((lcd*16)&~(1<<RS))|(1<<E); //RS=0 – это команда
PORTD=temp; //Выводим на portD младшую тетраду команды, сигналы RS, Е
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи команды

pause (10*TIME); //Пауза для выполнения команды
}

//Запись данных в ЖКИ
void lcd_dat (unsigned char lcd)
{ unsigned char temp;

temp=(lcd|(1<<RS))|(1<<E); //RS=1 – это данные
PORTD=temp; //Выводим на portD старшую тетраду данных, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи данных

temp=((lcd*16)|(1<<RS))|(1<<E); //RS=1 – это данные
PORTD=temp; //Выводим на portD младшую тетраду данных, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи данных

pause(TIME); //Пауза для вывода данных
}

//Иниализация ЖКИ
void lcd_init (void)
{
lcd_com(0x2c); //4-проводный интерфейс, 5x8 размер символа
pause(100*TIME);
lcd_com(0x0c); //Показать изображение, курсор не показывать
pause(100*TIME);
lcd_com(0x01); //Очистить DDRAM и установить курсор на 0x00
pause (100*TIME);
}


void init_timer (void)
{
TIMSK=(1<<TOIE0); //Разрешить прерывания по переполнению таймера0
TCCR0=(1<<CS00)|(1<<CS01)|(0<<CS02); //Делитель =/64
}

//Проверка, является ли х цифрой, если да результат =1, иначе результат =0
unsigned char is_digit (unsigned char x)
{
if ((x>='0')&&(x<='9')) return 1;
else return 0;
}

//Конвертирует "row" в int значение number
void get_number(void)
{ unsigned char i;
number=0;
for (i=0;i<row_counter;i++)
{
number=number*10;
number=number+row-0x30;
}
}

//Пишем row на ЖКИ
void write_row (void)
{ unsigned char i;

lcd_com(0x86); //Перейдем в начало
for (i=0;i<row_counter;i++) //Пишем row
lcd_dat(row);
for(i=row_counter;i<NUMBER_SIZE;i++) //Очистим незаполненные ячейки
lcd_dat(' ');
}

ISR (TIMER0_OVF_vect)
{ unsigned char i,j;

DDRC=0x00; //PortC как вход
PORTC=0x0f;
DDRB=0x0f; //PortB как выход
PORTB=0x00;

pause(10); //Задержка для устренения всяких переходных процессов, важно ее не забыть!
i=4;
if ((PINC&0x01)==0x00) i=0; //Если нажата клавиша в 0й колонке, i=0
if ((PINC&0x02)==0x00) i=1; //...
if ((PINC&0x04)==0x00) i=2;
if ((PINC&0x08)==0x00) i=3;

DDRC=0x0f; //PortC как выход
PORTC=0x00;
DDRB=0x00; //PortB как вход
PORTB=0x0f;

pause(10); //Задержка для устренения всяких переходных процессов, важно ее не забыть!
j=4;
if ((PINB&0x01)==0x00) j=0; //Если нажата клавиша в 0й строке, j=0
if ((PINB&0x02)==0x00) j=1; //...
if ((PINB&0x04)==0x00) j=2;
if ((PINB&0x08)==0x00) j=3;

if ((i!=4)&&(j!=4))
{ //Если была нажата клавиша
while ((PINB&_BV(j))==0x00) //Ждем отжатия
;

if ((is_digit(key_code[j])==1)&& //Нажата цифра и не достигнут лимит в NUMBER_SIZE
(row_counter<NUMBER_SIZE)) { //Добавить в row и увеличить row_counter
row[row_counter]=key_code[j];
row_counter++;
}
if (key_code[j]=='F') row_counter=0x00; //Если нажата 'F' очищаем row
if ((key_code[j]=='E')&&
(row_counter>0x00)) row_counter--; //Если нажата 'E'
//и есть введенные цифры – удалить последнюю
if (key_code[j]=='C') { //Если нажата 'C' тогда мигаем number раз
get_number();
while (number>0) //Мигаем number раз
{
lcd_com(0xc0);
lcd_dat(0xff);
pause(32000);
pause(32000);
pause(32000);
pause(32000);
lcd_com(0xc0);
lcd_dat(' ');
pause(32000);
pause(32000);
pause(32000);
pause(32000);
number=number-1;
}
}
write_row(); //Пишем row на ЖКИ
}
TCNT0=0x00; //Очищаем таймер и флаг переполнения
TIFR=0x00;

return;
}

int main(void)
{
DDRD=0xfc; //Инициализация PortD
PORTD=0x00;

pause(1000); //Задержка для включения ЖКИ
lcd_init(); //Инициализация ЖКИ
init_timer(); //Инициализация нулевого таймера
lcd_dat('D'); //Напишем на ЖКИ "Data= "
lcd_dat('a');
lcd_dat('t');
lcd_dat('a');
lcd_dat('=');
lcd_dat(' ');

sei(); //Разрешения прерываний

while(1) //Вечный цикл
;

return 1;
}

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Вс янв 02, 2011 00:17:31
Babayjon
Уважаемые коты и кошки помогите разобраться с LM016 в протэусе. Имеется вот такая схема "Матричная клавиатура 4х4 динамическое считывание данных с портов" Изображение. К схеме имеется готовая прошивка, но с индикатором WH1602. Собрал схему в протэусе, но вместо WH1602 я присоединил LM016. Вставил прошивку в МК. Запустил, ноги индикатора пинингуются, он загорается но при нажатии любой клавиши, на индикаторе ничего не появляется. Создавал еще несколько проектов в протеусе с заменой ЖКИ, тоже самое. Подсказали что, время задерки кажется не совподает. Я новичек, так что прошу сильно не бить. А вот и прошивка.

#include <avr/io.h>
#include <avr/interrupt.h>

#define NUMBER_SIZE 6 //Максимальная разрядность числа

#define RS 2 //RS=PD2
#define E 3 //E=PD3

#define TIME 10 //временная константа для ЖКИ
//Тактовая частота 4Mhz

unsigned char key_code[4][4]={{'C','D','E','F'},
{'B','3','6','9'},
{'A','2','5','8'},
{'0','1','4','7'}}; //Коды клавиш

unsigned char row[NUMBER_SIZE]={}; //массив, который содержит нажатые клавиши
unsigned char row_counter=0; //количество нажатых клавиш

unsigned long int number=0; //Число морганий курсора

void pause (unsigned int a)
{ unsigned int i;

for (i=a;i>0;i--)
;
}

//Передача команды ЖКИ
void lcd_com (unsigned char lcd)
{ unsigned char temp;

temp=(lcd&~(1<<RS))|(1<<E); //RS=0 – это команда
PORTD=temp; //Выводим на portD старшую тетраду команды, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи команды

temp=((lcd*16)&~(1<<RS))|(1<<E); //RS=0 – это команда
PORTD=temp; //Выводим на portD младшую тетраду команды, сигналы RS, Е
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи команды

pause (10*TIME); //Пауза для выполнения команды
}

//Запись данных в ЖКИ
void lcd_dat (unsigned char lcd)
{ unsigned char temp;

temp=(lcd|(1<<RS))|(1<<E); //RS=1 – это данные
PORTD=temp; //Выводим на portD старшую тетраду данных, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи данных

temp=((lcd*16)|(1<<RS))|(1<<E); //RS=1 – это данные
PORTD=temp; //Выводим на portD младшую тетраду данных, сигналы RS, E
asm("nop"); //Небольшая задержка в 1 такт МК, для стабилизации
PORTD=temp&~(1<<E); //Сигнал записи данных

pause(TIME); //Пауза для вывода данных
}

//Иниализация ЖКИ
void lcd_init (void)
{
lcd_com(0x2c); //4-проводный интерфейс, 5x8 размер символа
pause(100*TIME);
lcd_com(0x0c); //Показать изображение, курсор не показывать
pause(100*TIME);
lcd_com(0x01); //Очистить DDRAM и установить курсор на 0x00
pause (100*TIME);
}


void init_timer (void)
{
TIMSK=(1<<TOIE0); //Разрешить прерывания по переполнению таймера0
TCCR0=(1<<CS00)|(1<<CS01)|(0<<CS02); //Делитель =/64
}

//Проверка, является ли х цифрой, если да результат =1, иначе результат =0
unsigned char is_digit (unsigned char x)
{
if ((x>='0')&&(x<='9')) return 1;
else return 0;
}

//Конвертирует "row" в int значение number
void get_number(void)
{ unsigned char i;
number=0;
for (i=0;i<row_counter;i++)
{
number=number*10;
number=number+row-0x30;
}
}

//Пишем row на ЖКИ
void write_row (void)
{ unsigned char i;

lcd_com(0x86); //Перейдем в начало
for (i=0;i<row_counter;i++) //Пишем row
lcd_dat(row);
for(i=row_counter;i<NUMBER_SIZE;i++) //Очистим незаполненные ячейки
lcd_dat(' ');
}

ISR (TIMER0_OVF_vect)
{ unsigned char i,j;

DDRC=0x00; //PortC как вход
PORTC=0x0f;
DDRB=0x0f; //PortB как выход
PORTB=0x00;

pause(10); //Задержка для устренения всяких переходных процессов, важно ее не забыть!
i=4;
if ((PINC&0x01)==0x00) i=0; //Если нажата клавиша в 0й колонке, i=0
if ((PINC&0x02)==0x00) i=1; //...
if ((PINC&0x04)==0x00) i=2;
if ((PINC&0x08)==0x00) i=3;

DDRC=0x0f; //PortC как выход
PORTC=0x00;
DDRB=0x00; //PortB как вход
PORTB=0x0f;

pause(10); //Задержка для устренения всяких переходных процессов, важно ее не забыть!
j=4;
if ((PINB&0x01)==0x00) j=0; //Если нажата клавиша в 0й строке, j=0
if ((PINB&0x02)==0x00) j=1; //...
if ((PINB&0x04)==0x00) j=2;
if ((PINB&0x08)==0x00) j=3;

if ((i!=4)&&(j!=4))
{ //Если была нажата клавиша
while ((PINB&_BV(j))==0x00) //Ждем отжатия
;

if ((is_digit(key_code[j])==1)&& //Нажата цифра и не достигнут лимит в NUMBER_SIZE
(row_counter<NUMBER_SIZE)) { //Добавить в row и увеличить row_counter
row[row_counter]=key_code[j];
row_counter++;
}
if (key_code[j]=='F') row_counter=0x00; //Если нажата 'F' очищаем row
if ((key_code[j]=='E')&&
(row_counter>0x00)) row_counter--; //Если нажата 'E'
//и есть введенные цифры – удалить последнюю
if (key_code[j]=='C') { //Если нажата 'C' тогда мигаем number раз
get_number();
while (number>0) //Мигаем number раз
{
lcd_com(0xc0);
lcd_dat(0xff);
pause(32000);
pause(32000);
pause(32000);
pause(32000);
lcd_com(0xc0);
lcd_dat(' ');
pause(32000);
pause(32000);
pause(32000);
pause(32000);
number=number-1;
}
}
write_row(); //Пишем row на ЖКИ
}
TCNT0=0x00; //Очищаем таймер и флаг переполнения
TIFR=0x00;

return;
}

int main(void)
{
DDRD=0xfc; //Инициализация PortD
PORTD=0x00;

pause(1000); //Задержка для включения ЖКИ
lcd_init(); //Инициализация ЖКИ
init_timer(); //Инициализация нулевого таймера
lcd_dat('D'); //Напишем на ЖКИ "Data= "
lcd_dat('a');
lcd_dat('t');
lcd_dat('a');
lcd_dat('=');
lcd_dat(' ');

sei(); //Разрешения прерываний

while(1) //Вечный цикл
;

return 1;
}

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Вс янв 02, 2011 02:29:38
yaotzin
измени

//Иниализация ЖКИ
void lcd_init (void)
{
lcd_com(0x02);
pause(100*TIME);

lcd_com(0x2c); //4-проводный интерфейс, 5x8 размер символа
pause(100*TIME);
lcd_com(0x0c); //Показать изображение, курсор не показывать
pause(100*TIME);
lcd_com(0x01); //Очистить DDRAM и установить курсор на 0x00
pause (100*TIME);
}

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Вс янв 02, 2011 06:47:58
akl
Stalker46 писал(а):Между командами надо выдерживать паузы.
А между командами записи данных в DDRAM???? и сколько?
Для того, чтобы не гадать "сколько?" и служит флаг занятости BF. Если временная диаграмма обмена с HD44780 (установка адреса, RS, RW, E) выдержана, остается только анализ BF. В итоге это значительно ускоряет правильную выдачу на индикацию.
Изображение
Изображение
Изображение

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Вс янв 02, 2011 13:48:27
Arlleex
да не, я сделал программную задержку в 1,5мс, 40мкс.
Но это для записи команд в IR.
А для записи данных в DR нужно всего лишь выдержать вот такие временные параметры:
Изображение
и не выдерживать никаких 40мкс или 1,5мс после записи.
Ведь так?
Ведь эти 1,5мс или 40мкс - это всего лишь задержки внутренней инициализации LCD (например, установка курсора или адреса, там...)

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Вс янв 02, 2011 16:36:00
akl
Не совсем так. Например:
-адресный вывод на экран, т.е. в формате адрес-данные
-генерирование и вывод собственных символов из CGRAM
-использование DDRAM в качестве внешней памяти
Даже при монотонном выводе на индикацию двух строк нужно хотя бы раз скомандовать IR переход AC на вторую строку, т.е затратить 40мкс.
Можно ввести простую задержку, остановив практически контроллер, а можно, с помощью BF, выполнить какие-то другие полезные действия.

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Вс янв 02, 2011 19:18:30
Arlleex
Все, понял, спасибо:) но все равно лишний раз заходите в эту тему:) я не раз еще буду спрашивать)))

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Вс янв 02, 2011 19:37:41
Arlleex
.include "tn2313def.inc" ; Используем микроконтроллер Attiny2313
.cseg
.org 0
rjmp reset
;********************************************************************
reset:
ldi r16, low (RAMEND) ; Инициализация стека
out SPL, r16
rcall lcd_init
;********************************************************************
lcd_init:
ldi r16, 0b10000000 ; PUD>>1
out MCUCR, r16
ldi r16, 0b11111111 ; Настройка порта B
out ddrb, r16
ldi r16, 0b00000111 ; Настройка порта D
out ddrd, r16
;********************************************************************
ldi r16, 0b00000001 ; Сброс предделителя T0
out GTCCR, r16
;********************************************************************
ldi r16, 0b00000000 ; RS>>0
ldi r17, 0b00110000 ; Установка парамеров (Lcd Data 8 bit)
rcall delay_20000mks ; Пауза 20000мкс
rcall write_lcd ; Запись в lcd
rcall delay_40mks ; Пауза 40мкс
rcall write_lcd ; Запись в lcd
rcall delay_40mks ; Пауза 40мкс
rcall write_lcd ; Запись в lcd
rcall delay_40mks ; Пауза 40мкс
ldi r17, 0b00111000 ; Установка параметров
rcall write_lcd ; Запись в lcd
rcall delay_40mks ; Пауза 40мкс
ldi r17, 0b00001000 ; Выключение дисплея
rcall write_lcd ; Запись в lcd
rcall delay_40mks ; Пауза 40мкс
ldi r17, 0b00000001 ; Очистка дисплея
rcall write_lcd ; Запись в lcd
rcall delay_1500mks ; Пауза 1500мкс
ldi r17, 0b00000110 ; Установка режима ввода данных
rcall write_lcd ; Запись в lcd
rcall delay_40mks ; Пауза 40мкс
ret
;********************************************************************
delay_20000mks:
ldi r18, 0b
ldi r19, 0b
rjmp init_delay
delay_1500mks:
ldi r18, 0b
ldi r19, 0b
rjmp init_delay
delay_40mks:
ldi r18, 0b
ldi r19, 0b
init_delay:
out TCNT0, r18 ; Ввод переменной задержки
out TCCR0B, r19 ; Настройка предделителя
test:
in r20, TIFR ; Чтение TIFR
sbrs r20, 1 ; Пропустить, если TOV0>>1
rjmp test
out TCCR0B, r16 ; Остановка T0
ret
;********************************************************************
write_lcd:
out portd, r16 ; Установить значение линии RS
out portb, r17 ; Вывести байт данных DB0-DB7
sbi portd, 2 ; E>>1
cbi portd, 2 ; E>>0
out portd, r16 ; DB0-DB7 Hi-Z
ret
;********************************************************************
user_write_IR:
ldi r16, 0b00000000 ; Адресация IR
rcall write_lcd ; Запись в lcd
rcall delay_40mks ; Пауза 40мкс
ret
;********************************************************************
user_write_DR:
ldi r16, 0b00000001 ; Адресация DR
rcall write_lcd ; Запись в lcd
rcall delay_40mks ; Пауза 40мкс
ret
Пока что вот так))))

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Вс янв 02, 2011 22:18:05
Babayjon
yaotzin спасибо. Всё заработало. Урааааа

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Вс янв 02, 2011 23:54:41
yaotzin
Babayjon писал(а):yaotzin спасибо. Всё заработало. Урааааа
это методом тыка lcd_com(0x02); а почему оно так хз =))) сам мучался, наверное надо прочитать инструкцию к LM016L - хотя нафига=) если это только для протеуса.

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Пн янв 03, 2011 15:07:39
Arlleex
и все же странные странности происходят с моим LCD...
сделал все с задержками, даже увеличил их раз в 5, на дисплей выводятся глюки.
т.е. включил питание - дисплей инициализировался, но не вывел символы, или проинициализировался и вывел все что надо (это хорошо, не глюк), или вообще не проинициализировался.... вообщем глючит по-страшному.
Ну что еще не так?:)

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Пн янв 03, 2011 16:44:31
yaotzin
процесс инициализации (блок схема) правильной инициализации показана в спецификации контроллера LCD, начни с этого, и сделай так как там написано.

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Ср янв 05, 2011 20:27:56
Gudd-Head
У кого какой максимальной длины был шлейф до работающего дисплея с данным контроллером?

Re: Работа с ЖКИ на контроллере HD44780 и его аналогах

Добавлено: Чт янв 06, 2011 00:02:09
Arlleex
от скорости зависит.
У меня на частоте 1 МГц с минимально-допустимыми задержками на 30см работает хорошо