Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATTINY2313 и ЖКИ 16х2
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
aerobus
Уважаемое сообщество гуру.
Прошу помочь разобраться.
Собсно проблемка.
Взял ЛСД с кнопочками в виде шиелда к дуньке.
А у него пин RW запаян на землю, то бишь чтение из ЛСД запрещено.
Устройство у меня довольно простенькое, посему Тиньки вполне достаточно.
Програмлю в CVAVR.
Родная библиотека компилятора умеет работать с ЛСД только с использованием пина ДСД RW.
Отсюда вопрос можно ли както "объяснить" библиотечке чтоб не использовать пин RW? Или его отрезать от "земли" прийдется.

Токо не кидайте сразу помидорами. В данном вопросе не больно силен.

Mareng
Прикрути свою библиотеку, благо этого добра в инете достаточно, да и заново написать недолго.
demiurg_spb
Цитата(aerobus @ Jan 18 2013, 14:58) *
Отсюда вопрос можно ли както "объяснить" библиотечке чтоб не использовать пин RW?
Библиотека в исходниках?
Если да, то дело нехитрое.
aerobus
Цитата(demiurg_spb @ Jan 18 2013, 15:15) *
Библиотека в исходниках?
Если да, то дело нехитрое.

Ну собсно вот библиотека.
Я правда в ней перевесил пин Enable на PB3, чтоб не запускать еще один таймер (мне в устройстве надо два канала ШИМ, вот я на один таймер их и повесил)
Зеленым я пометил то что поменял, красным то что мне мешает.
В Ассемблере вообще не силен, тем паче в МКшном.
Помогите ежели не сложно. Или ткните носом в подходящую библиотеку.

С уважением.
CODE
/* LCD driver routines

CodeVisionAVR C Compiler
© 1998-2008 Pavel Haiduc, HP InfoTech S.R.L.
*/

#asm
.equ __lcd_direction=__lcd_port-1
.equ __lcd_pin=__lcd_port-2
.equ __lcd_rs=0
.equ __lcd_rd=1
.equ __lcd_enable=3
.equ __lcd_busy_flag=7
#endasm

#pragma used+
static unsigned char _base_y[4]={0x80,0xc0};
unsigned char _lcd_x,_lcd_y,_lcd_maxx;
#pragma used-

static void _lcd_delay(void)
{
#asm
ldi r31,15
__lcd_delay0:
dec r31
brne __lcd_delay0
#endasm
}

void _lcd_ready(void)
{
#asm
in r26,__lcd_direction
andi r26,0xf ;set as input
out __lcd_direction,r26
sbi __lcd_port,__lcd_rd ;RD=1
cbi __lcd_port,__lcd_rs ;RS=0
__lcd_busy:
#endasm
_lcd_delay();
#asm
sbi __lcd_port,__lcd_enable;EN=1
#endasm
_lcd_delay();
#asm
in r26,__lcd_pin
cbi __lcd_port,__lcd_enable;EN=0
#endasm
_lcd_delay();
#asm
sbi __lcd_port,__lcd_enable;EN=1
#endasm
_lcd_delay();
#asm
cbi __lcd_port,__lcd_enable;EN=0
sbrc r26,__lcd_busy_flag
rjmp __lcd_busy
#endasm
}

static void _lcd_write_nibble(void)
{
#asm
andi r26,0xf0
or r26,r27
out __lcd_port,r26 ;write
sbi __lcd_port,__lcd_enable;EN=1
#endasm
_lcd_delay();
#asm
cbi __lcd_port,__lcd_enable;EN=0
#endasm
_lcd_delay();
}

void _lcd_write_data(unsigned char data)
{
#asm
cbi __lcd_port,__lcd_rd ;RD=0
in r26,__lcd_direction
ori r26,0xf0 | (1<<__lcd_rs) | (1<<__lcd_rd) | (1<<__lcd_enable);set as output
out __lcd_direction,r26
in r27,__lcd_port
andi r27,0xf
ld r26,y
#endasm
_lcd_write_nibble(); //RD=0, write MSN
#asm
ld r26,y
swap r26
#endasm
_lcd_write_nibble(); //write LSN
#asm
sbi __lcd_port,__lcd_rd ;RD=1
#endasm
}

