Уже столько камней об него заточено что и писать нет смысла, однако есть какие то грабли при запуске, и я вот не пойму то ли это у него не так что то то ли я жутко торможу, надеюсь что первое.
Жутко принципиальный момент, по этому хочется его запустить.
Итак, 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() */
...
...
#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
Вопрос - Где же что не правильно?
Или есть такое что индикатор не поддерживает этот режим?
Так должен - даташит обещает...