cos-II+ucGUI390+ARM9s3c2410+LCD+触摸屏基本整合成功

Touch_GUI(基于STM32触摸屏) Touch_GUI(基于STM32触摸屏) 提示:基于STM32触摸屏的简易GUI设计(主要涉及逻辑控制,界面较为简化) 文章目录Touch_GUI(基于STM32触摸屏)前言一、 前言 一、 阅读详情

本文来自:http://blog.youkuaiyun.com/jnstone3/archive/2008/09/10/2907161.aspx

 

环境:ads2.2+ARM9+s3c2410
 
注意:由于编译器(ads1.2或2.2)对全局变量初始化为0的不完全支持,有时必须手动初始化为0,切记!!!
 
一、     ucos-II移植到ARM9s3c2410
可从官网下载移植代码,基本无需改动。
在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 
 
二、     ucGui390移植到ARM9s3c2410:
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
用户、组管理学习笔记5.3 安全3A: Authentication:认证 验明身份—计算机普遍用户名、密码。手机指纹、面部识别、图形认证。 Authorization:授权 Accouting|Audition:审计 用户提供账户名、密码进入验证中心进行验证,验证通过后验证中心给予用户令牌(token)。 用户登陆成功后根据令牌(token),发给资源库,资源库识别令牌内的UID给予用户令牌对应权限。... 阅读详情

相关推荐

使用STM32实现简单的图形界面

步骤9:配置STemWin 在"Middlewares" -> "STemWin" -> "Config"文件夹中,找到"LCDConf_template.h"和"GUIConf_template.h"两个文件,将其分别复制并重命名为"LCDConf.h"和"GUIConf.h"。步骤3:配置GPIO 在"Peripherals" -> "GPIO"中配置LCD相关的GPIO引脚,并设置为输出模式。步骤5:配置触摸屏 在"Peripherals" -> "I2C"中配置I2C接口,用于读取触摸屏的数据。

xiaoalla的博客 2109

单片机---STM8L移植ucosII系统

将ucos2.91版本移植到stm8l芯片上

小人物的编程 1516

STM32之简易GUI(多级菜单进阶版)

很久之前,写过一个简易的多级菜单,如今回头看,我都不敢承认那玩意是自己写的,于是打算重新写过一个,并且做成一个简易的GUI。原来用的OLED,现在改成了TFT(ST7789驱动)。但是答题的思路还是不变的。 先说说思路,由于选择的是一个没有触摸的屏幕,于是就要加上物理按键。这样才能操作屏幕嘛。 按照面向对象的思想,我将整个GUI结构分为三类:按键,显示,动作。 按键用来控制屏幕,进行上滑下滑切入切出菜单; 显示则作为每一级菜单的背景,并且将菜单设置为静态显示(即每次切换只显示一次); 动作则用来链接各种显

qq_43940175的博客 1万+

Ucos-II+ucGUI390+ARM2410+LCD+触摸屏基本整合成功(更新于2007-3-15)

  ucos-II+ucGUI390+ARM9s3c2410+LCD+触摸屏基本整合成功(最近更新于2007-3-15) 环境:ads2.2+ARM9+s3c2410 注意:由于编译器(ads1.2或2.2)对全局变量初始化为0的不完全支持,有时必须手动初始化为0,切记!!! 一、     ucos-II移植到ARM9s3c2410可从官网下载移植代码,基本

@塘外人 7584

UCGUI+UCOS-II 例程源代码

UCGUI+UCOS-II 例程源代码,包含内容:STM32 UCOS-II UCGUI图形开发库。

GXHT40温湿度传感器:I2C通信与CRC校验实战解析

本文详细解析GXHT40温湿度传感器的I2C通信协议与CRC校验机制,涵盖硬件连接、时序控制、数据读取及加热功能应用。通过实战案例分享优化技巧与异常处理,帮助开发者提升嵌入式系统中传感器数据的准确性与可靠性。

rgv234567的博客 242

ucos-ii和ucgui在stm32上的移植及工程

uc/os-ii移植笔记<br />(此部分参考了tomato的介绍)<br />os_cpu.h<br />与编译器相关的数据类型<br /> <br />typedef   unsigned char   BOOLEAN;<br />typedef   unsigned char   INT8U;                    /* Unsigned  8 bit quantity */<br />typedef   signed   char   INT8S;                 

guoyin的专栏 4950

使用阿里天池平台训练YOLO目标检测模型

YOLO算法是一种单阶段目标检测算法,由Joseph Redmon等人于2015年提出。与传统的两阶段检测算法相比,YOLO将目标检测问题转化为回归问题,直接预测边界框的位置和类别概率,大大提高了检测速度。YOLOv1: 首次提出YOLO的核心思想,将图像分割成网格,每个网格预测边界框和类别概率。YOLOv2: 引入了批量归一化、锚框等改进,提高了检测精度。YOLOv3: 采用多尺度预测,增强了对小目标的检测能力。

