广告位招租搞笑图片:ucos II+ucGUI+s3c2410+LCD+触摸屏整合

来源:百度文库 编辑:中财网 时间:2024/04/29 17:55:06
ucos II+ucGUI+s3c2410+LCD+触摸屏整合

特别说明:需要嵌入式UCOSII   ucGUI  arm和linux入门资料,项目资料,linux驱动资料可以加我QQ!!希望我的一些项目经验和资料可以带你进入嵌入式之门,在浩瀚的linux世界里找到属于你自己的舞台!!!希望大家多多支持

我的QQ:1653687969

 ; 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        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<.......
}
 
 
修改如下函数为:(位于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 xMax) | (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