首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ucos II+ucGUI+s3c2410+LCD+触摸屏整合01

ucos II+ucGUI+s3c2410+LCD+触摸屏整合01

环境:ads2.2+arm9 +s3c2410
  注意:由于编译器(ads1.2或2.2)对全局变量初始化为0的不完全支持,有时必须手动初始化为0,切记!!!
  一、ucos II移植到arm9 s3c2410
  可从官网下载移植代码,基本无需改动。
  在os_cpu_a.s中的函数UCOS_IRQHandler中的bl OSIntEnter和bl C_IRQHandler之间插入如下代码
  ldr r0, =OSIntNesting
  ldrb r0,[r0]
  cmp r0,#1
  bne XX
  ldr r0,=OSTCBCur
  ldr r1,[r0]
  str sp,[r1]                 ; store sp in preempted tasks's TCB
  XX
  二、ucGui 390移植到arm9 s3c2410
  1. Lcd驱动:
  1) 画点函数:
  对dm2410实验板上的lcd,左上为原点(0,0),函数如下:
  void LCD2410_SetPixel(int xp, int yp, U16 color, int dindex)
  {
  *(pLCDBuffer565 + SCREEN_WIDTH*yp + xp) = color;
  }
  为了达到更快的显示速度,别忘了开启Cache!!!
  2)LCD控制器的初始化,对2410函数如下:
  int LCD2410_Init(void)
  {
  if(!isLcdInit)
  {
  InitLcdPort();
  InitLcdRegs();
  isLcdInit = 1;
  return 0;
  }
  return 1;
  }
  void InitLcdPort(void)
  {
  // LCD port initialize.
  s2410IOP->GPCUP = 0xFFFFFFFF;
  s2410IOP->GPCCON = 0xAAAAAAAA;
  s2410IOP->GPDUP = 0xFFFFFFFF;
  s2410IOP->GPDCON = 0xAAAAAAAA;
  s2410IOP->GPGCON &= ~(3 << 8);                 /* Set LCD_PWREN as output  */
  s2410IOP->GPGCON |= (1 << 8);
  s2410IOP->GPGDAT |= (1 << 4);                 //* Backlight ON
  }
  void InitLcdRegs(void)
  {
  s2410LCD->LCDCON1   =   (CLKVAL_TFT << 8) |   //* VCLK = HCLK / ((CLKVAL + 1) * 2) -> About 7 Mhz
  (EACH_FRAME << 7) |   //* 0 : Each Frame
  (3           << 5) |   // TFT LCD Pannel
  (12          << 1) |   //Y: // 16bpp Mode
  (0           << 0) ;   // Disable LCD Output
  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       : LSB valid
  (1           << 11) |   // FRM565 MODE   : 5:5:5:1 Format
  (0           << 10) |   // INVVCLK       : VCLK Falling Edge
  (1           << 9) |   // INVVLINE      : Inverted Polarity
  (1           << 8) |   // INVVFRAME     : Inverted Polarity
  (0           << 7) |   // INVVD         : Normal
  (0           << 6) |   // INVVDEN       : Normal
  (0           << 5) |   // INVPWREN      : Normal
  (0           << 4) |   // INVENDLINE    : Normal
  (1           << 3) |   // PWREN         : Disable PWREN
  (0           << 2) |   // ENLEND        : Disable LEND signal
  (0           << 1) |   // BSWP          : Swap Disable
  (1           << 0) ;   // HWSWP         : Swap Enable
  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); // MASK LCD Sub Interrupt
  s2410LCD->LPCSEL&=(~7); // Disable LPC3600
  s2410LCD->TPAL=0; // Disable Temp Palette
  s2410LCD->LCDCON1 |= 1;
  }
  其中,部分变量、常量定义如下:
  #define LCD_XSIZE_TFT       (800)
  #define LCD_YSIZE_TFT       (480)
  #define HOZVAL_TFT          (LCD_XSIZE_TFT-1)
  #define LINEVAL_TFT         (LCD_YSIZE_TFT-1)
  #define MVAL                (13)
  #define MVAL_USED           (1)
  #define EACH_FRAME                (0)
  //STN/CSTN timing parameter for LCBHBT161M(NANYA)
  #define WLH                 (3)
  #define WDLY                (3)
  #define LINEBLANK           (1 &0xff)
  #define VBPD                ((32-1)&0xff)
  #define VFPD                ((11-1)&0xff)
  #define VSPW                ((2-1) &0x3f)
  #define HBPD                ((88-1)&0x7f)
  #define HFPD                ((40-1)&0xff)
  #define HSPW                ((128-1)&0xff)
  #define CLKVAL_TFT          (0)
  #define M5D(n)              ((n) & 0x1fffff)
  #define SCREEN_WIDTH 800 //800
  #define SCREEN_HEIGHT 480 //480
  #define FRAMEBUF_DMA_BASE               (0x35000000)
  U16* pLCDBuffer565=(U16*)FRAMEBUF_DMA_BASE;
  3)填写配置文件LCDConf.h
  #define LCD_XSIZE      (800)   /* X-resolution of LCD, Logical coor. */
  #define LCD_YSIZE      (480)   /* Y-resolution of LCD, Logical coor. */
  #define LCD_BITSPERPIXEL (16)
  #define LCD_CONTROLLER 1
  #define LCD_SWAP_RB_0  1
  2.触摸屏驱动:
  触摸屏驱动计算出触摸屏的坐标(x,y),对dm2410实验板上的触摸屏,左下为原点,但不一定是(0,0)。两个函数:
  1) 设置中断向量,开中断:
  void SetTSInterrupt(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) 中断处理函数:
  static void TSIrqISR(void)
  {
  int i;
  U32 Pt[6];
  rINTSUBMSK |= (BIT_SUB_ADC|BIT_SUB_TC);
  if(rADCDAT0 & 0x8000)
  {//抬起
  isDown = 0;
  rADCTSC &= 0xff;    // Set stylus down interrupt
  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<LOOP;i++);            //delay to set up the next channel
  for(i=0;i<5;i++)                           //5 times
  {
  rADCCON|=0x1;               // Start X-position conversion
  while(rADCCON & 0x1);       // Check if Enable_start is low
  while(!(0x8000&rADCCON));   // Check ECFLG
  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<LOOP;i++);            //delay to set up the next channel
  for(i=0;i<5;i++)                           //5 times
  {
  rADCCON|=0x1;               // Start Y-position conversion
  while(rADCCON & 0x1);       // Check if Enable_start is low
  while(!(0x8000&rADCCON));   // Check ECFLG
  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);         // Unmask sub interrupt (TC)
  ClearPending(BIT_ADC);
  }
  3) 需要的量:
  #define LOOP 1
  #define ADCPRS 0x27
  int TX=0;//触摸坐标x
  int TY=0;//触摸坐标y
  extern OS_EVENT *TouchMbox;
  int isDown;
  4) 触摸屏校准:
  Ucgui390中,带有一校准程序(于TOUCH_Calibrate.c中),可以改写为我所用(见下文)。
  也可设置默认值,测出左下最小坐标minX,minY和右上最大坐标maxX,maxY,注意是触摸坐标,不是lcd坐标,如下填写配置文件GUITouchConf.h:
  #define GUI_TOUCH_AD_LEFT   minX
  #define GUI_TOUCH_AD_TOP    maxY
  #define GUI_TOUCH_AD_RIGHT maxX
  #define GUI_TOUCH_AD_BOTTOM minY
  #define GUI_TOUCH_SWAP_XY   0
  #define GUI_TOUCH_MIRROR_X   1
  #define GUI_TOUCH_MIRROR_Y 1
  #define TOUCH_NEED_CALIBRATE 0
  3、如下填写GUIConf.h:
  #define GUI_OS                    (1) /* Compile with multitasking support */
  #define GUI_SUPPORT_TOUCH         (1) /* Support a touch screen (req. win-manager) */
  #define GUI_SUPPORT_UNICODE       (1) /* Support mixed ASCII/UNICODE strings */
  #define GUI_SUPPORT_CHINESE              (1)
  #define GUI_DEFAULT_FONT          &GUI_Font6x8
  #define GUI_ALLOC_SIZE            12500 /* Size of dynamic memory ... For WM and memory devices*/
  #define GUI_WINSUPPORT            1 /* Window manager package available */
  #define GUI_SUPPORT_MEMDEV        1 /* Memory devices available */
  #define GUI_SUPPORT_AA            1 /* Anti aliasing available */
  4、ucgui与lcd驱动函数的连接,即修改LCDWin.c文件:
  在LCDWin.c中,去掉无用的头文件包含。
  #define SETPIXEL(x, y, c)   LCD2410_SetPixel(x, y, c, LCD_DISPLAY_INDEX)
  #define GETPIXEL(x, y)    LCD2410_GetPixel(x,y, LCD_DISPLAY_INDEX)
  即将“LCDSIM_XX”改成“LCD2410_XX”,这两个函数位于lcd驱动文件中。
  ……………………………
  #define SETPIXEL(x, y, c) \
  if (!_CheckBound(c)) { \
  LCD2410_SetPixel(x, y, c, LCD_DISPLAY_INDEX); \
  }
  #else
  #define SETPIXEL(x, y, c) LCD2410_SetPixel(x, y, c, LCD_DISPLAY_INDEX)
  #endif
  #define GETPIXEL(x, y)    LCD2410_GetPixel(x,y,LCD_DISPLAY_INDEX)
  ……………………………
  static void _XorPixel(int x, int y) {
  unsigned int Index = LCD_L0_GetPixelIndex(x,y);
  LCD2410_SetPixel(x, y, LCD_NUM_COLORS-1-Index, LCD_DISPLAY_INDEX);
  }
  ……………………………
  int LCD_L0_Init(void) {
  return LCD2410_Init();//调用lcd初始化函数
  }
返回列表