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

 
 
> Запуск LCD в 4-bit mode на AT91SAM7S
PrSt
сообщение Jan 30 2011, 21:40
Сообщение #1


http://uschema.com
****

Группа: Свой
Сообщений: 708
Регистрация: 16-02-06
Из: UK(Ukrainian_Kingdom) Kharkov
Пользователь №: 14 394



Запускаю на своем модуле ARM7MODA LCD индикатор из серии KS0066. Режим этот нужен, так что вопрос принципиальный.
Уже столько камней об него заточено что и писать нет смысла, однако есть какие то грабли при запуске, и я вот не пойму то ли это у него не так что то то ли я жутко торможу, надеюсь что первое.
Жутко принципиальный момент, по этому хочется его запустить.

Итак, 8bit mode - запустился на раз плюнуть, код я подставил свой старый, уже рабочий. Но был затык, и как оказалось, выяснил опытным путем, что индикатор мне попался жуткий тормозяра... каких я не встречал до этого.
Индикатор NEWTEC NC08082A. Ну то ладно, главное что нашел виновника, это - его медлительность.

Потом залез в его даташит, там приведены намного меньшие таймауты необходимые для работы... А по моему коду получается что нужно намного большие временные периоды между RS -> E -> Data.

А вот 4bit mode - напрочь не хочет заводиться. И вот тут у меня какой то шоковый ступор. Так как 4 бит я уже запускал несколько штук ранее. А на этом индикаторе - не получается.

В общем вот я вам и пишу, взгляните на код и скажите, это я где то торможу или для этого индикатора нужно что-то отличное от даташита...
На не оптимизированный код в 4bit mode не обращайте внимания, это я уже ради удобства выснения проблемы все перенес в один фрагмент

CODE
#define _RS _B8
#define _E _B9

#define LCD_TIME_FAST (10)
#define LCD_TIME_SLOW (50)
#define LCD_TIME LCD_TIME_SLOW
...
...
//-----------------------------------------------------------
void LCD_Config(void)
{

#ifdef LCD_4_BITS
AT91PS_SYS regs = AT91C_BASE_SYS;

tick(600*LCD_TIME); regs->PIOA_ODSR &=~_RS; // RS=0;
udelay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
udelay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
udelay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
delay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;

delay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0x20);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
udelay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0x80);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
delay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0x00);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
udelay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0x80);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
delay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0x00);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
udelay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0x10);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
delay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0x00);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
udelay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (0x30);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
delay();
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_RS; // RS=0;
#endif /*LCD_4_BITS*/


#ifdef LCD_8_BITS
unsigned char i=0, init_value[] = { 0x01, 0x02, 0x06, 0x0c, 0x14, 0x38 }; /* 16x2 */

for (i=0; i<sizeof(init_value); i++) {
lcd_cmd ( init_value[i] );
}
#endif /*LCD_8_BITS*/

} /* LCD_Config() */

