|
LPC2478 + TFT 320x240 совсем рябит (, вместе с курсором.. |
|
|
|
Apr 5 2010, 03:29
|
Участник

Группа: Свой
Сообщений: 73
Регистрация: 17-10-07
Из: Киев
Пользователь №: 31 422

|
Частота клока 6,5 МГц (По ДШ рекоммендуют 6,75). С чем может быть связано рябение (я так понимаю постоянно прорисовываются то четные- то нечетные строки)?. Рябит вместе с курсором. Картинка изначально была сдвинута влево вверх, чтоб стала посредине, значительно увеличил Vertical front porch и horizontal front porch(от значений, рекоммендуемых ДШ на ТФТ). При некоторых стечениях обстоятельств)) (положение курсора, данные тестовой картинки) ТФТ вообще отказывается что-либо показывать... (Белый фон, как до инициализации). Смотрел сигналы осциллографом - форма верт. и гор синхронизаций нормальная, синхр. данных (DCLK) - почти синус. Это нормально? Еще интересная особенность - значения LCD_POL(IPC Invert panel clock., IHS Invert horizontal synchronization., IVS Invert vertical synchronization.) в в нескольких комбинациях на картинку не влияют. Подскажите плз в какую вообще сторону думать? ) На всякий случай код с парой тестов и картинку с ДШ ТФТ прилагаю. Код #define LCD_RES_H 320 #define LCD_RES_V 240 #define LCD_BUF_SIZE (LCD_RES_H*LCD_RES_V*2)
unsigned char VideoBuf[LCD_BUF_SIZE] __attribute__((at(NOR_FLASH_BASE))); //SDRAM
void InitLCD() { int i, testnum = 0; int k=0; unsigned short *Pall = (unsigned short *)&LCD_PAL; unsigned short *Vbuf = (unsigned short *)&VideoBuf; unsigned short *Curs = (unsigned short *)&CRSR_IMG; PCONP|= (1<<20); //LCD
PINSEL11 = (6<<1)|(1<<0);// bit0=1 - LCD port is enabled. bit1...3 = 110 TFT 16-bit. (1:5:5:5 mode) LCD_CFG = 10;//72 MHz div 11 //1 // LCD_TIMH = (((42-1)<<24) | ((67-1)<<16) | ((11-1)<<8) | (((LCD_RES_H/16)-1)<<2)); // LCD_TIMV = ((6<<24) | (16<<16) | ((3-1)<<10) | (LCD_RES_V-1)); //2 //LCD_TIMH = (((31-1)<<24) | ((67-1)<<16) | ((11-1)<<8) | (((LCD_RES_H/16)-1)<<2)); //LCD_TIMV = ((3<<24) | (16<<16) | ((3-1)<<10) | (LCD_RES_V-1)); //kartinka posredine LCD_TIMH = (((61-1)<<24) | ((67-1)<<16) | ((11-1)<<8) | (((LCD_RES_H/16)-1)<<2)); LCD_TIMV = ((33<<24) | (16<<16) | ((3-1)<<10) | (LCD_RES_V-1));
LCD_POL = ((0<<27) | (1<<26) | (((LCD_RES_H/1)-1)<<16) | (0<<14) | (1<<13)| (1<<12) | (1<<11)| (0<<6) | (0<<5) | (2<<0));
LCD_CTRL = ((0<<10) | (0<<9) | (0<<8) | (1<<5) | (4<<1)); // 100 = 16 bpp, 1:5:5:5 mode.
for(i=0; i<256; i++) Curs[i] = 0xFFFF;
CRSR_CFG = 0; CRSR_XY = (110<<16)|(160<<0); CRSR_CTRL = 1;//Cursor on
LCD_UPBASE = (unsigned long)VideoBuf; LCD_LPBASE = (unsigned long)VideoBuf; for(i=0; i<256; i++)//test { Pall[i] = 0xFF00+i; } LCD_CTRL |= 1;//Enable LCD_CTRL |= 1<<11;//PWR ON
testnum = 3; while(1) { switch(testnum) { case 0://bleklie tsveta for(i=0; i<(LCD_BUF_SIZE/2); i++) if(i < (LCD_BUF_SIZE/4)) Vbuf[i]= (32<<10)|(0<<5)|(0<<0); else Vbuf[i]= (0<<10)|(0<<5)|(32<<0); testnum = -1; break; case 1://ne vivodit - vse beloe for(i=0; i<(LCD_BUF_SIZE/2); i++) if(i < (LCD_BUF_SIZE/4)) Vbuf[i]= 0; else Vbuf[i]= 0xFFFF; testnum = -1; break; case 2://sverhu beloe, vnizu-4ernoe for(i=0; i<(LCD_BUF_SIZE/2); i++) if(i < (LCD_BUF_SIZE/4)) Vbuf[i]= 0xFFFF; else Vbuf[i]= 0; testnum = -1; break; case 3://poloski for(i=0; i<(LCD_BUF_SIZE/2); i++) { if((i % (320*20)) == 0) k = rand(); Vbuf[i]= k; } testnum = -1; break; case 4://random for(i=0; i<(LCD_BUF_SIZE/2); i++) Vbuf[i]= rand() & 0xFFFF; testnum = -1; break;
default: break; } }
}
|
|
|
|
2 страниц
< 1 2
|
 |