/* write a byte to the LCD character generator or display RAM */
void lcd_write_byte(unsigned char addr, unsigned char data)
{
_lcd_ready();
_lcd_write_data(addr);
_lcd_ready();
#asm
sbi __lcd_port,__lcd_rs ;RS=1
#endasm
_lcd_write_data(data);
}

static void _lcd_read_nibble(void)
{
#asm
sbi __lcd_port,__lcd_enable;EN=1
#endasm
_lcd_delay();
#asm
in r30,__lcd_pin ;read
cbi __lcd_port,__lcd_enable;EN=0
#endasm
_lcd_delay();
#asm
andi r30,0xf0
#endasm
}

static unsigned char lcd_read_byte0(void)
{
_lcd_delay();
_lcd_read_nibble(); // read MSN
#asm
mov r26,r30
#endasm
_lcd_read_nibble(); // read LSN
#asm
cbi __lcd_port,__lcd_rd ;RD=0
swap r30
or r30,r26
#endasm
}

/* read a byte from the LCD character generator or display RAM */
unsigned char lcd_read_byte(unsigned char addr)
{
_lcd_ready();
_lcd_write_data(addr);
_lcd_ready();
#asm
in r26,__lcd_direction
andi r26,0xf ;set as input
out __lcd_direction,r26
sbi __lcd_port,__lcd_rs ;RS=1
#endasm
return lcd_read_byte0();
}

/* set the LCD display position x=0..39 y=0..3 */
void lcd_gotoxy(unsigned char x, unsigned char y)
{
_lcd_ready(); // RS=0
_lcd_write_data(_base_y[y]+x);
_lcd_x=x;
_lcd_y=y;
}

// clear the LCD
void lcd_clear(void)
{
_lcd_ready(); // RS=0
_lcd_write_data(2); // cursor home
_lcd_ready();
_lcd_write_data(0xc); // cursor off
_lcd_ready();
_lcd_write_data(1); // clear
_lcd_x=_lcd_y=0;
}

void lcd_putchar(char c)
{
#asm
push r30
push r31
ld r26,y
set
cpi r26,10
breq __lcd_putchar1
clt
#endasm
if (_lcd_x>=_lcd_maxx)
{
#asm("__lcd_putchar1:")
++_lcd_y;
lcd_gotoxy(0,_lcd_y);
#asm("brts __lcd_putchar0")
};
++_lcd_x;
#asm
rcall __lcd_ready
sbi __lcd_port,__lcd_rs;RS=1
ld r26,y
st -y,r26
rcall __lcd_write_data
__lcd_putchar0:
pop r31
pop r30
#endasm
}

// write the string str located in SRAM to the LCD
void lcd_puts(char *str)
{
char k;
while (k=*str++) lcd_putchar(k);
}

// write the string str located in FLASH to the LCD
void lcd_putsf(char flash *str)
{
char k;
while (k=*str++) lcd_putchar(k);
}

static void _long_delay(void)
{
#asm
clr r26
clr r27
__long_delay0:
sbiw r26,1 ;2 cycles
brne __long_delay0;2 cycles
#endasm
}

static void _lcd_init_write(unsigned char data)
{
#asm
cbi __lcd_port,__lcd_rd ;RD=0
in r26,__lcd_direction
ori r26,0xf7 ;set as output
out __lcd_direction,r26
in r27,__lcd_port
andi r27,0xf
ld r26,y
#endasm
_lcd_write_nibble(); //RD=0, write MSN
#asm
sbi __lcd_port,__lcd_rd ;RD=1
#endasm
}