步子哥的博客 1090

STM32 触摸屏移植GUI控制控件

指向输入设备可以是触摸屏、鼠标或者游戏操纵杆触摸屏驱动一般会简单的调用 GUI_PID_StoreState().这种方式可以支持任何类型的触摸屏。用户负责编写驱动代码(一般来说都很简单)。

Lushengshi的博客 4297

用 Custom Entity 打造 RAP Value Help:从能跑到好用的深度踩坑笔记

本文介绍了在RAP项目中实现Value Help(Fiori输入帮助)的完整流程。通过Custom Entity方式,开发者可以灵活构建不依赖数据库实体的值帮助功能,但需手动实现CDS原本提供的过滤、排序、分页等能力。文章以一个典型场景为例,详细说明了如何为Partner维护界面的City字段创建可搜索的值帮助,包括创建查询实现类、绑定CDS Custom Entity、服务发布等关键步骤,并特别指出了处理排序分页请求等常见问题。最后强调在ABAP Cloud环境下需要自行实现查询能力,而非依赖传统工具类。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 140

Sigrity SPEED2000 General SI Simulation模式如何进行信号仿真分析操作指导-DDR

本例是几个简单的板载DDR颗粒的结构,本例中使用General SI Simulation模式仿真DDR信号,结构拓扑如下,Addcmd,clk,cke都是T拓扑。Sigrity SPEED2000 General SI Simulation模式可以对信号进行仿真分析,仿真将电源视为理想电源,以下图为例进行说明。DQS的接收端模型设置为DQS_34_ODT60_1333。模式如何进行信号仿真分析操作指导-DDR。附带驱动和接收端的IBIS模型。

weixin_54787054的博客 513

emwin窗口中显示触摸痕迹,使用2D图形API画点的办法

项目需要,在窗体中显示触摸效果,在网上搜索办法,搜到安富来的一篇教程 http://blog.sina.com.cn/s/blog_98ee3a930102wqwi.html 按照里面的办法,我在WM_TOUCH事件里获取触摸的坐标,并画点,显示成功 case WM_TOUCH: { GUI_PID_STATE TouchState; GUI_TOUCH_GetState(&TouchState); hWinOld= WM_SelectWindow(WM_GetClientWindow(pMsg-&

flash1983的博客 912

Python地理数据处理 十七:植被物候提取和分析(Savitzky-Golay)

植被是陆地生态系统中最重要的组分之一,也是对气候变化最敏感的组分,其在全球变化过程中起着重要作用,能够指示自然环境中的大气、水、土壤等成分的变化,其年际和季节性变化可以作为地球气候变化的重要指标。此外,由于生态工程保护建设和植被自然生长等因素,中国陆地生态系统发挥了重要的碳汇作用。因此,定量评估植被时空动态变化是制定生态系统可持续发展目标和衡量生态系统固碳潜力的重要前提,卫星遥感数据衍生的生态参量产品为研究长时间序列全球及区域植被时空变化提供了重要数据源。SG滤波能够对物候信息进行平滑,并提取其中的物候信息

amyniez的博客,欢迎交流讨论 4247

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

环境: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版,

abbing的专栏 4038

23、管状剪纸结构的研究与功能生成连杆机构的综合设计

本文研究了管状剪纸结构的压缩运动特性,通过剪纸技术将非刚性可折叠的Yoshimura和Kresling折纸结构转化为刚性可折叠结构,并提出径向可闭合剪纸(RC-kiri)构型。推导了位移与折叠角之间的数学关系,设计了带外部LET接头的RC-kiri模型,建立了力-位移理论模型并通过Abaqus进行有限元验证,制作了3D打印物理模型以测量直径变化。同时,研究了四杆和六杆功能生成连杆机构的综合设计方法,基于负闭合运动链和最小二乘法实现函数生成。结果表明理论、仿真与实验整体吻合良好,误差来源得到分析,为机器人、机

nokia的博客 167

RT-Thread Studio 使用笔记(七)| 配合STM32CubeMX添加裸机驱动(以ADC为例)

1. 配置STM32CubeMX 2. 复制stm32xxxx_hal_msp.c文件 将 CubeMx 生成的代码 stm32f7xx_hal_msp.c 函数复制到 RT-Thread Studio 生成的工程中,并参与工程编译: 由于我们并没有使用 CubeMx 生成的工程,所以这里需要将 stm32f7xx_hal_msp.c 文件中 #include “main.h” 替换为 #i...

Mculover666的博客(嵌入式) 9626