Ответов
(15 - 28)
|
Apr 6 2010, 15:52
|
Участник

Группа: Участник
Сообщений: 25
Регистрация: 10-11-09
Пользователь №: 53 547

|
а земля точно хорошая к дисплею идет?
|
|
|
|
|
Apr 6 2010, 17:07
|
Участник

Группа: Свой
Сообщений: 73
Регистрация: 17-10-07
Из: Киев
Пользователь №: 31 422

|
Цитата(Dog Pawlowa @ Apr 6 2010, 18:41)  Вы бы по мусоркам покопались и нашли "человеческий" TFT, ага? Да этот во 2-м режиме тоже может быть "человеческий", в крайнем случае его и буду пробовать, но хотел по СПИ менять яркость\контраст.. Цитата(scorp1969 @ Apr 6 2010, 18:22)  видео буфер выровнен по границе 8? а RGB выводы правильные используются в режиме 555 out of 888? и вообще, у вас видео буфер как char pазмером 2х320х240 при этом режим 555 один пиксел это 16бит но ни как не char выровнян(0х80000000). вроде да)) (старшие к старшим ТФТ, младшие ТФТ на землю.) в любом случае были бы искаженные цвета, но на развертку это бы врядли повлияло.. это просто буфер так задан, заполняется он через short* . А сейчас вообще в 8бит (палитру) переделал, от этого суть не меняется.. Присмотрелся внимательней на медленной развертке - ВСЕ кадры выводятся черезстрочно, сначала четные, потом - нечетные или наоборот)..Те что "не выводятся"- - белые.. Это я так понимаю контроллер в ТФТ так их выдает? Или все-таки МК?
|
|
|
|
|
Apr 16 2010, 15:13
|
Участник

Группа: Свой
Сообщений: 73
Регистрация: 17-10-07
Из: Киев
Пользователь №: 31 422

|
Заработало! =)) Все-таки надо было более тщательно подойти к настройке VCOM... +увеличил частоту в 1.5 раза от рекоммендуемой, убрал яркости, увеличил контраст - черный стал похож на черный) Но пиксели сбоку курсора все еще пробегают.. Как с правильной полярностью клока, так и с неправильной (с неправильной больше). А вообще обычно ставят согласующие резисторы на видео-интерфейсы? Посмотреть форму DCLK пока нечем..
|
|
|
|
|
Mar 17 2011, 12:06
|
Местный
  
Группа: Свой
Сообщений: 231
Регистрация: 7-12-06
Из: Киев
Пользователь №: 23 248

|
Цитата(overloaded @ Mar 16 2011, 19:06)  Не прошло и года =) В общем фон стал окончательно черным после того как нашел ошибку в схемотехнике подключения экрана (было неправильное напряжение для общего электрода TFT) а что такое "напряжение для общего электрода TFT"?
|
|
|
|
|
Mar 20 2011, 20:19
|
Участник

Группа: Свой
Сообщений: 73
Регистрация: 17-10-07
Из: Киев
Пользователь №: 31 422

|
Это COMMON ELECTRODE CENTER VOLTAGE. Т.е. средняя точка, относительно которой подается то прямая то обратная полярность на ТФТ транзисторы (чтоб не было берн-ина т.е. "вжегшейся" картинки). Есть разные схемы организации экранов, в этом одна полярность подавалась на четные, другая на нечетные строки, на следующем кадре - наоборот. Т.к. напряжение было неправильным, строки (через одну) были серого цвета вместо черного, чередуясь через каждый кадр давали серый фон и рябь.
|
|
|
|
|
Apr 5 2011, 09:11
|

Частый гость
 
Группа: Свой
Сообщений: 158
Регистрация: 15-10-07
Из: Й-Ола
Пользователь №: 31 376

