1. gzyueqian
      13352868059
      首頁 > 新聞中心 > > 正文

      ucos II+ucGUI+s3c2410+LCD+觸摸屏整合

      更新時間: 2008-01-09 08:48:41來源: 粵嵌教育瀏覽量:1218

      環境: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之間插入如下代碼(見邵貝貝,第2版,第104頁的說明:L3.18(4) ):
      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[i]=(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[i]=(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初始化函數
      }

      5、某些編譯器(如:ads1.2)不會初始化全局變量,因此做如下事:
      1) 修改如下函數為:(位于GUICore.c)
      static void _InitContext(GUI_CONTEXT* pContext) {

      memset(pContext,0,sizeof(GUI_CONTEXT));//add

      #if GUI_SUPPORT_MEMDEV
      GUI_SelectLCD();
      #else
      LCD_SetClipRectMax();//LCD_L0_GetRect
      #endif
      pContext->pLCD_HL = &LCD_HL_APIList;
      pContext->pAFont = GUI_DEFAULT_FONT;
      pContext->pClipRect_HL = &GUI_Context.ClipRect;
      pContext->PenSize = 1;
      pContext->DrawMode = GUI_DRAWMODE_NORMAL;//add
      pContext->TextMode = GUI_TEXTMODE_NORMAL;//add
      pContext->TextAlign = GUI_TA_LEFT|GUI_TA_TOP;//add
      pContext->AA_HiResEnable = 0;//add
      /* Variables in WM module */
      #if GUI_WINSUPPORT
      pContext->hAWin = WM_GetDesktopWindow();
      #endif
      /* Variables in GUI_AA module */
      pContext->AA_Factor = 3;
      LCD_SetBkColor(GUI_DEFAULT_BKCOLOR);
      LCD_SetColor(GUI_DEFAULT_COLOR);
      }

      修改如下函數為:(位于GUIAlloc.c)
      void GUI_ALLOC_Init(void) {
      ........
      GUI_ALLOC.NumUsedBytes = 0;
      memset(&aBlock,0,sizeof(aBlock[0])*GUI_MAXBLOCKS);/////self
      aBlock[0].Size = (1<<GUI_BLOCK_ALIGN); /* occupy minimum for a block */
      .......
      }


      修改如下函數為:(位于WM.c)(――――――――――New)
      void WM_Init(void) {
      if (!_IsInited) {
      ……….
      memset(&_ClipContext,0,sizeof(WM_IVR_CONTEXT));//add
      NextDrawWin = WM__FirstWin = WM_HWIN_NULL;
      ……………….
      _IsInited =1;
      }
      }
      2)自己編寫如下函數(ads1.2):
      void MyInit()
      {
      IsInitialized = 0;//MemDev
      _IsInited = 0;//Win
      WM__CreateFlags = 0;
      GUI_CURSOR_pfTempHide = NULL;
      GUI_Context.hDevData = 0;
      WM__hCapture=0;
      WM__hWinFocus=0;
      WM_pfPollPID = 0;
      WM_pfHandlePID = 0;
      GUI_pfTimerExec = 0;
      _KeyMsgCnt = 0;
      }
      該函數應在GUI_Init()調用之前調用。

      6、改寫GUI_Init()函數:
      int GUI_Init(void) {
      int r;
      GUI_DEBUG_LOG("\nGUI_Init()");
      /* Init system wide globals first */
      GUI_DecChar = '.';

      /* Init context */
      _InitContext(&GUI_Context);
      GUITASK_INIT();
      r = LCD_Init();
      #if GUI_WINSUPPORT
      WM_Init();
      #endif
      GUITASK_COPY_CONTEXT();
      GUI_Clear();
      GUI_X_Init();
      GUI_CURSOR_Show();//啟動即顯示鼠標
      return r;
      }

      三、ucGUI與ucOS的整合,主要修改GUI_X.c文件:
      1、定義信號量及全局量:
      static OS_EVENT *DispSem;
      static OS_EVENT *EventMbox;
      static OS_EVENT *KeySem;
      static int KeyPressed;
      static char KeyIsInited;
      2、實現結合函數:
      int GUI_X_GetTime(void)
      {
      return ((int)OSTimeGet());
      }
      void GUI_X_Delay(int period)
      {
      INT32U ticks;
      ticks = (period * 1000) / OS_TICKS_PER_SEC;
      OSTimeDly((INT16U)ticks);
      }
      void GUI_X_Unlock(void)
      {
      OSSemPost(DispSem);
      }
      void GUI_X_Lock(void)
      {
      U8 err;
      OSSemPend(DispSem, 0, &err);
      }
      U32 GUI_X_GetTaskId(void)
      {
      return ((U32)(OSTCBCur->OSTCBPrio));
      }
      void GUI_X_WaitEvent (void)
      {
      INT8U err;
      (void)OSMboxPend(EventMbox, 0, &err);
      }
      void GUI_X_SignalEvent (void)
      {
      (void)OSMboxPost(EventMbox, (void *)1);
      }
      void GUI_X_InitOS(void)
      {
      DispSem = OSSemCreate(1);
      EventMbox = OSMboxCreate((void *)0);
      }
      void GUI_X_ExecIdle(void) {GUI_X_Delay(1);}

      void GUI_X_Init(void) {
      SetTSInterrupt();//此處接入觸摸屏的中斷設置
      GUI_TOUCH_SetDefaultCalibration();//用默認值校準觸摸屏
      }

      四、與觸摸屏有關的函數:
      1、4個功能函數:
      void GUI_TOUCH_X_ActivateX(void) {//空}
      void GUI_TOUCH_X_ActivateY(void) {//空}
      int GUI_TOUCH_X_MeasureX(void) {
      return TX;//返回觸摸坐標x
      }
      int GUI_TOUCH_X_MeasureY(void){
      return TY; //返回觸摸坐標y
      }

      2、觸摸屏校準任務(進程, 來自示例程序:TOUCH_Calibrate.c):
      #if TOUCH_NEED_CALIBRATE
      static const char * _acPos[] = {
      "(upper left position)",
      "(lower right position)"
      };
      static void _WaitForPressedState(int Pressed) {
      GUI_PID_STATE State;
      /* Wait until touch is pressed */
      do {
      GUI_TOUCH_GetState(&State);
      if (State.Pressed == Pressed) {
      break;
      }
      GUI_Delay (100);
      } while (1);
      }
      static void _DispStringCentered(const char * pString) {
      GUI_RECT Rect;
      Rect.x0 = Rect.y0 = 0;
      Rect.x1 = LCD_GetXSize() - 1;
      Rect.y1 = LCD_GetYSize() - 1;
      GUI_DispStringInRect(pString, &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER);
      }
      static void _GetPhysValues(int LogX, int LogY, int * pPhysX, int * pPhysY, const char * pString) {
      char acText[] = "Press here";
      GUI_RECT Rect;
      int FontSizeY, Align;
      FontSizeY = GUI_GetFontSizeY();
      GUI_Clear();
      GUI_SetColor(GUI_BLACK);
      _DispStringCentered("Runtime calibration,\n"
      "please touch the screen\n"
      "at the center of the ring."); /* Ask user to press the touch */
      /* Calculate the rectangle for the string */
      Rect.y0 = LogY - FontSizeY;
      Rect.y1 = LogY + FontSizeY;
      if (LogX < LCD_GetXSize() / 2) {
      Rect.x0 = LogX + 15;
      Rect.x1 = LCD_GetXSize();
      Align = GUI_TA_LEFT;
      } else {
      Rect.x0 = 0;
      Rect.x1 = LogX - 15;
      Align = GUI_TA_RIGHT;
      }
      /* Show the text nearby the ring */
      GUI_DispStringInRect(acText, &Rect, Align | GUI_TA_TOP);
      GUI_DispStringInRect(pString, &Rect, Align | GUI_TA_BOTTOM);
      /* Draw the ring */
      GUI_FillCircle(LogX, LogY, 10);
      GUI_SetColor(GUI_WHITE);
      GUI_FillCircle(LogX, LogY, 5);
      GUI_SetColor(GUI_BLACK);
      /* Wait until touch is pressed */
      _WaitForPressedState(1);
      *pPhysX = GUI_TOUCH_GetxPhys();
      *pPhysY = GUI_TOUCH_GetyPhys();
      /* Wait until touch is released */
      _WaitForPressedState(0);
      }

      static void _Explain(void) {
      _DispStringCentered("This sample shows how\n"
      "a touch screen can be\n"
      "calibrated at run time.\n"
      "Please press the touch\n"
      "screen to continue...");
      GUI_DispStringHCenterAt("TOUCH_Calibrate", LCD_GetXSize() / 2, 5);
      _WaitForPressedState(1);
      _WaitForPressedState(0);
      }

      void CalibrateTask(void* pdata) {//觸摸屏校準任務入口
      int aPhysX[2], aPhysY[2], aLogX[2], aLogY[2], i;
      GUI_SetBkColor(GUI_WHITE);
      GUI_Clear();
      GUI_SetColor(GUI_BLACK);
      GUI_SetFont(&GUI_Font13B_ASCII);
      _Explain();
      /* Set the logical values */
      aLogX[0] = 15;
      aLogY[0] = 15;
      aLogX[1] = LCD_GetXSize() - 20;
      aLogY[1] = LCD_GetYSize() - 20;
      /* Get the physical values of the AD converter for 2 positions */
      for (i = 0; i < 2; i++) {
      _GetPhysValues(aLogX[i], aLogY[i], &aPhysX[i], &aPhysY[i], _acPos[i]);
      }
      /* Use the physical values to calibrate the touch screen */
      GUI_TOUCH_Calibrate(0, aLogX[0], aLogX[1], aPhysX[0], aPhysX[1]); /* Calibrate X-axis */
      GUI_TOUCH_Calibrate(1, aLogY[0], aLogY[1], aPhysY[0], aPhysY[1]); /* Calibrate Y-axis */

      { /* calculate and display values for configuration file */
      int calX0, calX1;
      int calY0, calY1;
      GUI_Clear();

      GUI_TOUCH_GetCalData(GUI_COORD_X, &calX0, &calX1);
      GUI_TOUCH_GetCalData(GUI_COORD_Y, &calY0, &calY1);

      GUI_DispStringAt("calX0: ", 0, 0); GUI_DispDec(calX0, 4); GUI_DispNextLine();
      GUI_DispString ("calX1: "); GUI_DispDec(calX1, 4); GUI_DispNextLine();
      GUI_DispString ("calY0: "); GUI_DispDec(calY0, 4); GUI_DispNextLine();
      GUI_DispString ("calY1: "); GUI_DispDec(calY1, 4);

      GUI_DispStringAt("lcdx0: ", 0, 200); GUI_DispDec(aLogX[0], 4); GUI_DispNextLine();
      GUI_DispString ("lcdx1: "); GUI_DispDec(aLogX[1], 4); GUI_DispNextLine();
      GUI_DispString ("lcdy0: "); GUI_DispDec(aLogY[0], 4); GUI_DispNextLine();
      GUI_DispString ("lcdy1: "); GUI_DispDec(aLogY[1], 4); GUI_DispNextLine();

      GUI_DispString ("tscX0: "); GUI_DispDec(aPhysX[0], 4); GUI_DispNextLine();
      GUI_DispString ("tscX1: "); GUI_DispDec(aPhysX[1], 4); GUI_DispNextLine();
      GUI_DispString ("tscY0: "); GUI_DispDec(aPhysY[0], 4); GUI_DispNextLine();
      GUI_DispString ("tscY1: "); GUI_DispDec(aPhysY[1], 4); GUI_DispNextLine();

      GUI_DispString ("Please touch display to continue...");
      GUI_Delay(1000);

      _WaitForPressedState(1);
      _WaitForPressedState(0);
      }
      GUI_Clear();
      SystemOn();
      OSTaskSuspend(OS_PRIO_SELF);

      }
      3、為了響應觸摸屏,做如下事:
      1)創建進程處理觸摸事件,形式如下:
      void TouchTask(void* data) {
      INT8U err;
      while(1)
      {
      CONSOL_Printf("Waiting for Touch......\n");
      OSMboxPend(TouchMbox, 0, &err); /* Acquire semaphore to perform random numbers */
      CONSOL_Printf("Got a message\n");
      GUI_TOUCH_Exec();//
      }
      }
      2) 如下修改函數 GUI_TOUCH_Exec():
      void GUI_TOUCH_Exec(void) {
      #ifndef WIN32
      static U8 ReadState;
      int x,y;
      /* calculate Min / Max values */
      if (xyMinMax[GUI_COORD_X].Min < xyMinMax[GUI_COORD_X].Max) {
      xMin = xyMinMax[GUI_COORD_X].Min;
      xMax = xyMinMax[GUI_COORD_X].Max;
      } else {
      xMax = xyMinMax[GUI_COORD_X].Min;
      xMin = xyMinMax[GUI_COORD_X].Max;
      }
      if (xyMinMax[GUI_COORD_Y].Min < xyMinMax[GUI_COORD_Y].Max) {
      yMin = xyMinMax[GUI_COORD_Y].Min;
      yMax = xyMinMax[GUI_COORD_Y].Max;
      } else {
      yMax = xyMinMax[GUI_COORD_Y].Min;
      yMin = xyMinMax[GUI_COORD_Y].Max;
      }
      /* Execute the state machine which reads the touch */
      //switch (ReadState) {
      //case 0:
      yPhys = TOUCH_X_MeasureY();
      // TOUCH_X_ActivateY(); /* Prepare X- measurement */
      // ReadState++;
      // break;
      //default:
      xPhys = TOUCH_X_MeasureX();
      // TOUCH_X_ActivateX(); /* Prepare Y- measurement */
      /* Convert values into logical values */
      #if !GUI_TOUCH_SWAP_XY /* Is X/Y swapped ? */
      x = xPhys;
      y = yPhys;
      #else
      x = yPhys;
      y = xPhys;
      #endif

      if ((x <xMin) | (x>xMax) | (y <yMin) | (y>yMax)) {
      GUI_TOUCH_StoreUnstable(-1,-1);
      } else {
      x = AD2X(x);
      y = AD2Y(y);
      GUI_TOUCH_StoreUnstable(x,y);
      }
      /* Reset state machine */
      //ReadState=0;
      // break;
      //}
      #endif /* WIN32 */
      }

      五、 GUI多任務測試:
      測試程序:MT_MultiTasking.c

      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 在线中文字幕亚洲日韩日本 | 最新在线精品国自产拍视频 | 久久精品79国产精品 | 一区二区粉嫩高清AV | 日韩欧美国产精品专区 | 日本高清一本大道不卡视频 |