|
4 битный режим ЖК, ничего не выходит |
|
|
|
Oct 2 2006, 11:09
|
Участник

Группа: Новичок
Сообщений: 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);
}
|
|
|
|
|
Oct 2 2006, 11:50
|
Частый гость
 
Группа: Свой
Сообщений: 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 там не трогалось
|
|
|
|
|
Oct 2 2006, 12:03
|
Участник

Группа: Новичок
Сообщений: 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 итд, здесь всё правильно? как в чтении так и в записи?
|
|
|
|
|
Oct 2 2006, 12:26
|
Частый гость
 
Группа: Свой
Сообщений: 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 ...
|
|
|
|
|
Oct 2 2006, 12:34
|
Участник

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

|
данные на PA0-PA7, но так как 4битный режим то передаем только через старшую тетраду, соответственно на PA4-PA7
Dog Pawlowa это ты фрагмент программы кинул? а можешь всю скинуть? да задержки счиатются нормально, он же переводит нормально в 4битный режим
|
|
|
|
|
Oct 2 2006, 12:35
|
Частый гость
 
Группа: Свой
Сообщений: 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
|
|
|
|
|
Oct 2 2006, 12:52
|
Участник

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

|
а в передаче данных\команд всё так и оставить? или также RW убрать в конце?
|
|
|
|
|
Oct 4 2006, 09:52
|
Участник

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

|
народ как си кодом поменять местами старшую и младшую тетраду, типа как swap(data) в ассемблере?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|