|
Цитата(Prinz @ Apr 4 2011, 09:09)  // 0 = divide by 1 LCD_CFG = 0x0; И после этого дисплей все еще работает, максимальная частота вашего дисплея вряд-ли может быть более 25МГц, а тут превышение в три раза. Приведите всю инициализацию дисплея.
|
|
|
|
|
Apr 5 2011, 10:14
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(M_Andrey @ Apr 5 2011, 15:11)  И после этого дисплей все еще работает, максимальная частота вашего дисплея вряд-ли может быть более 25МГц, а тут превышение в три раза. Приведите всю инициализацию дисплея. Уточнение. Где-то значит что-то ещё делиться, так как DOTCLK = 4 MHz с хвостиком. Осцилографом натыкал. Вроде ка бы обновление порядочное. Шина паралельная 18 бит. И вот что я хаметил, если с SD грузить однородная картинка, то всё норма. Нарисовал пару квадратиков на ней, мерцание заметно только на одном, который такого тёмно-зелёного цвета. Я вот сейчас вообще в шоке. Всё нормально кроме одного маленького квадратика. В чём может быть ароблема??? CODE #define NULL 0 #define MUL 72/8 #define ACTIVATE_CS FIO0CLR = 0x10000 #define DEACTIVATE_CS FIO0SET = 0x10000 #define SET_RS FIO0SET = 0x80000 #define RESET_RS FIO0CLR = 0x80000 pInt32U a; extern void delay(int cnt); unsigned long buf[4]={0x56FF,0x7447,8098,87};
spiSend(BYTE data) { unsigned int failsafe;
S0SPDR = data; failsafe = 0; while(((S0SPSR & 0x80) == 0) && (failsafe < 5000)) failsafe++;
if(failsafe >= 5000) { S0SPCCR = 8; S0SPCR = 0x38; } }
void writeToReg(WORD addr, WORD data) { RESET_RS; ACTIVATE_CS; spiSend(0); spiSend(addr & 0xff); DEACTIVATE_CS;
SET_RS; ACTIVATE_CS; spiSend(data >> 8); spiSend(data & 0xff); DEACTIVATE_CS;
RESET_RS; ACTIVATE_CS; spiSend(0); spiSend(0x22); DEACTIVATE_CS; }
void lcd_hw_init(void) { //Turn on power to LCD FIO2DIR |= 0x1; FIO2SET = 0x1; //set P1.18 as PWM output (PWM1.1, second alternative function) PINSEL3 &= 0xFFFFFFCF; PINSEL3 |= 0x00000020; PWM1PR = 0x00; //no prescaling PWM1MCR = 0x02; //reset counter if MR0 match PWM1MR0 = 0x3000; //period time equal about 5 ms PWM1MR1 = 0x1000; PWM1LER = 0x03; //latch MR0 and MR1 PWM1PCR = 0x0200; //enable PWMENA1 PWM1TCR = 0x09; //enable counter and PWM FIO0DIR |= 0x90000; FIO0SET = 0x90000; PINSEL10 = 0; PINSEL0 = (PINSEL0 & 0xFFF000FF) | 0x00055500; PINSEL3 = (PINSEL3 & 0xF00000FF) | 0x05555500; PINSEL4 = (PINSEL4 & 0xF0300000) | 0x054FFFFF; PINSEL9 = (PINSEL9 & 0xF0FFFFFF) | 0x0A000000; PINSEL11 = 0x0000000d; }
void lcd_display_init(void) { writeToReg (0x00,0x0001); delay(20000); writeToReg (0x03,0xA2A4); writeToReg (0x0C,0x0004); writeToReg (0x0D,0x0308); writeToReg (0x0E,0x3000); delay(50000); writeToReg (0x1E,0x00AF); writeToReg (0x01,0x2B3F); writeToReg (0x02,0x0600); writeToReg (0x10,0x0000); writeToReg (0x07,0x0233); writeToReg (0x0B,0x0039); writeToReg (0x0F,0x0000); delay(50000); writeToReg (0x30,0x0707); writeToReg (0x31,0x0204); writeToReg (0x32,0x0204); writeToReg (0x33,0x0502); writeToReg (0x34,0x0507); writeToReg (0x35,0x0204); writeToReg (0x36,0x0204); writeToReg (0x37,0x0502); writeToReg (0x3A,0x0302); writeToReg (0x3B,0x0302); writeToReg (0x23,0x0000); writeToReg (0x24,0x0000); writeToReg (0x48,0x0000); writeToReg (0x49,0x013F); writeToReg (0x4A,0x0000); writeToReg (0x4B,0x0000); writeToReg (0x41,0x0000); writeToReg (0x42,0x0000); writeToReg (0x44,0xEF00); writeToReg (0x45,0x0000); writeToReg (0x46,0x013F); delay(50000); writeToReg (0x44,0xEF00); writeToReg (0x45,0x0000); writeToReg (0x4E,0x0000); writeToReg (0x4F,0x0000); writeToReg (0x46,0x013F); }
void lcd_ctrl_init(tLcdParams* pParams) { DWORD regValue = 0; // disable the display LCD_CTRL &= ~LCD_CTRL_REG_EN; // ppl value to set = ppl / 16 -1 (2:7) // hsw value to set = hsw - 1 (8:15) // hfp value to set = hfp - 1 (16:23) // hbp value to set = hbp - 1 (24:31) regValue= ( ((((pParams->ppl/16)-1)&0x3F) << 2) | (( (pParams->hsw-1) &0xFF) << 8) | (( (pParams->hfp-1) &0xFF) << 16) | (( (pParams->hbp-1) &0xFF) << 24) ); LCD_TIMH = regValue; regValue =((((pParams->lpp-1) &0x3FF) << 0) | (((pParams->vsw-1) &0x03F) << 10) | (((pParams->vfp-1) &0x0FF) << 16) | (((pParams->vbp-1) &0x0FF) << 24) ); LCD_TIMV = regValue; regValue = 0; if(pParams->acb != 0) { regValue = (((pParams->acb-1) & 0x1F) << 6); } if(pParams->ioe != 0) { regValue |= LCD_POL_REG_IOE; } if(pParams->ipc != 0) { regValue |= LCD_POL_REG_IPC; } if(pParams->ihs != 0) { regValue |= LCD_POL_REG_IHS; } if(pParams->ivs != 0) { regValue |= LCD_POL_REG_IVS; } // clocks per line (CPL) switch(pParams->panelType) { case LCD_MONO_4: regValue |= ((((pParams->ppl / 4)-1) & 0x3FF) << 16); break; case LCD_MONO_8: regValue |= ((((pParams->ppl / 8)-1) & 0x3FF) << 16); break; case LCD_CSTN: regValue |= (((((pParams->ppl * 3)/8)-1) & 0x3FF) << 16); break; case LCD_TFT: case LCD_ADTFT: case LCD_HRTFT: default: regValue |= (((pParams->ppl-1) & 0x3FF) << 16); } // panel clock divisor, lower bits regValue |= ((17)-2)&0x0F; // TODO: should be calculated from fcclk //regValue LCD_POL = regValue; // skip line end control LCD_LE = 0; // disable interrupts LCD_INTMSK = 0; // default 16 bits per pixel regValue = LCD_CTRL_REG_BPP24; // default BGR regValue |= LCD_CTRL_REG_BGR; switch(pParams->panelType) { case LCD_ADTFT: case LCD_HRTFT: case LCD_TFT: regValue |= LCD_CTRL_REG_TFT; break; case LCD_MONO_4: regValue |= LCD_CTRL_REG_BW_MONO; break; case LCD_MONO_8: regValue |= (LCD_CTRL_REG_MONO8 | LCD_CTRL_REG_BW_MONO); break; case LCD_CSTN: break; default: break; } if(pParams->dp == 1) { regValue |= LCD_CTRL_REG_DUAL; } LCD_CTRL = regValue; // 0 = divide by 1 LCD_CFG = 0; }
/****************************************************************************** * Implementation of public functions *****************************************************************************/
void lcdSetColorFormat(tColorFormat format) { switch(format) { case COLOR_FORMAT_RGB: LCD_CTRL &= ~LCD_CTRL_REG_BGR; break; case COLOR_FORMAT_BGR: LCD_CTRL |= LCD_CTRL_REG_BGR; break; default: // ERROR break;
} }
void lcdSetBacklight(BYTE percent) { PWM1MR1 = ((unsigned long)0x3000 * (unsigned long)(100-percent)) / (unsigned long)100; PWM1LER = 0x02; }
void lcdSetBpp(tLcdBpp bpp) {
LCD_CTRL &= 0xfffffff1; switch (bpp) { case LCD_BPP1: LCD_CTRL |= LCD_CTRL_REG_BPP1; break; case LCD_BPP2: LCD_CTRL |= LCD_CTRL_REG_BPP2; break; case LCD_BPP4: LCD_CTRL |= LCD_CTRL_REG_BPP4; break; case LCD_BPP8: LCD_CTRL |= LCD_CTRL_REG_BPP8; break; case LCD_BPP16: LCD_CTRL |= LCD_CTRL_REG_BPP16; break; case LCD_BPP24: LCD_CTRL |= LCD_CTRL_REG_BPP24; break; case LCD_BPP16_565: LCD_CTRL |= LCD_CTRL_REG_BPP16_565; break; case LCD_BPP12_444: LCD_CTRL |= LCD_CTRL_REG_BPP12_444; break; }
}
void lcdTurnOn(void) { // enable LCD LCD_CTRL |= LCD_CTRL_REG_EN;
// power on LCD_CTRL |= LCD_CTRL_REG_PWR;
delay(5000); //lcd_display_init();
lcdSetBacklight(100); }
void lcdInit(tLcdParams* pParams) { unsigned int i; //char *d; lcd_hw_init(); a=(pInt32U)0xA0000000; //óêàçàòåëü íà âíåøíþþ ïàìÿòü íà áóôåð îáíîâëåíèÿ 320 x 240 x 32 bit lcdSetBacklight(0); lcd_ctrl_init(pParams); // set the frame buffer LCD_UPBASE = 0xA0000000; a=(pInt32U)0xFFE10800; for(i=0;i<256;i++) *a++=0x00; //CRSR_CTRL=21; CRSR_CTRL=0x0; //îòêëþ÷èëè êóðñîð CRSR_CFG=2; CRSR_CLIP=0x00001010; CRSR_XY=0x00000000; CRSR_PAL0=0x00FF0000; CRSR_PAL1=0x0000FF00; } В майне вызывается lcdInit(&ea_QVGA_v2); static tLcdParams ea_QVGA_v2 = { 28, /* Horizontal back porch */ 10, /* Horizontal front porch */ 2, /* HSYNC pulse width */ 240, /* Pixels per line */ 3, /* Vertical back porch */ 2, /* Vertical front porch */ 2, /* VSYNC pulse width */ 320, /* Lines per panel */ 0, /* Do not invert output enable */ 1, /* Invert panel clock */ 1, /* Invert HSYNC */ 1, /* Invert VSYNC */ 1, /* AC bias frequency (not used) */ 24, /* Bits per pixel */ LCD_ADTFT, /* LCD panel type */ 0, /* Single panel display */ }; Исследования: 0xffff00 - не мирцает 0x000000 - не мирцает 0x008000 - мирцает 0x00ff80 - не мирцает 0x0000ff - не мирцает 0x00ff00 - не мирцает 0x8080ff - мирцает 0xff8040 - мирцает
Сообщение отредактировал IgorKossak - Apr 5 2011, 09:45
Причина редактирования: Длинный код оформляйте тэгами [codebox]
|
|
|
|
|
Apr 6 2011, 05:11
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(M_Andrey @ Apr 5 2011, 21:29)  1. PINSEL11 = 0x0000000d; - это режим 1:5:5:5 не стыкуется с: 24, /* Bits per pixel */ LCD_ADTFT, /* LCD panel type */ надо PINSEL11 = 0x0000000F;
2. 240, /* Pixels per line */ - по горизонтали наверное 320, а 320, /* Lines per panel */ - по вертикали 240
3. regValue |= ((17)-2)&0x0F; // TODO: should be calculated from fcclk LCD_POL = regValue; как раз делит 72МГц на 17 = 4,24МГц
4. Если не ошибаюсь у вас кадры обновляются с частотой: (72/17)/((HBP+HFP+HPW+PPL)*(VBP+VFP+VPW+LPP))=47,63Гц. Можете попробовать постепенно уменьшать число из пред.пункта до 8 для достижения требуемого результата. 1. Там джампера есть переключени на 16. Но у меня стояло 24, поэтому я переделал на PINSEL11 = 0x0000000F; 2. Тут всё нормально. Там по вертикале 320, а по горизонтале 240. Он как бы развёрнут. 3. Я поставил 9, получилось ровно 8 MHz, вроде всё стало работать шикарно. Спасибо большое за помощь. Разобрался.
|
|
|
|
|
Jun 6 2011, 11:24
|
Группа: Новичок
Сообщений: 7
Регистрация: 11-12-07
Пользователь №: 33 185

|
Вообще-то должны быть либо HSYNC и VSYNC либо DCLK. Это разные режимы. И если используются HSYNC и VSYNC, то вход дисплея DCLK должен быть единицей, а не синусом. Рябить также может, если большая частота развёртки, а память не успевает.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|