ucosII+ucGUI+s3c2410+LCD+触摸屏整合.docx
《ucosII+ucGUI+s3c2410+LCD+触摸屏整合.docx》由会员分享,可在线阅读,更多相关《ucosII+ucGUI+s3c2410+LCD+触摸屏整合.docx(24页珍藏版)》请在冰点文库上搜索。
![ucosII+ucGUI+s3c2410+LCD+触摸屏整合.docx](https://file1.bingdoc.com/fileroot1/2023-5/6/bb6cc841-711e-4095-bd73-6b3cc175e9d4/bb6cc841-711e-4095-bd73-6b3cc175e9d41.gif)
ucosII+ucGUI+s3c2410+LCD+触摸屏整合
ucosII+ucGUI+s3c2410+LCD+触摸屏整合
1.ucosII移植到ARM9s3c2410
方法:
可从官网下载移植代码,基本无需改动。
在os_cpu_a.s中的函数UCOS_IRQHandler中的blOSIntEnter和blC_IRQHandler之间插入如下代码:
ldrr0,=OSIntNesting
ldrbr0,[r0]
cmpr0,#1
bneXX
ldrr0,=OSTCBCur
ldrr1,[r0]
strsp,[r1] ;storespinpreemptedtasks'sTCB
2.ucGui390移植到ARM9s3c2410
2.1.Lcd驱动
1)画点函数
对dm2410实验板上的lcd,左上为原点(0,0),函数如下:
voidLCD2410_SetPixel(intxp,intyp,U16color,intdindex)
{
*(pLCDBuffer565+SCREEN_WIDTH*yp+xp)=color;
}
为了达到更快的显示速度,别忘了开启Cache!
!
!
2)LCD控制器的初始化
对2410函数如下:
intLCD2410_Init(void)
{
if(!
isLcdInit)
{
InitLcdPort();
InitLcdRegs();
isLcdInit=1;
return0;
}
return1;
}
voidInitLcdPort(void)
{
//LCDportinitialize.
s2410IOP->GPCUP=0xFFFFFFFF;
s2410IOP->GPCCON=0xAAAAAAAA;
s2410IOP->GPDUP=0xFFFFFFFF;
s2410IOP->GPDCON=0xAAAAAAAA;
s2410IOP->GPGCON&=~(3<<8); /*SetLCD_PWRENasoutput */
s2410IOP->GPGCON|=(1<<8);
s2410IOP->GPGDAT|=(1<<4); //*BacklightON
}
voidInitLcdRegs(void)
{
s2410LCD->LCDCON1 = (CLKVAL_TFT<<8)| //*VCLK=HCLK/((CLKVAL+1)*2)->About7Mhz
(EACH_FRAME<<7)| //*0:
EachFrame
(3 <<5)| //TFTLCDPannel
(12 <<1)| //Y:
//16bppMode
(0 <<0); //DisableLCDOutput
s2410LCD->LCDCON2 = (VBPD <<24)| //*VBPD :
((32-1)&0xff)=0x1f
(LINEVAL_TFT<<14)| //*LINEVAL_TFT:
480-1
(VFPD <<6)| //*VFPD :
((11-1)&0xff)=0xa
(VSPW <<0); //*VSPW :
((2-1)&0x3f)=0x1
s2410LCD->LCDCON3 = (HBPD <<19)| //*HBPD :
((88-1)&0x7f)
(HOZVAL_TFT<<8)| //*HOZVAL_TFT :
800-1
(HFPD <<0); //*HFPD :
((40-1)&0xff)
s2410LCD->LCDCON4 = (MVAL <<8)| //*MVAL :
13
(HSPW <<0); //*HSPW :
((128-1)&0xff)
s2410LCD->LCDCON5 = (0 <<12)| //BPP24BL :
LSBvalid
(1 <<11)| //FRM565MODE :
5:
5:
5:
1Format
(0 <<10)| //INVVCLK :
VCLKFallingEdge
(1 <<9)| //INVVLINE :
InvertedPolarity
(1 <<8)| //INVVFRAME :
InvertedPolarity
(0 <<7)| //INVVD :
Normal
(0 <<6)| //INVVDEN :
Normal
(0 <<5)| //INVPWREN :
Normal
(0 <<4)| //INVENDLINE :
Normal
(1 <<3)| //PWREN :
DisablePWREN
(0 <<2)| //ENLEND :
DisableLENDsignal
(0 <<1)| //BSWP :
SwapDisable
(1 <<0); //HWSWP :
SwapEnable
s2410LCD->LCDSADDR1=((FRAMEBUF_DMA_BASE>>22) <<21)|
((M5D(FRAMEBUF_DMA_BASE>>1))<<0);
s2410LCD->LCDSADDR2=M5D((FRAMEBUF_DMA_BASE+(LCD_XSIZE_TFT*LCD_YSIZE_TFT*2))>>1);
s2410LCD->LCDSADDR3=(((LCD_XSIZE_TFT-LCD_XSIZE_TFT)/1)<<11)|(LCD_XSIZE_TFT/1);
s2410LCD->LCDINTMSK|=(3);//MASKLCDSubInterrupt
s2410LCD->LPCSEL&=(~7);//DisableLPC3600
s2410LCD->TPAL=0;//DisableTempPalette
s2410LCD->LCDCON1|=1;
}
其中,部分变量、常量定义如下:
#defineLCD_XSIZE_TFT (800)
#defineLCD_YSIZE_TFT (480)
#defineHOZVAL_TFT (LCD_XSIZE_TFT-1)
#defineLINEVAL_TFT (LCD_YSIZE_TFT-1)
#defineMVAL (13)
#defineMVAL_USED
(1)
#defineEACH_FRAME (0)
//STN/CSTNtimingparameterforLCBHBT161M(NANYA)
#defineWLH (3)
#defineWDLY (3)
#defineLINEBLANK (1&0xff)
#defineVBPD ((32-1)&0xff)
#defineVFPD ((11-1)&0xff)
#defineVSPW ((2-1)&0x3f)
#defineHBPD ((88-1)&0x7f)
#defineHFPD ((40-1)&0xff)
#defineHSPW ((128-1)&0xff)
#defineCLKVAL_TFT (0)
#defineM5D(n) ((n)&0x1fffff)
#defineSCREEN_WIDTH800//800
#defineSCREEN_HEIGHT480//480
#defineFRAMEBUF_DMA_BASE (0x35000000)
U16*pLCDBuffer565=(U16*)FRAMEBUF_DMA_BASE;
3)填写配置文件LCDConf.h
#defineLCD_XSIZE (800) /*X-resolutionofLCD,Logicalcoor.*/
#defineLCD_YSIZE (480) /*Y-resolutionofLCD,Logicalcoor.*/
#defineLCD_BITSPERPIXEL(16)
#defineLCD_CONTROLLER1
#defineLCD_SWAP_RB_0 1
2.2.触摸屏驱动
触摸屏驱动计算出触摸屏的坐标(x,y),对dm2410实验板上的触摸屏,左下为原点,但不一定是(0,0)。
两个函数:
1)设置中断向量,开中断:
voidSetTSInterrupt(void)
{
rADCDLY=(50000);
rADCCON=(1<<14)|(ADCPRS<<6)|(7<<3)|(0<<2)|(0<<1)|(0);
rADCTSC=(0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
pISR_ADC=(U32)TSIrqISR;//
rINTMSK&=~(BIT_ADC);
rINTSUBMSK&=~(BIT_SUB_TC);
}
2)中断处理函数:
staticvoidTSIrqISR(void)
{
inti;
U32Pt[6];
rINTSUBMSK|=(BIT_SUB_ADC|BIT_SUB_TC);
if(rADCDAT0&0x8000)
{//抬起
isDown=0;
rADCTSC&=0xff; //Setstylusdowninterrupt
TX=-1;
TY=-1;//抬起触笔时,TX,TY要值成不大于0的数
}
else//按下
{ isDown=1;
rADCTSC=(0<<8)|(0<<7)|(0<<6)|(1<<5)|(1<<4)|(1<<3)|(0<<2)|
(1);
for(i=0;i for(i=0;i<5;i++) //5times
{
rADCCON|=0x1; //StartX-positionconversion
while(rADCCON&0x1); //CheckifEnable_startislow
while(!
(0x8000&rADCCON)); //CheckECFLG
Pt=(0x3ff&rADCDAT0);
}
Pt[5]=(Pt[0]+Pt[1]+Pt[2]+Pt[3]+Pt[4])/5;//多次采样取平均值
TX=Pt[5];
rADCTSC=(0<<8)|(0<<7)|(1<<6)|(1<<5)|(0<<4)|(1<<3)|(0<<2)|
(2);
for(i=0;i for(i=0;i<5;i++) //5times
{
rADCCON|=0x1; //StartY-positionconversion
while(rADCCON&0x1); //CheckifEnable_startislow
while(!
(0x8000&rADCCON)); //CheckECFLG
Pt=(0x3ff&rADCDAT1);
}
Pt[5]=(Pt[0]+Pt[1]+Pt[2]+Pt[3]+Pt[4])/5;//多次采样取平均值
TY=Pt[5];
rADCTSC=(1<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
}
//cprintf("%d,%d\n",TX,TY);
OSMboxPost(TouchMbox,0);//向处理触摸进程发消息
rSUBSRCPND|=BIT_SUB_TC;
rINTSUBMSK&=~(BIT_SUB_TC); //Unmasksubinterrupt(TC)
ClearPending(BIT_ADC);
}
3)需要的量:
#defineLOOP1
#defineADCPRS0x27
intTX=0;//触摸坐标x
intTY=0;//触摸坐标y
externOS_EVENT*TouchMbox;
intisDown;
4)触摸屏校准:
Ucgui390中,带有一校准程序(于TOUCH_Calibrate.c中),可以改写为我所用(见下文)。
也可设置默认值,测出左下最小坐标minX,minY和右上最大坐标maxX,maxY,注意是触摸坐标,不是lcd坐标,如下填写配置文件GUITouchConf.h:
#defineGUI_TOUCH_AD_LEFT minX
#defineGUI_TOUCH_AD_TOP maxY
#defineGUI_TOUCH_AD_RIGHTmaxX
#defineGUI_TOUCH_AD_BOTTOMminY
#defineGUI_TOUCH_SWAP_XY 0
#defineGUI_TOUCH_MIRROR_X 1
#defineGUI_TOUCH_MIRROR_Y1
#defineTOUCH_NEED_CALIBRATE0
2.3.如下填写GUIConf.h
#defineGUI_OS
(1)/*Compilewithmultitaskingsupport*/
#defineGUI_SUPPORT_TOUCH
(1)/*Supportatouchscreen(req.win-manager)*/
#defineGUI_SUPPORT_UNICODE
(1)/*SupportmixedASCII/UNICODEstrings*/
#defineGUI_SUPPORT_CHINESE
(1)
#defineGUI_DEFAULT_FONT &GUI_Font6x8
#defineGUI_ALLOC_SIZE 12500/*Sizeofdynamicmemory...ForWMandmemorydevices*/
#defineGUI_WINSUPPORT 1/*Windowmanagerpackageavailable*/
#defineGUI_SUPPORT_MEMDEV 1/*Memorydevicesavailable*/
#defineGUI_SUPPORT_AA 1/*Antialiasingavailable*/
2.4.ucgui与lcd驱动函数的连接,即修改LCDWin.c文件
在LCDWin.c中,去掉无用的头文件包含。
#defineSETPIXEL(x,y,c) LCD2410_SetPixel(x,y,c,LCD_DISPLAY_INDEX)
#defineGETPIXEL(x,y) LCD2410_GetPixel(x,y,LCD_DISPLAY_INDEX)
即将“LCDSIM_XX”改成“LCD2410_XX”,这两个函数位于lcd驱动文件中。
……………………………
#defineSETPIXEL(x,y,c)\
if(!
_CheckBound(c)){\
LCD2410_SetPixel(x,y,c,LCD_DISPLAY_INDEX);\
}
#else
#defineSETPIXEL(x,y,c)LCD2410_SetPixel(x,y,c,LCD_DISPLAY_INDEX)
#endif
#defineGETPIXEL(x,y) LCD2410_GetPixel(x,y,LCD_DISPLAY_INDEX)
……………………………
staticvoid_XorPixel(intx,inty){
unsignedintIndex=LCD_L0_GetPixelIndex(x,y);
LCD2410_SetPixel(x,y,LCD_NUM_COLORS-1-Index,LCD_DISPLAY_INDEX);
}
……………………………
intLCD_L0_Init(void){
returnLCD2410_Init();//调用lcd初始化函数
}