signature=550f83b3c0ee7d4581add4fc23bcdd2e,Security and Quality Rollup for .NET Framework 4.6, 4.6.1...

Amd64_01f6ca84130fb592db1c8fd7756824c4_b03f5f7f11d50a3a_4.0.9264.17143_none_2b54432407a1b7cd.manifestNot applicable62611-Dec-201903:17Not applicableAmd64_05a1f18662cc99d684763e0fdb7c4eaa_b03f5f7f11d50...

weixin_39631667的博客 1663

Linux----Ubuntu系统官网下载iso镜像文件

Linux----Ubuntu系统官网下载iso镜像文件

MQ0522的博客 5万+

in_addr

struct in_addr {    in_addr_t s_addr;    };    结构体in_addr 用来表示一个32位的IPv4地址.    in_addr_t 一般为 32位的unsigned long.    其中每8位代表一个IP地址位中的一个数值.    例如192.168.3.144记为0xc0a80390,其中 c0 为192 ,a8

king16304的博客 1460

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

git add使用大全

作用:将当前新建、修改过的文件的内容生成快照,加入到索引中,或者删除工作树中不存在的路径。 git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p] [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--u...

u012953143的博客 4046

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

010Editor实战:游戏文件校验机制分析与绕过思路

在游戏安全与逆向工程领域,文件完整性校验是反作弊体系的重要防线。其核心原理并不神秘——程序在运行时读取目标文件内容,通过哈希算法计算指纹并与预存值比对,从而判断文件是否被篡改。理解这一机制,需要从二进制数据的基本分析方法入手,而010Editor作为一款专业的十六进制编辑器,凭借模板化结构解析、灵活的模式搜索及文件对比能力,成为剖析未知文件格式、定位校验逻辑的利器。它既能将原始字节流转化为可读的字段树,也能快速锁定硬编码的哈希值或路径字符串,为后续的绕过分析提供了高效路径。这项技术广泛应用于漏洞研究、恶意样

weixin_34242509的博客 474

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【python】在学习用于图和网络分析的python时遇到的问题和解决方法

【python】在学习用于图和网络分析的python时遇到的报错和解决方法 1.Python安装igraph包加载出错问题 报错: Python中加载igraph包(from igraph import *)出现igraph包重复,请升级jgraph的错误信息。 报错信息如下: “DeprecationWarning: To avoid name collision with the igraph project, this visualization library has been renamed to

qq_45688243的博客 6755

wear的complication系列文字稿

Youtube subtitles download by mo.dbxdb.com OLIN LAN: Hello, everybody. I'm Oli Lan, an engineer on the Android Wear team. TONY FERREIRA: And I'm Tony Ferreira, a designer on Android Wear.

russe124的博客 2361

洛谷 - P4390 [BOI2007]Mokia 摩基亚(带修二维数点-四叉线段树/CDQ分治)

题目链接:点击查看 题目大意:给出一个二维平面坐标系,需要执行数次操作,具体操作分为下列两种: 1 x y a:坐标 (x,y)(x,y)(x,y) 加上 aaa 个点 2 x1 y1 x2 y2:查询以 (x1,y1)(x_1,y_1)(x1​,y1​) 为左下角、(x2,y2)(x_2,y_2)(x2​,y2​) 为右上角的矩阵中有多少个点 题目分析:三种做法,但是树套树内存不太够,所以拿不了满分。 剩下的四叉树跑的巨慢,cdq分治表现还算不错。因为写 cdqcdqcdq 的时候询问和加点并不会冲突

Falcon的博客 822

390 Stream流中间操作之sorted

390 Stream流中间操作之sorted Stream <T> sorted() 返回自然排序的流 Stream <T> sorted(Comparator comparator) 返回comparator排序的流 【练习需求】 按字母顺序排列元素 按字符串长度排列元素 【报错了】 按原代码写完,运行结果不理想,为什么? 理想结果:按字符串长度排序,长度一样的按自然顺序排序 实际结

m0_63673788的博客 371

Leetcode 解题报告

据说刷完leetcode是准备编程面试的第一步。想到明年可能就要开始找工作了,先准备着吧。 计划今年11月份前做完,大概平均每天2-3题,难度应该不大,贵在坚持! 代码放在github上,地址:https://github.com/xingjian-f/Leetcode-solution 简略解题报告 1 Two Sum 三种解法: 1 暴力枚举所有的两两组合,检查它们的和是否等于

勿忘初衷 1万+
上一篇: 关于从NAND Flash启动的问题,2440 启动问题 , 拷贝4k程序 ,启动代码分析
下一篇: 嵌入式用户图形接口uC/GUI在uC/OSII上的嵌入
#Page#
博客等级 码龄23年 1691粉丝 360原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值