//-----------------------------------------------------------
void lcd_cmd (unsigned char ch)
{
AT91PS_SYS regs = AT91C_BASE_SYS;

#ifdef LCD_4_BITS
udelay();
tick(600*LCD_TIME); regs->PIOA_ODSR &=~_RS;// RS=0;
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (ch&0xf0);
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
udelay();
tick(60*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(60*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |= (ch&0x0f)<<4;
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_RS; // RS=0;
#endif /*LCD_4_BITS*/

#ifdef LCD_8_BITS
tick(600*LCD_TIME); regs->PIOA_ODSR &=~_RS;// RS=0;
tick(6*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(6*LCD_TIME); regs->PIOA_ODSR &= 0xffffff00;
tick(6*LCD_TIME); regs->PIOA_ODSR |= ch;
tick(6*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
tick(6*LCD_TIME); regs->PIOA_ODSR &=~_RS; // RS=0;
#endif /*LCD_8_BITS*/
} /* lcd_cmd() */

//-----------------------------------------------------------
// Set address of first byte on desired row
void lcd_xy( unsigned char y, unsigned char x )
{
unsigned char LCD_ROW_ADDRESS[4] = { 0x00, 0x40, 0x14, 0x54 };
unsigned char AddrXYData;
AT91PS_SYS regs = AT91C_BASE_SYS;

AddrXYData = LCD_ROW_ADDRESS[y]+x;

#ifdef LCD_4_BITS
tick(60*LCD_TIME); regs->PIOA_ODSR &=~_RS; // RS=0;
tick(40*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(40*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |=0x80|(AddrXYData&0xF0);
tick(40*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
tick(40*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(40*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |=(AddrXYData&0x0F)<<4;
tick(40*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
#endif /*LCD_4_BITS*/

#ifdef LCD_8_BITS
tick(6*LCD_TIME); regs->PIOA_ODSR &=~_RS;// RS=0;
tick(4*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(4*LCD_TIME); regs->PIOA_ODSR &= 0xffffff00;
tick(1); regs->PIOA_ODSR |=(0x80|AddrXYData);
tick(4*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
#endif /*LCD_8_BITS*/
} /* lcd_xy() */

//-----------------------------------------------------------
/* Show message on LCD*/
void lcd_char( unsigned char value )
{
AT91PS_SYS regs = AT91C_BASE_SYS;
unsigned char kod;

kod = value;
kod = lcd_recode( value );

#ifdef LCD_4_BITS
tick(30*LCD_TIME); regs->PIOA_ODSR |=_RS; // RS=1;
tick(30*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(20*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |=((kod &0xF0));
tick(20*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
tick(30*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(20*LCD_TIME); regs->PIOA_ODSR &= 0xffffff0f;
tick(1); regs->PIOA_ODSR |=((kod &0x0F)<<4);
tick(20*LCD_TIME); regs->PIOA_ODSR &=~_E; // E=0;
#endif /*LCD_4_BITS*/

#ifdef LCD_8_BITS
tick(3*LCD_TIME); regs->PIOA_ODSR |=_RS; // RS=1;
tick(3*LCD_TIME); regs->PIOA_ODSR |=_E; // E=1;
tick(2*LCD_TIME); regs->PIOA_ODSR &= 0xffffff00;
tick(1); regs->PIOA_ODSR |= kod;
tick(2*LCD_TIME); regs->PIOA_ODSR &= ~_E; // E=0;
#endif /*LCD_8_BITS*/
} /* lcd_char() */

...
...


...тормознутость можете сами заметить по 60*LCD_TIME

Вопрос - Где же что не правильно?
Или есть такое что индикатор не поддерживает этот режим?
Так должен - даташит обещает...

Сообщение отредактировал IgorKossak - Jan 31 2011, 07:52
Причина редактирования: Пользуйтесь тэгами [codebox]


--------------------
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
rezident
сообщение Jan 30 2011, 21:49
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Боже ж мой! Да подключите вы PCF8575 к аппаратному I2C МК, а к ней в свою очередь этот ваш символьный LCD и используйте на здоровье любимый вами 8-ми битный режим вместо этого "ногодрыжества". Ногодрыжество на ARM это совершенно специальный вид секса с элементами грубого мазохизма wink.gif
Go to the top of the page
 
+Quote Post
izerg
сообщение Jan 31 2011, 07:53
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 531
Регистрация: 1-02-05
Из: Украина, Киев
Пользователь №: 2 342



Rezident, а чем ногодрыжество через PCF8575 в программе будет принципиально отличатся от простого ногодрыжества?
Да еще и в используемой плате, где стоит AT91SAM7S с его "фирменным" i2c.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- PrSt   Запуск LCD в 4-bit mode на AT91SAM7S   Jan 30 2011, 21:40
|- - rezident   Цитата(izerg @ Jan 31 2011, 12:53) Rezide...   Jan 31 2011, 12:08
|- - izerg   Цитата(rezident @ Jan 31 2011, 14:08) А ч...   Jan 31 2011, 13:45
- - aaarrr   Код, уж простите, просто чудовищный. И это еще сам...   Jan 30 2011, 22:00
|- - PrSt   Цитата(aaarrr @ Jan 31 2011, 00:00) Код, ...   Jan 31 2011, 21:36
|- - aaarrr   Цитата(PrSt @ Feb 1 2011, 00:36) да я зна...   Feb 1 2011, 18:46
- - IgorKossak   Тем более, что программа пишется один раз, ногами ...   Jan 31 2011, 07:56
- - Сергей Борщ   Да, читать такой код сложновато. Если правильно по...   Jan 31 2011, 09:32
- - RabidRabbit   Вот что у меня работает на SAM7S32 в четырёхбитной...   Feb 1 2011, 13:49
- - Genadi Zawidowski   Бросается в глаза, что в оригинальном проекте ниче...   Feb 2 2011, 21:08
|- - DmitryM   Цитата(Genadi Zawidowski @ Feb 3 2011, 00...   Feb 2 2011, 21:47
- - Genadi Zawidowski   ЦитатаВ ODSR можно писать при соответствующих наст...   Feb 2 2011, 22:52


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

 


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


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