// initialize the LCD controller
unsigned char lcd_init(unsigned char lcd_columns)
{
#asm
cbi __lcd_port,__lcd_enable;EN=0
cbi __lcd_port,__lcd_rs ;RS=0
#endasm
_lcd_maxx=lcd_columns;
_base_y[2]=lcd_columns+0x80;
_base_y[3]=lcd_columns+0xc0;
_long_delay();
_lcd_init_write(0x30);
_long_delay();
_lcd_init_write(0x30);
_long_delay();
_lcd_init_write(0x30);
_long_delay();
_lcd_init_write(0x20);
_long_delay();
_lcd_write_data(0x28);
_long_delay();
_lcd_write_data(4);
_long_delay();
_lcd_write_data(0x85);
_long_delay();
#asm
in r26,__lcd_direction
andi r26,0xf ;set as input
out __lcd_direction,r26
sbi __lcd_port,__lcd_rd ;RD=1
#endasm
if (lcd_read_byte0()!=5) return 0;
_lcd_ready();
_lcd_write_data(6);
lcd_clear();
return 1;
}

void lcd_control (unsigned char control)
{
_lcd_ready();
_lcd_write_data(control);
}
demiurg_spb
"Отличная" говнолиба с привязкой к такому-же говнокомпилятору...

По сути:
Ищите все вхождения интересующей вас ножки в тексте либы например __lcd_rd.
Такие строки удаляйте полностью (или заменяйте их на nop, чтобы не порушить времянку):
Код
        sbi __lcd_port,__lcd_rd
        cbi __lcd_port,__lcd_rd

а такие (могут и отличаться)
Код
        ori r26,0xf0 | (1<<__lcd_rs) | (1<<__lcd_rd) | (1<<__lcd_enable)

правьте примерно до такого состояния:
Код
        ori r26,0xf0 | (1<<__lcd_rs)  | (1<<__lcd_enable)
aerobus
Цитата(demiurg_spb @ Jan 18 2013, 16:37) *
"Отличная" говнолиба с привязкой к такому-же говнокомпилятору...

По сути:
Ищите все вхождения интересующей вас ножки в тексте либы например __lcd_rd.
Такие строки удаляйте полностью (или заменяйте их на nop, чтобы не порушить времянку):
Код
        sbi __lcd_port,__lcd_rd
        cbi __lcd_port,__lcd_rd

а такие (могут и отличаться)
Код
        ori r26,0xf0 | (1<<__lcd_rs) | (1<<__lcd_rd) | (1<<__lcd_enable)

правьте примерно до такого состояния:
Код
        ori r26,0xf0 | (1<<__lcd_rs)  | (1<<__lcd_enable)

Спасибо. Буду пробовать. Ежели что ешшо задам глупых вопросов. Уж не обессудьте. 05.gif
Ну и подскажите тогда, чем лучше пользоваться из компилеров и либов. wacko.gif
demiurg_spb
winavr или avr-studio + avr-gcc.
aerobus
Цитата(aerobus @ Jan 18 2013, 17:38) *
Ежели что ешшо задам глупых вопросов.

Ну в общем прибил все обращения к __lcd_rd ... Не помогло. sad.gif
Теперь после инициализации экрана на пине энабле идет "моргание" 0,1,0,1.....
Т.е. этими средствами похоже проблемку не решить.
Не хочется рисовать кусок проги своей, то бишь свою либу... Думал обойтись на скорую руку готовыми решениями. И готовой библиотечкой.
Ну видимо ума хватит только на написание своего "говнокода" sm.gif заместо стандартной либы. Прийдется изучать даташит на ЛСД sm.gif


aerobus
Цитата(demiurg_spb @ Jan 18 2013, 17:59) *
avr-gcc.

Кстати, а иде сей компилер можно взять? Или он платный?
Genadi Zawidowski
Цитата(aerobus @ Jan 18 2013, 22:32) *
Кстати, а иде сей компилер можно взять? Или он платный?


Бесплатный.
Atmel AVR 8-bit and 32-bit Toolchain 3.4.0 - Windows
http://www.atmel.com/Images/avr-toolchain-...2.win32.x86.exe

Среда разработки - AVR Studio 4.19 (build 730) - тоже бесплатная:
http://www.atmel.com/Images/AvrStudio4Setup.exe

