Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: подключение lcd FDCC2004A к atmega8
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
failguru
простой код(выводит символ на lcd), а не пашет ничего
вот код на cvavr:

#include <io.h>
#include <delay.h>
#define E PORTC.2
#define RS PORTC.0
#define RW PORTC.1
#define port PORTD
int chkbf(){ // проверка флага занятости
DDRD=0x00;
RS=0;
RW=1;
E=0;
delay_us(2);
port=0xff;
delay_us(2);
E=1;
delay_us(2);
E=0;
return(PIND.7);
}
void wrcmd(int cmd){ // пишу команду
DDRD=0xff;
while(chkbf());
RS=0;
RW=0;
E=0;
delay_us(2);
port=cmd;
delay_us(2);
E=1;
delay_ms(2);
E=0;
}
void main(){
DDRC=0xff;
PORTC=0x00;
delay_ms(100);

wrcmd(0b00111000); // инициализация
delay_us(40);
wrcmd(0b00001111);
delay_us(40);
wrcmd(0b00000001);
delay_ms(2);
wrcmd(0b00000110);
delay_us(40);

DDRD=0xff; // пишу символ
while(chkbf());
RS=0;
RW=1;
E=0;
delay_us(2);
PORTD=0b00110001;
delay_us(2);
E=1;
delay_us(2);
E=0;
delay_us(50);
}

че нитак??? v0 для контрастности кинул на землю через резистор 1 кОм вроде нормал
SortoVaritu
Контроллер SPLCD780D?
failguru
S6A0069 самсунговский помойму,
даташит даже нашел, прикрепляю
SortoVaritu
Код
DDRD=0x00; - выставляете порт D как выход
RS=0;
RW=1;
E=0;
delay_us(2);
port=0xff; - включаете подтяжку на порт D. почему после 2мкс?
delay_us(2);
E=1;
delay_us(2);
E=0;
return(PIND.7);



http://www.hantronix.com/files/down/splc780d.pdf
пункт 5.4 - подробно расписан пример написания слова на дисплее
ILYAUL
Цитата(SortoVaritu @ Nov 1 2011, 19:26) *
Код
DDRD=0x00; - выставляете порт D как ...

ВХОД
SortoVaritu
Цитата(failguru @ Nov 1 2011, 18:11) *
S6A0069 самсунговский помойму,
даташит даже нашел, прикрепляю


именно поэтому лучше писать не жки а контроллер, так как в данном случае от жки мало что зависит

