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
{
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
{
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 *********************** */