В Вашем случае этого будет достаточно.
aerobus
Цитата(Genadi Zawidowski @ Jan 18 2013, 23:21) *
Бесплатный.
Atmel AVR 8-bit and 32-bit Toolchain 3.4.0 - Windows
http://www.atmel.com/Images/avr-toolchain-...2.win32.x86.exe

Среда разработки - AVR Studio 4.19 (build 730) - тоже бесплатная:
http://www.atmel.com/Images/AvrStudio4Setup.exe

В Вашем случае этого будет достаточно.

Пасиб. Я пользовал CVAVR и 5 Visual. Вроде усе работало. Скачал и поставил последнюю 6-ю студию она не узнается CVAVR.
Ну да собсно проблема не велика. У мну проекты с МК возникают раз в полтора года. И оне все "домашние". Попробую неспешно разобраться.
Спасибо всем потратившим время на мои делитанские проблемы. Снимаю шляпу.
С уважением.
hd44780
aeribus, ловите мою самодельную либу под CvAVR.
LCD_RW там задекларирован, но реально не используется. В схеме заведен в землю, как и у Вас.
Инициализировать ноги надо где-то извне, все на выход. Либа эти не занимается.

Режим дисплея - 8-битный, имхо 4-битный - говнорежим, также как для некоторых CvAVR - "говнокомпилятор".

В качестве "плюсов" - после минимальной доработки работает и на дисплеях 20x4, если это актуально.
ILYAUL
Цитата
имхо 4-битный - говнорежим
Вы просто не умеете его готовить
Цитата
Родная библиотека компилятора умеет работать с ЛСД только с использованием пина ДСД RW.

Вообще хрень какая-то , ну не умеет и ладно , не подключай пин к LCD и программе хорошо и дисплею по....

А на 2313 с дисплеем надо работать вооще на 2 проводах. Хоть порты сохраните для дела
aerobus
Цитата(hd44780 @ Jan 20 2013, 18:19) *
aeribus, ловите мою самодельную либу под CvAVR.
...
Режим дисплея - 8-битный, имхо 4-битный - говнорежим, также как для некоторых CvAVR - "говнокомпилятор".

Спасибо!
Токо 8-битный забирает порты, мне тогда не хватает. sad.gif

2 ILYAUL
Ежели пин RW ставлю в землю, то на пине Enable идут осциляции и ничо не запускается.

Тут еще проблемка вылезла.
Кнопочки на шилде запаяны под разбор АЦП. А у Тиньки его нету.
Вот думаю компаратор присобачить под АЦП, только тогда прийдется растягивать управление ЖКИ на два порта, потому как нужны два канала ШИМ от таймера 0 и две ноги компаратора из порта В прийдется забрать под АЦП.
В общем буду колхозить свои процедуры инициализации и отображения. sad.gif
ILYAUL
Какой
Цитата
пин RW ставлю в землю
? Где?
Всё что скрыто под этим убрать
Цитата
/* read a byte from the LCD character generator or display RAM */
unsigned char lcd_read_byte(unsigned char addr) и
static unsigned char lcd_read_byte0(void)

вот сюда
static void _lcd_delay(void) - только задержку согласно DS на Ваш дисплей
aerobus
Цитата(ILYAUL @ Jan 20 2013, 23:17) *
Какой ? Где?
Всё что скрыто под этим убрать

вот сюда
static void _lcd_delay(void) - только задержку согласно DS на Ваш дисплей

Не въехал. sad.gif
Что под чем скрыто и куды его убрать?

Ну вот такая схемка пока.
Нажмите для просмотра прикрепленного файла

Т.е. ЖКИ сидит на порту В
Кнопки на D
Ежели забрать компаратор, то пины освободятся на D а управление экраном надо буит осуществлять из двух портов.
RS, RW, E повесить на порт D
а данные гнать через порт B.

Может конечно єто все не сильно грамотно, с точки зрения профи, ну да я и не претендую. Это так, для дома для себя изредка заглядываю в МК.
laughing.gif
Ну а сие кусок говнокода который это должон оживлять.

CODE
#include <tiny2313.h>
#include <string.h>
#include <delay.h>
#include <lcd.h>


#asm
.equ __lcd_port=0x18 ;PORTB //Подключаем дисплей к порту B
#endasm