DDRD=0x00; - выставляете порт D как вход... это я очепятался
failguru
да, спасибо, поставил в начало функции проверки бизи флага, но это не спасло(((((((((

Изчезли темные квадраты!!!! и появился курсор в непонятном месте! УЖЕ ЧТОТО!!!!

Вот код переделал:

Код
#include <io.h>
#include <delay.h>
#define E PORTC.2
#define RS PORTC.0
#define RW PORTC.1
#define port PORTD
int chkbf(){    // проверка флага занятости
    DDRD=0x00;
    port=0xff;
    RS=0;
    RW=1;
    E=0;
    delay_us(2);
    E=1;
    delay_us(2);
    E=0;
    return(PIND.7);    
}
void wrcmd(int cmd){    // пишу команду
    DDRD=0xff;
    //while(chkbf());    
    RS=0;
    RW=0;
    E=0;
    delay_us(2);
    port=cmd;
    delay_us(2);
    E=1;
    delay_ms(2);
    E=0;
}
void main(){
    DDRC=0xff;
    PORTC=0x00;
    delay_ms(20);
    
    wrcmd(0b00111000);  // инициализация
    delay_ms(5);
    wrcmd(0b00001110);
    delay_us(40);
    //wrcmd(0b00000001);
    //delay_ms(2);
    wrcmd(0b00000110);
    delay_us(40);

        DDRD=0xff;    // пишу символ
        while(chkbf());
        RS=0;
        RW=1;
        E=0;
        delay_us(2);
        PORTD=0b1001010111;
        delay_us(2);
        E=1;
        delay_us(2);
        E=0;
        delay_us(50);
}
ILYAUL
Цитата
Изчезли темные квадраты!!!! и появился курсор в непонятном месте! УЖЕ
ЧТОТО!!!!

Ну и поставьте его на базу
failguru
в //пишу символ поставил RS=1 RW=0 ну как и должно быть, стал писать но вместо символа - черный квадрат
help.gif
ILYAUL
Цитата(failguru @ Nov 1 2011, 20:08) *
в //пишу символ поставил RS=1 RW=0 ну как и должно быть, стал писать но вместо символа - черный квадрат
help.gif


Код
DDRD=0xff;    // пишу символ
while(chkbf());
        RS=1;      
        RW=0;
        E=1;
PORTD=0x30;
        delay_us(2);
        E=0
       delay_us(2);
        E=1;
}


А так
failguru
тоже самое angry.gif
SortoVaritu
А какой символ вообще должен высветиться... Какой у контроллера знакогенератор?
У вас много лишних задержек. Зря закоментили проверку флага занятости в процедуре записи.
ILYAUL
Цитата(failguru @ Nov 1 2011, 20:53) *
тоже самое angry.gif

А тупую без while(chkbf());

Цитата(SortoVaritu @ Nov 1 2011, 21:05) *
А какой символ вообще должен высветиться... Какой у контроллера знакогенератор?
У вас много лишних задержек. Зря закоментили проверку флага занятости в процедуре записи.


30 в любом 0
И в его коде вообще ничего не пишется сразу 2 ошибки

Код
DDRD=0xff;    // пишу символ
        while(chkbf());
        RS=0;
        RW=1;
        E=0;
        delay_us(2);
        PORTD=0b1001010111;
        delay_us(2);
        E=1;
        delay_us(2);
        E=0;
        delay_us(50);
failguru
Да, заработало disco.gif . Я убрал while(chkbf()); из функции записи команд - лсд инициализировался. Убрал из вывода символа, тоже заработало. Странно, а что проверку занятости не надо делать, или я ее неправильно делаю wacko.gif
ILYAUL
Цитата(failguru @ Nov 1 2011, 21:15) *
Да, заработало disco.gif . Я убрал while(chkbf()); из функции записи команд - лсд инициализировался. Убрал из вывода символа, тоже заработало. Странно, а что проверку занятости не надо делать, или я ее неправильно делаю wacko.gif

Не правильно - читайте выложенный Вами же DS и уберите лишние задержки
SortoVaritu
В процедуре проверки флага думаю нужно инвертировать все E как и в основном коде по совету ILYAUL
failguru
Вот код
Код
#include <io.h>
#include <delay.h>
#define E PORTC.2
#define RS PORTC.0
#define RW PORTC.1
#define port PORTD
int chkbf(){    // проверка флага занятости
    DDRD=0x00;
    port=0xff;
    RS=0;
    RW=1;
    E=0;
    delay_us(2);
    E=1;
    delay_us(2);
    E=0;
    return(PIND.7);    
}
void wrcmd(int cmd){    // пишу команду
    DDRD=0xff;
    //while(chkbf());    
    RS=0;
    RW=0;
    E=0;
    delay_us(2);
    port=cmd;
    delay_us(2);
    E=1;
    delay_ms(2);
    E=0;
}
void wrsym(int sym){     // пишу символ
    DDRD=0xff;  
    //while(chkbf());
    RS=1;
    RW=0;
    E=1;
    port=sym;
    delay_us(2);
    E=0;
    delay_us(2);
    E=1;
}
void main(){
    DDRC=0xff;
    PORTC=0x00;
    delay_ms(20);
    
    wrcmd(0b00110000);  // инициализация
    delay_ms(5);
    wrcmd(0b00001110);
    delay_us(40);
    wrcmd(0b00000001);
    delay_ms(2);
    wrcmd(0b00000110);
    delay_us(40);
    wrsym(0x30);  //пишу символ
}
SortoVaritu
у вас в процедуре вывода символа

Код
    E=1;
    port=sym;
    delay_us(2);
    E=0;
    delay_us(2);
    E=1;


в процедуре проверки флага занятости

Код
    E=0;
    delay_us(2);
    E=1;
    delay_us(2);
    E=0;


Видите разницу?
failguru
загвоздка была в этом
Код
void wrcmd(int cmd){    // пишу команду
    [b]DDRD=0xff;
    while(chkbf());[/b]    
    RS=0;
    RW=0;

в проверке бизи флага я переключал порт на вход, а при записи команды переключение на выход было раньше проверки бизи флага)))))

вот причесал код, все работает!!!

Код
#include <io.h>
#include <delay.h>
#define E PORTC.2
#define RS PORTC.0
#define RW PORTC.1
#define port PORTD
int chkbf(){    // проверка флага занятости
    DDRD=0x00;
    port=0xff;
    RS=0;
    RW=1;
    E=1;
    delay_us(2);
    E=0;
    return(PIND.7);    
}
void wrcmd(int cmd){    // пишу команду
    while(chkbf());
    DDRD=0xff;    
    RS=0;
    RW=0;
    E=1;
    port=cmd;
    delay_us(2);
    E=0;
}
void wrsym(int sym){     // пишу символ  
    while(chkbf());
    DDRD=0xff;
    RS=1;
    RW=0;
    E=1;
    port=sym;
    delay_us(2);
    E=0;
}
void main(){
    DDRC=0xff;
    PORTC=0x00;
    delay_ms(20);
    
    wrcmd(0b00110000);  // инициализация
    delay_ms(5);
    wrcmd(0b00001110);
    delay_us(40);
    wrcmd(0b00000001);
    delay_ms(2);
    wrcmd(0b00000110);
    delay_us(40);
    wrsym(0x30);  //пишу символ
}


Спасибо, очень всем благодарен! Форум супер, первый раз тут a14.gif
ILYAUL
Код
DDRD=0xff;
это перенести в конец функции Busy в void wrcmd и void wrsym убрать
failguru
нет, так не катит. если перенести в конец функции бизи - то это не учитывается т.к. после ретурна осуществляется возврат, а перед ретурном не имеет смысла, т.к. мне нужно прочитать 7ой бит. вот так)
ILYAUL
Цитата(failguru @ Nov 2 2011, 00:02) *
нет, так не катит. если перенести в конец функции бизи - то это не учитывается т.к. после ретурна осуществляется возврат, а перед ретурном не имеет смысла, т.к. мне нужно прочитать 7ой бит. вот так)

Ах , ну да..
XVR
У вас в чтении bsy флага ошибка. Вот тут -
Код
    E=1;
    delay_us(2);
    E=0;
    return(PIND.7);
Вы должны прочесть PIND.7 до того, как сбросите E перед выходом из функции. У вас сейчас ваша функция читает бит 7 с уже отключенной шины LCD (и читает она оттуда всегда 1, т.к. в LCD шина притянута резисторами в 1)
SortoVaritu
tDH=300 ns. Может успеть прочитать))))))))))))))))))))
failguru
походу успевает, раз ноль читает с портд.7)))) частота кварца 8МГц, следовательно 125нс один такт, нормал. Либо нужно сделать паузу в 120нс после поднятия Е, если я правильно понимаю))))))))))))) а то не то может считать)))
SortoVaritu
E выставляешь в 1. делаешь задержку на время нужное для выставления контроллером жки данных(смотри по даташиту), читай данные, E сбрасывай в 1.
failguru
дк я и говорю в даташите максимум 120нс. с частотой кварца 8Мгц и > можно сделать как я, а так надо с задержкой в 120 нс припариться
XVR
Цитата(failguru @ Nov 3 2011, 00:33) *
дк я и говорю в даташите максимум 120нс.
Максимум - это не минимум. Т.е. 120нс вам никто не гарантирует. Вам гарантируют, что будет не более 120нс, т.е. вполне может быть и 0
Цитата
с частотой кварца 8Мгц и > можно сделать как я, а так надо с задержкой в 120 нс припариться
Если устойчивая работа не интересует, то конечно можно не парится smile3046.gif
failguru
Кто-нибудь знает, когда ставлю двухстрочный режим он ничего не показывает. При однострочном все нормал, только 1 и 3тью строку соответственно пишет, так по адресам и должно быть. Дальше если указать адрес второй строки или четвертой, то он там ничего не пишет, что скорее всего из-за однострочного режима. А как двустрочный сделать? help.gif
SortoVaritu
На практике будет работать как вы сделали, но вообще это неправильно....
Выставить E в 1, ждать 120 нс, читать выставленные контроллером ЖКИ данные.
В вашем случае если расширите программу и будете использовать прерывания, то есть вероятность сработки прерывания как раз после того как выставите E в 0, но до того как вы прочитаете шину данных. В этом случае вы точно не успеете считать данные.

