failguru
Nov 1 2011, 14:09
простой код(выводит символ на 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
Nov 1 2011, 14:55
Контроллер SPLCD780D?
failguru
Nov 1 2011, 15:11
S6A0069 самсунговский помойму,
даташит даже нашел, прикрепляю
SortoVaritu
Nov 1 2011, 15:26
Код
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 - подробно расписан пример написания слова на дисплее
Цитата(SortoVaritu @ Nov 1 2011, 19:26)

Код
DDRD=0x00; - выставляете порт D как ...
ВХОД
SortoVaritu
Nov 1 2011, 15:33
Цитата(failguru @ Nov 1 2011, 18:11)

S6A0069 самсунговский помойму,
даташит даже нашел, прикрепляю
именно поэтому лучше писать не жки а контроллер, так как в данном случае от жки мало что зависит
DDRD=0x00; - выставляете порт D как вход... это я очепятался
failguru
Nov 1 2011, 15:55
да, спасибо, поставил в начало функции проверки бизи флага, но это не спасло(((((((((
Изчезли темные квадраты!!!! и появился курсор в непонятном месте! УЖЕ ЧТОТО!!!!
Вот код переделал:
Код
#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);
}
Цитата
Изчезли темные квадраты!!!! и появился курсор в непонятном месте! УЖЕ
ЧТОТО!!!!
Ну и поставьте его на базу
failguru
Nov 1 2011, 16:08
в //пишу символ поставил RS=1 RW=0 ну как и должно быть, стал писать но вместо символа -
черный квадрат
Цитата(failguru @ Nov 1 2011, 20:08)

в //пишу символ поставил RS=1 RW=0 ну как и должно быть, стал писать но вместо символа -
черный квадрат 
Код
DDRD=0xff; // пишу символ
while(chkbf());
RS=1;
RW=0;
E=1;
PORTD=0x30;
delay_us(2);
E=0
delay_us(2);
E=1;
}
А так
failguru
Nov 1 2011, 16:53
тоже самое
SortoVaritu
Nov 1 2011, 17:05
А какой символ вообще должен высветиться... Какой у контроллера знакогенератор?
У вас много лишних задержек. Зря закоментили проверку флага занятости в процедуре записи.
Цитата(failguru @ Nov 1 2011, 20:53)

тоже самое

А тупую без 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
Nov 1 2011, 17:15
Да, заработало

. Я убрал while(chkbf()); из функции записи команд - лсд инициализировался. Убрал из вывода символа, тоже заработало. Странно, а что проверку занятости не надо делать, или я ее неправильно делаю
Цитата(failguru @ Nov 1 2011, 21:15)

Да, заработало

. Я убрал while(chkbf()); из функции записи команд - лсд инициализировался. Убрал из вывода символа, тоже заработало. Странно, а что проверку занятости не надо делать, или я ее неправильно делаю

Не правильно - читайте выложенный Вами же DS и уберите лишние задержки
SortoVaritu
Nov 1 2011, 17:19
В процедуре проверки флага думаю нужно инвертировать все E как и в основном коде по совету ILYAUL
failguru
Nov 1 2011, 17:20
Вот кодКод
#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
Nov 1 2011, 17:27
у вас в процедуре вывода символа
Код
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
Nov 1 2011, 17:39
загвоздка была в этом
Код
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); //пишу символ
}
Спасибо, очень всем благодарен! Форум супер, первый раз тут
Код
DDRD=0xff;
это перенести в конец функции Busy в
void wrcmd и
void wrsym убрать
failguru
Nov 1 2011, 20:02
нет, так не катит. если перенести в конец функции бизи - то это не учитывается т.к. после ретурна осуществляется возврат, а перед ретурном не имеет смысла, т.к. мне нужно прочитать 7ой бит. вот так)
Цитата(failguru @ Nov 2 2011, 00:02)

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

дк я и говорю в даташите максимум 120нс.
Максимум - это не минимум. Т.е. 120нс вам никто не гарантирует. Вам гарантируют, что будет
не более 120нс, т.е. вполне может быть и 0
Цитата
с частотой кварца 8Мгц и > можно сделать как я, а так надо с задержкой в 120 нс припариться
Если устойчивая работа не интересует, то конечно можно не парится
failguru
Nov 3 2011, 13:16
Кто-нибудь знает, когда ставлю двухстрочный режим он ничего не показывает. При однострочном все нормал, только 1 и 3тью строку соответственно пишет, так по адресам и должно быть. Дальше если указать адрес второй строки или четвертой, то он там ничего не пишет, что скорее всего из-за однострочного режима. А как двустрочный сделать?
SortoVaritu
Nov 3 2011, 13:23
На практике будет работать как вы сделали, но вообще это неправильно....
Выставить E в 1, ждать 120 нс, читать выставленные контроллером ЖКИ данные.
В вашем случае если расширите программу и будете использовать прерывания, то есть вероятность сработки прерывания как раз после того как выставите E в 0, но до того как вы прочитаете шину данных. В этом случае вы точно не успеете считать данные.
Однострочный или двустрочный режим задается при инициализации...
failguru
Nov 3 2011, 13:36
Согласен полностью) но как задержку в 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
Nov 3 2011, 13:50
А вы напишите в первую строчку символов больше чем в нее помещается....
failguru
Nov 3 2011, 14:05
она переходит в третью как и должно быть по адресации в даташите, но дальше нет, нужно подрубать двустрочный режим, а он ничего не показывает((((
Цитата(failguru @ Nov 3 2011, 17:36)

Согласен полностью) но как задержку в 120нсек сделать???
Вставить пару NOP'ов
Цитата(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
Nov 3 2011, 17:39
я в асме не очень, примерно понимаю но не все

а проблема с двустрочным режимом была в том, что нужно было контраст увеличить(резистор меньше поставил(переменного нет)), тк хавать тока стал больше
Цитата(failguru @ Nov 3 2011, 21:39)

я в асме не очень, примерно понимаю но не все

И не надо. Совет про NOP'ы относился к С (у WinAVR это _NOP() ).
В asm действительно можно вставить что нибудь более полезное
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.