UCOS加上触摸屏支持[源代码+说明]ARM9-2440测试通过~

S3C2410/S3C2440 ADC和触摸屏接口有 等待中断模式 的特性。所以需要编写一个中断函数,来完成ADC数据的读取。
以下代码均在友善提供的ucos移植版上测试通过~
有兴趣的朋友,可以直接下载bin文件实际进行测试,基于eCGUI图形系统的简单演示,支持触摸屏矫正。
链接:http://www.ecgui.com/download/qq2440ucos2.bin
使用ADS1.2编译,请使用DNW下载~

增加两个文件touch.c  和touch.h ,再修改ucos中的uCos2/S3C2440/source/main.c 文件,找到MainTask主函数,
修改部分如下:

int LCD_tourch_init(void);
void MainTask(void *pdata) //Main Task create taks0 and task1
{
   
   #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
   OS_CPU_SR  cpu_sr;
   #endif
   OS_ENTER_CRITICAL();
         
        Timer0Init();//initial timer0 for ucos time tick
        ISRInit();   //initial interrupt prio or enable or disable
        //GUI_Init();
LCD_tourch_init();// 初始化触摸屏
        OS_EXIT_CRITICAL();
//后续部分省略
/*****************************************************************/

以下贴出touch.c 和touch.h 的完整代码,touch.h 中的一些定义可以在2440addr.h等头文件中找到,
但是为了实现模块化,单独编译,就把需要的定义收集在touch.h里了~


/******  touch.h -start*******/
/*
Touch support for ecgui
ecCGUI是一个微型嵌入式图形界面系统,支持linux,dos,ucos等系统,支持常用GUI控件,
体积小巧 大小在 100KB~180KB!
特性: 多窗口支持| 完全中文输入/显示| 多数常用GUI控件| 99.9% ANSI C 编写| 已成功移植 DOS,Linux,uc/OS-II| 组件式 API(易用,高效)
更多信息:http://www.ecgui.com   
email:[email protected]

code from files:Touchpanel.c,2440addr.h,option.h,def.h
*/

// def.h
#define U32 unsigned int
#define U16 unsigned short
#define S32 int
#define S16 short int
#define U8  unsigned char
#define        S8  char

#define        BYTE        char
#define        WORD         short
#define        DWORD        int
#define        UINT        U32
#define        LPSTR        U8 *               

#define TRUE         1   
#define FALSE         0
#ifndef _G_TOUCH_H
#define _G_TOUCH_H

#define OK                1
#define FAIL        0


#define REQCNT 30
#define ADCPRS 9        //YH 0627
#define LOOP 1


//Option.h
#define _ISR_STARTADDRESS         0x33ffff00     

// 2440addr.h ADC
#define rADCCON    (*(volatile unsigned *)0x58000000)        //ADC control
#define rADCTSC    (*(volatile unsigned *)0x58000004)        //ADC touch screen control
#define rADCDLY    (*(volatile unsigned *)0x58000008)        //ADC start or Interval Delay
#define rADCDAT0   (*(volatile unsigned *)0x5800000c)        //ADC conversion data 0
#define rADCDAT1   (*(volatile unsigned *)0x58000010)        //ADC conversion data 1
#define rADCUPDN   (*(volatile unsigned *)0x58000014)        //Stylus Up/Down interrupt status

#define pISR_ADC                (*(unsigned *)(_ISR_STARTADDRESS+0x9c))

// INTERRUPT
#define rSRCPND     (*(volatile unsigned *)0x4a000000)        //Interrupt request status
#define rINTMOD     (*(volatile unsigned *)0x4a000004)        //Interrupt mode control
#define rINTMSK     (*(volatile unsigned *)0x4a000008)        //Interrupt mask control
#define rPRIORITY   (*(volatile unsigned *)0x4a00000c)        //IRQ priority control
#define rINTPND     (*(volatile unsigned *)0x4a000010)        //Interrupt request status
#define rINTOFFSET  (*(volatile unsigned *)0x4a000014)        //Interruot request source offset
#define rSUBSRCPND  (*(volatile unsigned *)0x4a000018)        //Sub source pending
#define rINTSUBMSK  (*(volatile unsigned *)0x4a00001c)        //Interrupt sub mask

#define BIT_ADC                        (0x1<<31)
//#define BIT_ADC                        (0x1<<30)
#define BIT_SUB_ADC                (0x1<<10)
#define BIT_SUB_TC                (0x1<<9)
#define BIT_ALLMSK                (0xffffffff)

int _touch_init(void);
int _touch_exit(void);
int _touch_read(int *x,int *y,int *key);
int LCD_tourch_init(void);

#endif // _G_TOUCH_H


/************* touch.c ************/
/*
Touch support for ecgui
ecCGUI是一个微型嵌入式图形界面系统,支持linux,dos,ucos等系统,支持常用GUI控件,
体积小巧 大小在 100KB~180KB!
特性: 多窗口支持| 完全中文输入/显示| 多数常用GUI控件| 99.9% ANSI C 编写| 已成功移植 DOS,Linux,uc/OS-II| 组件式 API(易用,高效)
更多信息:http://www.ecgui.com   
email:[email protected]
code from files:Touchpanel.c,2440addr.h,option.h
*/

//need touch.h


int _touch_count=0;
volatile int _touch_xdata=0, _touch_ydata=0,_touch_key=0;


int TX=0;//触摸坐标x
int TY=0;//触摸坐标y


int _touch_init(void)
{

return 1;
}

int _touch_exit(void)
{

        return 1;
}
void Uart_Printf(const char *fmt,...);

/*
(912,127) _______ (921,897)
    |                                |
        |                                |
        |                                |
        |                                |
(130,136) ________ (135,899)

=>  x <->y

(127,912)_________(897,921)
    |                                |
        |                                |
        |                                |       
        |                                |
(130,136)_________(899,135)
*/
int _touch_b[2],_touch_k[2];

#define ABS(a) (a<0>?-a:a)

int _touch_txy[4]={127,921,899,135};
int _touch_sxy[4]={0,0,240,320};

void _touch_setbk(int txy[4],int sxy[4])
{
int tw,sw,th,sh;
tw=(txy[0]-txy[2]);
tw=tw<0?0-tw:tw;
sw=(sxy[0]-sxy[2])*100;
sw=sw<0?0-sw:sw;
_touch_k[0]=sw/tw;
Uart_Printf("%d/%d=%d/n",sw,tw,_touch_k[0]);
th=(txy[1]-txy[3]);
th=th<0?0-th:th;
sh=(sxy[1]-sxy[3])*100;
sh=sh<0?0-sh:sh;
_touch_k[1]=sh/th;

Uart_Printf("%d/%d=%d/n",sh,th,_touch_k[1]);
}

int _touch_X(int tx)
{
int x;
x=tx-127;
x*=_touch_k[0];
return (x/100);
}

int _touch_Y(int ty)
{
int y;
y=921-ty;
y*=_touch_k[1];
return (y/100);
}

int _touch_read(int *x,int *y,int *key)
{
*x=_touch_X(TY);
*y=_touch_Y(TX);
*key=_touch_key;
return 0;
}


/* ******************* Touch Support -start *********************** */

#define REQCNT 30
#define ADCPRS 9        //YH 0627
#define LOOP 1

void __irq ost_AdcTsAuto(void);
static void TSIrqISR(void);
__inline void ClearPending(int bit)
{
        register i;
        rSRCPND = bit;
        rINTPND = bit;
        i = rINTPND;
}

int ost_count=0;
volatile int ost_xdata, ost_ydata;

int LCD_tourch_init(void)
{

        _touch_setbk(_touch_txy,_touch_sxy);

        rADCDLY=50000;                  //Normal conversion mode delay about (1/3.6864M)*50000=13.56ms
    rADCCON=(1<<14)+(ADCPRS<<6);   //ADCPRS En, ADCPRS Value

    Uart_Printf("ADC touch screen test/n");

    rADCTSC=0xd3;  //Wfait,XP_PU,XP_Dis,XM_Dis,YP_Dis,YM_En

   // pISR_ADC = (int)ost_AdcTsAuto;
        pISR_ADC = (int)TSIrqISR;
        rINTMSK &=~BIT_ADC;       //ADC Touch Screen Mask bit clear
        rINTSUBMSK &=~(BIT_SUB_TC);

return 0;
}


static void TSIrqISR(void)
{
    int i,j;
    U32 Pt[6];
    rINTSUBMSK |= (BIT_SUB_ADC|BIT_SUB_TC);
     if(rADCDAT0 & 0x8000)
    {//抬起
        _touch_key = 0;
        rADCTSC &= 0xff;    // Set stylus down interrupt
    }
    else //按下
    {          _touch_key = 1;
        rADCTSC=(0<<8)|(0<<7)|(0<<6)|(1<<5)|(1<<4)|(1<<3)|(0<<2)|(1);
        for(i=0;i         for(j=0;j<5;j++)                           //5 times
        {
               rADCCON|=0x1;               // Start X-position conversion
            while(rADCCON & 0x1);       // Check if Enable_start is low
            while(!(0x8000&rADCCON));   // Check ECFLG
                     Pt[j]=(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(j=0;j<5;j++)                           //5 times
        {
            rADCCON|=0x1;               // Start Y-position conversion
            while(rADCCON & 0x1);       // Check if Enable_start is low
            while(!(0x8000&rADCCON));   // Check ECFLG
            Pt[j]=(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);
        }
    Uart_Printf("%d,%d -> (%d,%d)/n",TX,TY,_touch_X(TY),_touch_Y(TX));
    rSUBSRCPND |= BIT_SUB_TC;
    rINTSUBMSK &= ~(BIT_SUB_TC);         // Unmask sub interrupt (TC)   
    ClearPending(BIT_ADC);   
}


/* ******************* Touch Support -end *********************** */

你可能感兴趣的:(微型16/32位嵌入式GUI)