Однострочный или двустрочный режим задается при инициализации...
failguru
Согласен полностью) но как задержку в 120нсек сделать???

Когда задаешь двустрочный, он ничего не отображает((((

Код
void main(){
    DDRC=0xff;
    PORTC=0x00;
    delay_ms(20);
    
    wrcmd(0b00111000);  // инициализация двустрочного режима
    delay_ms(2);
    wrcmd(0b00001110);
    delay_us(40);
    wrcmd(0b00000001);
    delay_ms(2);
    wrcmd(0b00000110);
    delay_us(40);
    wrcmd(0b11000000);  //переход на вторую строчку
    delay_us(2);
    
    for(i=0;i<10;i++)wrsym(48+i);
}
SortoVaritu
А вы напишите в первую строчку символов больше чем в нее помещается....
failguru
она переходит в третью как и должно быть по адресации в даташите, но дальше нет, нужно подрубать двустрочный режим, а он ничего не показывает((((
XVR
Цитата(failguru @ Nov 3 2011, 17:36) *
Согласен полностью) но как задержку в 120нсек сделать???
Вставить пару NOP'ов

ILYAUL
Цитата(XVR @ Nov 3 2011, 18:09) *
Вставить пару NOP'ов

Не надо NOP лучше так
Код
outr    LCD_PORT,temp;/ Выводим первый полубайт в порт
;+ И готовим второй , чтобы не ставить "тупые" NOP для задержки
swap    temp1
cbr    temp1,0x0F
cbr    temp,0xF0
cbi    LCD_Port,LCD_E;" Записываем данные в LCD
failguru
я в асме не очень, примерно понимаю но не все smile3046.gif

а проблема с двустрочным режимом была в том, что нужно было контраст увеличить(резистор меньше поставил(переменного нет)), тк хавать тока стал больше cool.gif
XVR
Цитата(failguru @ Nov 3 2011, 21:39) *
я в асме не очень, примерно понимаю но не все smile3046.gif
И не надо. Совет про NOP'ы относился к С (у WinAVR это _NOP() ).
В asm действительно можно вставить что нибудь более полезное rolleyes.gif

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.