int c;
unsigned char numdigchar(int x)
{
unsigned char temp;
if ((x>=1000)||(x<=-1000)) return 1;
if (x<0) {
lcd_putchar('-');
x=-x;
}

temp=x/1000; //вычисляем тысячи
lcd_putchar(0x30+temp); //выводим на ЖКИ
x=x-temp*1000; //вычитаем тысячи

temp=x/100; //вычисляем сотни
lcd_putchar(0x30+temp); //выводим
x=x-temp*100; //вычитаем сотни

temp=x/10; //вычисляем десятки
lcd_putchar(0x30+temp); //выводим
x=x-temp*10; //вычитаем десятки

temp=x/1; //вычисляем единицы
lcd_putchar(0x30+temp); //выводим
x=x-temp; //вычитаем единицы

return 0;

}
//Главная функция программы
void main(void)
{
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTB=0x00;
DDRB=0xDF;

PORTD=0x00;
DDRD=0x20;

TCNT0=0xFF;
TCCR0A=0xF3;
TCCR0B=0x01;


OCR0B=0x05;
OCR0A=0xF0;

//Инициализируем дисплей
lcd_init(16);


#asm("cli")
c=5;


lcd_clear(); //функция очистки дисплея

while(1){
delay_ms(1000); //задержка 1 секунда
if (PIND.6==0) {
if (OCR0A<0xFF)
OCR0A++;
}
if (PIND.2==0) {
if (OCR0A>0)
OCR0A--;
}
if (PIND.4==0) {
if (OCR0B<0xFF)
OCR0B++;
}
if (PIND.1==0) {
if (OCR0B>0)
OCR0B--;
}
lcd_gotoxy(7,0);
numdigchar(OCR0A);
lcd_gotoxy(7,1);
numdigchar(OCR0B);


}
}

Т.е. Гдето так.
Приношу извинения, не умею код засовывать в отдельный блок. Может подскажете как?
hd44780
Цитата(ILYAUL @ Jan 20 2013, 17:07) *
Вы просто не умеете его готовить


Пожалуйста не говорите того, чего не знаете. Схема одна и та же, прошивка одна и та же. Меняю только дисплеи, как перчатки - один работает, другой - нет. Такую картину наблюдал и на CvAVR-овской либе, и на avrlib под winAVR. И вне зависимости от RW и чего либо ещё.

И на других форумах другие люди говорят то же самое.

И у меня лично есть 2 дисплея, прекрасно работающие по 4-бит, и 3 дисплея (2 из них 20x4), которые не работают. Может шаманить надо и подгонять - не знаю. Хотя, если это схема под один экземпляр дисплея и лично для себя, то можно и с 4-бит помучиться.

aerobus, вообще дисплей не микросхема в противно-мелком SMD корпусе, можно одну ногу перепаять.
aerobus
Цитата(hd44780 @ Jan 21 2013, 11:26) *
aerobus, вообще дисплей не микросхема в противно-мелком SMD корпусе, можно одну ногу перепаять.

Угу. Ежели б не шилд, то и резюки б с кнопок выпаял, а оне(резюки) под ЖКИ. И нога к земле прикручена...
ILYAUL
Цитата
Такую картину наблюдал и на CvAVR-овской либе, и на avrlib под winAVR. И вне зависимости от RW и чего либо ещё.
Мможет в выше перечисленном что-то поменять.
Поработайте с дисплеями по сигналу готовности , глядишь и рабочие окажутся.

aerobus
Проверяйте , может я что-то и упустил, но направление Вам задал.
aerobus
Цитата(ILYAUL @ Jan 21 2013, 13:55) *
Поработайте с дисплеями по сигналу готовности , глядишь и рабочие окажутся.

aerobus
Проверяйте , может я что-то и упустил, но направление Вам задал.

Пасиб. rolleyes.gif
Я именно с этого примера и начинал.
Тут как раз и прикручена нога RW к библиотеке Т.е. работа по готовности.
Ну да в прочем ежели отпаять таки ногу от "земли", то вроде как все должно работать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.