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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> 4 битный режим ЖК, ничего не выходит
Hellka
сообщение Oct 2 2006, 11:09
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 16
Регистрация: 2-10-06
Пользователь №: 20 895



ривет, никак не получается вывести хоть что-то на ЖК в 4битном режиме, вроде всё правильно написал...
по идее первоначально ЖК стоит в 8битном режиме, т.е. для инициализация сначала использую функцию для 8битного режима, а затем уже для 4битного....
инициализация нормально проходит, т.е. в 4битныйрежим переходит, а вот данные не выдает, у меня подозрение на функцию передачи в 4битном режиме rs_data, уже всё перепробовал - ничего не выходит =(
кидаю текст программы, посмотрите плиз...
ЖК - HD44780U

Код
#include
#include //Для ф-ции
#include <comp_a90.h>

#define CPU_FREQ 2450000//2.450 МГц
#define SOUND_WAIT 10000

unsigned char temp;
unsigned char send_tmp1;
unsigned char send_tmp2;

unsigned char temp1;
unsigned char temp2;

void LCD_initialization(void);
void put_char_to_LCD(char,char,char);
void clear_display(void);
char rs_data(char,char,char);


void print_time_to_LCD(void);
char rs_data_bit(char,char,char);

void main(void)
{
WDTCR=(1<<WDCE)|(1<<WDE);//сброс
WDTCR=0x00;
DDRB=0xFF; //Регистр направления PORTB - все на вывод
PORTB|=(1<<PB4);//вкл. свет
SFIOR|=(1<<PUD);//Запрет pull-up resisitors на всех портах
TCCR1A=0x00; //запрет на signal override portb
SREG&=~0x80; //запрет прерываний устанавливаеться 7 бит регистра "1"
_WDR(); // reset watch dog taimer
LCD_initialization();
clear_display();
while(1)
{WDTCR=(1<<WDCE)|(1<<WDE);//сброс
WDTCR=0x00;
print_time_to_LCD();
//__watchdog_reset();
PORTB&=~(1<<PORTB5); //пищим
__delay_cycles(SOUND_WAIT);//ждем ввода новой информации на LCD
PORTB&=~(1<<PORTB5); //не пищим
}
}
char rs_data_bit(char rs,char rw,char data)//ф-ция передачи команды/данных на ЛСД 8 бит
{
_WDR();
send_tmp1=DDRA; //записываем состояние портов А
send_tmp2=PORTC; //записываем состояние портов С
DDRC|=7; //3 младших бита PORTC на вывод
DDRA=0x00; // А на ввод
PORTC&=0xf8; //pc0 - pc2=0
PORTC|=(1<<PORTC1); //R/W -> "1"
do //Проверка занятости LCD
{
_WDR();
PORTC|=(1<<PORTC2); //E -> UP
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
temp=PINA; //выводы А считали в temp
PORTC&=~(1<<PORTC2); //E -> DOWN
}
while(temp&0x80); //маскируем старший бит - флаг BF(=0, когда LCD свободен)
PORTC&=0xf8; //pc0 - pc2=0
if(rs)
PORTC|=(1<<PC0); //если RS=1 то записываем данные,если нет от RS так и остаеться 0, тоесть идет запись комманд
DDRA=0xff; //PORTA на вывод
PORTA=data; //выводимая информация
PORTC|=(1<<PORTC2); //E->1
__delay_cycles(0.00000045*CPU_FREQ);
PORTC&=~(1<<PORTC2);//E->0
temp=0;
DDRA=send_tmp1; //обнуление портов
PORTC=send_tmp2;
_WDR();
return(temp);
}


char rs_data(char rs,char rw,char data)//ф-ция передачи данных/команд на ЛСД 4бита
{
_WDR();
send_tmp1=DDRA; //записываем состояние портов А
send_tmp2=PORTC; //записываем состояние портов С
DDRC|=7; //3 младших бита PORTC на вывод
DDRA=0x00; // А на ввод
PORTC&=0xf8; //pc0 - pc2=0
PORTC|=(1<<PORTC1); //R/W -> "1"
do //Проверка занятости LCD
{
_WDR();
PORTC|=(1<<PORTC2); //E -> UP
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025

temp1=(PINA & 0xf0); //выводы А считали в temp
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
PORTC&=~(1<<PORTC2); //E -> DOWN
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
PORTC|=(1<<PORTC2); //E -> UP
temp2=((PINA<<4) & 0xf0);
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
PORTC&=~(1<<PORTC2); //E -> DOWN
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
PORTC&=~(1<<PORTC1); //R/W -> "0"
temp=(temp1 | (temp2<<4));

}
while(temp&0x80); //маскируем старший бит - флаг BF(=0, когда LCD свободен)
PORTC&=0xf8; //pc0 - pc2=0
if(rs)
PORTC|=(1<<PC0); //если RS=1 то записываем данные,если нет от RS так и остаеться 0, тоесть идет запись комманд
DDRA=0xff; //PORTA на вывод
PORTA=(data & 0xf0); //выводимая информация
PORTC|=(1<<PORTC2); //E->1
__delay_cycles(0.00000045*CPU_FREQ);
PORTC&=~(1<<PORTC2);//E->0
PORTA=((data<<4) & 0xf0);
PORTC|=(1<<PORTC2); //E->1
__delay_cycles(0.00000045*CPU_FREQ);
PORTC&=~(1<<PORTC2);//E->0

temp=0;
DDRA=send_tmp1; //обнуление портов
PORTC=send_tmp2;
_WDR();
return(temp);
}






void LCD_initialization(void)
{
_WDR();
rs_data_bit(0,0,0x28); //2 строки, 4-разр. шина, инициализируем по 8битной шине, т.к. она идет по умолчанию, после установки в 4разрядную, уже работаем только с ними
rs_data(0,0,0x0C); //вкл. LCD, квадратик, (подчеркивание, то 0x0C)
rs_data(0,0,0x06); //2 строки, 4-разр. шина
}

void clear_display(void)
{
_WDR();
rs_data(0,0,1);//Очистка LCD
}

void put_char_to_LCD(char ch,char string_number,char position)
{
_WDR();
if(string_number==1)
rs_data(0,0,(position-1)|(1<<PA7)); //перемещает символы в первой строке по очереди начиная с 0X80
else
rs_data(0,0,(0x40+position-1)|(1<<PA7));//перемещает символы во второй строке по очереди начиная с 0X80
_WDR();
rs_data(1,0,ch); // передаем как данные
}

void print_time_to_LCD(void)
{
int j; //Ввод данных
put_char_to_LCD('0',1,1);
put_char_to_LCD('0',1,2);
put_char_to_LCD(':',1,3);
put_char_to_LCD('0',1,4);
put_char_to_LCD(0,1,5);

}
Go to the top of the page
 
+Quote Post
sff
сообщение Oct 2 2006, 11:50
Сообщение #2


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

Группа: Свой
Сообщений: 172
Регистрация: 23-04-06
Пользователь №: 16 404



Цитата(Hellka @ Oct 2 2006, 15:09) *
инициализация нормально проходит, т.е. в 4битныйрежим переходит, а вот данные не выдает, у меня подозрение на функцию передачи в 4битном режиме rs_data, уже всё перепробовал - ничего не выходит =(
кидаю текст программы, посмотрите плиз...
ЖК - HD44780U

[code]
...
PORTC|=(1<<PORTC1); //R/W -> "1"
do //Проверка занятости LCD
{
_WDR();
PORTC|=(1<<PORTC2); //E -> UP
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025

temp1=(PINA & 0xf0); //выводы А считали в temp
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
PORTC&=~(1<<PORTC2); //E -> DOWN
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
PORTC|=(1<<PORTC2); //E -> UP
temp2=((PINA<<4) & 0xf0);
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
PORTC&=~(1<<PORTC2); //E -> DOWN
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
///////////////////////////////////////////////////////////////////////
PORTC&=~(1<<PORTC1); //R/W -> "0"
///////////////////////////////////////////////////////////////////////
temp=(temp1 | (temp2<<4));

}
while(temp&0x80); //маскируем старший бит - флаг BF(=0, когда LCD свободен)

А Вам не кажется что "PORTC&=~(1<<PORTC1); " как-то не к месту во время опроса состояния в цикле. Вот в 8 битном нормальный опрос и R/W там не трогалось
Go to the top of the page
 
+Quote Post
Hellka
сообщение Oct 2 2006, 12:03
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 16
Регистрация: 2-10-06
Пользователь №: 20 895



Цитата(sff @ Oct 2 2006, 14:50) *
Цитата(Hellka @ Oct 2 2006, 15:09) *

инициализация нормально проходит, т.е. в 4битныйрежим переходит, а вот данные не выдает, у меня подозрение на функцию передачи в 4битном режиме rs_data, уже всё перепробовал - ничего не выходит =(
кидаю текст программы, посмотрите плиз...
ЖК - HD44780U

[code]
...
PORTC|=(1<<PORTC1); //R/W -> "1"
do //Проверка занятости LCD
{
_WDR();
PORTC|=(1<<PORTC2); //E -> UP
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025

temp1=(PINA & 0xf0); //выводы А считали в temp
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
PORTC&=~(1<<PORTC2); //E -> DOWN
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
PORTC|=(1<<PORTC2); //E -> UP
temp2=((PINA<<4) & 0xf0);
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
PORTC&=~(1<<PORTC2); //E -> DOWN
__delay_cycles(0.00000045*CPU_FREQ);//450 нс, чтобы успело сработать по докум. 1.1025
///////////////////////////////////////////////////////////////////////
PORTC&=~(1<<PORTC1); //R/W -> "0"
///////////////////////////////////////////////////////////////////////
temp=(temp1 | (temp2<<4));

}
while(temp&0x80); //маскируем старший бит - флаг BF(=0, когда LCD свободен)

А Вам не кажется что "PORTC&=~(1<<PORTC1); " как-то не к месту во время опроса состояния в цикле. Вот в 8 битном нормальный опрос и R/W там не трогалось


ну в мануале именно так написано, нао попробовать завтра на макете, а насчет самих пердач:
temp1=(PINA & 0xf0); //выводы А считали в temp итд, здесь всё правильно?
как в чтении так и в записи?
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Oct 2 2006, 12:11
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Задержки правильно считаются?


void ShortDelay(void) { char i; for (i=1; i<5; i++) ;}

void WriteByte(char D)
{ LcdData=(D>>4)&0x0f;
SetLcdData;
OnLcdE;
ShortDelay();
OffLcdE;
ShortDelay();

LcdData=D&0x0f;
SetLcdData;
OnLcdE;
ShortDelay();
OffLcdE;
ShortDelay();
LcdData=0;
SetLcdData;
}

void WriteLcdData(char D)
{ OnLcdRs;
WriteByte(D);
}

void WriteLcdControl(char D)
{ OffLcdRs;
WriteByte(D);
}

void InitLcd(void)
{
// char i;
WriteLcdControl(0x28);
Delay(5);
WriteLcdControl(0x28);
Delay(1);
WriteLcdControl(0x28);
Delay(1);
WriteLcdControl(0x28);
Delay(5);
WriteLcdControl(0x0C);
Delay(1);
WriteLcdControl(0x01);
Delay(5);
WriteLcdControl(0x06);
Delay(1);
WriteLcdControl(0x02);
Delay(1);
InitVar();
ClrScr();
// CreateCharSet();
}


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
sff
сообщение Oct 2 2006, 12:26
Сообщение #5


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

Группа: Свой
Сообщений: 172
Регистрация: 23-04-06
Пользователь №: 16 404



Цитата(Hellka @ Oct 2 2006, 16:03) *
[code]
...
do //Проверка занятости LCD
{
...
temp1=(PINA & 0xf0); //выводы А считали в temp
...
temp2=((PINA<<4) & 0xf0);
...
temp=(temp1 | (temp2<<4));
}

ну в мануале именно так написано, нао попробовать завтра на макете, а насчет самих пердач:
temp1=(PINA & 0xf0); //выводы А считали в temp итд, здесь всё правильно?
как в чтении так и в записи?

Ну я в цикле 4битного опроса R/W не дергаю, да и зачем?? ведь тогда на следущей итерации в цикле уже не чтение а запись подразумевается.

А вот на temp я поначалу не обратил внимания ..
во-первых ((PINA<<4) & 0xf0); можно и без логического AND обойтись результат не изменится.

а во-вторых (я так понимаю данные на PA0-PA3 лежат) конструкция (PINA & 0xf0) убивает релевантные биты. Если подумать что данные на PA4-PA7 тогда ((PINA<<4) & 0xf0) бессмысленна.

Если бы данные были в PA0-PA3 я бы записал так:
...
temp=(PINA << 4); //вместо temp1
...
temp |= (PINA & 0x0f); //вместо temp2
...
Go to the top of the page
 
+Quote Post
Hellka
сообщение Oct 2 2006, 12:34
Сообщение #6


Участник
*

Группа: Новичок
Сообщений: 16
Регистрация: 2-10-06
Пользователь №: 20 895



данные на PA0-PA7, но так как 4битный режим то передаем только через старшую тетраду, соответственно на PA4-PA7

Dog Pawlowa это ты фрагмент программы кинул? а можешь всю скинуть? да задержки счиатются нормально, он же переводит нормально в 4битный режим
Go to the top of the page
 
+Quote Post
sff
сообщение Oct 2 2006, 12:35
Сообщение #7


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

Группа: Свой
Сообщений: 172
Регистрация: 23-04-06
Пользователь №: 16 404



Цитата(Hellka @ Oct 2 2006, 16:31) *
данные на PA0-PA7, но так как 4битный режим то передаем только через старшую тетраду, соответственно на PA4-PA7

Просто у меня к PA0-PA3 было разведено =)
ну тогда
...
temp=(PINA & 0xF0); //вместо temp1
...
temp |= (PINA >> 4); //вместо temp2
...

В догонку выдрал свои функции из реально рабочего девайсаПрикрепленный файл  LCD_Example.txt ( 5.21 килобайт ) Кол-во скачиваний: 203


Сообщение отредактировал sff - Oct 2 2006, 12:48
Go to the top of the page
 
+Quote Post
Hellka
сообщение Oct 2 2006, 12:52
Сообщение #8


Участник
*

Группа: Новичок
Сообщений: 16
Регистрация: 2-10-06
Пользователь №: 20 895



а в передаче данных\команд всё так и оставить? или также RW убрать в конце?
Go to the top of the page
 
+Quote Post
prottoss
сообщение Oct 2 2006, 19:23
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



в http://electronix.ru/forum/index.php?showtopic=10934 есть полностью рабочий драйвер для символьных ЖКИ, и еще, по моему, вариант реализации бегущей строки. Драйвер был написан мною с подробнейшими комментариями. Скачивайте и пользуйтесь))) Удачи


--------------------
Go to the top of the page
 
+Quote Post
Igor26
сообщение Oct 3 2006, 05:13
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 521
Регистрация: 10-02-05
Пользователь №: 2 544



Цитата(prottoss @ Oct 2 2006, 23:23) *
в http://electronix.ru/forum/index.php?showtopic=10934 есть полностью рабочий драйвер для символьных ЖКИ, и еще, по моему, вариант реализации бегущей строки. Драйвер был написан мною с подробнейшими комментариями. Скачивайте и пользуйтесь))) Удачи

Проверенно. Рекомендую.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 3 2006, 07:40
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



А вот документ сам пользовался.
Прикрепленные файлы
Прикрепленный файл  Powertip.zip ( 121.97 килобайт ) Кол-во скачиваний: 314
 
Go to the top of the page
 
+Quote Post
Hellka
сообщение Oct 4 2006, 09:52
Сообщение #12


Участник
*

Группа: Новичок
Сообщений: 16
Регистрация: 2-10-06
Пользователь №: 20 895



народ как си кодом поменять местами старшую и младшую тетраду, типа как swap(data) в ассемблере?
Go to the top of the page
 
+Quote Post
prottoss
сообщение Oct 4 2006, 10:11
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Hellka @ Oct 4 2006, 17:52) *
народ как си кодом поменять местами старшую и младшую тетраду, типа как swap(data) в ассемблере?




i = (i >> 4) | (i << 4);



при максимальном уровне оптимизации и хорошей погоде компилятор может сгенерить даже чистый SWAP rxx


--------------------
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 4 2006, 10:41
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(prottoss @ Oct 4 2006, 13:11) *
Цитата(Hellka @ Oct 4 2006, 17:52) *
народ как си кодом поменять местами старшую и младшую тетраду, типа как swap(data) в ассемблере?




i = (i >> 4) | (i << 4);



при максимальном уровне оптимизации и хорошей погоде компилятор может сгенерить даже чистый SWAP rxx


Ну а в IARе можно и так i = __swap_nibbles(i); Хотя для универсальности лучше вариант предложенный 'prottoss' . smile.gif
Go to the top of the page
 
+Quote Post
ps1x
сообщение Oct 4 2006, 23:41
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



Ну так заработал дисплей?
Есть одна версия - если дисплей фирмы МЕЛТ то 4 битный режим включается немного не так как стандартный HD. smile.gif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 01:18
Рейтинг@Mail.ru


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