使用的是RVDS4.0编译的
大家主要是看看如何配置模式的
我之前一直使用自动X,Y采样,但是读取的都不准,最后采样分离的,才可以,需要注意的是使能ADC读开始后需要先读转换结果寄存器,但是此时读取的是上一次的转换结果,如果是连续读取需要等待转换完成,否则转换结果不准.
adc.c
/************************************************************************************************************* * 文件名: ADC.c * 功能: S3C6410 ADC底层驱动函数 * 作者: [email protected] * 创建时间: 2012年3月12日21:05 * 最后修改时间:2012年3月12日 * 详细: 触摸屏驱动以及相关ADC驱动 * 问题: 一直以来存在一个误区,一直以为使用了启动开始读操作,每次读DAT寄存器后就可以读取到转换后的数据,最终发现使用这个后读到的是上一次的数据, * 还是需要等到转换完成,否则连续转换的时候数据会非常乱. * 现在使用的是手动控制转换开始 *************************************************************************************************************/ #include "system.h" #include "ADC.h" //ADC的控制寄存器 ADCCON #define ADCCON_RESSEL_12BIT (1 << 16) //12bit模式 #define ADCCON_ECFLG (0 << 15) //A/D转换结束标志只读; #define ADCCON_PRSCEN (1 << 14) //A/D转换器预分频器使能 #define ADCCON_PRSCVL (32 << 6) //预分频值,1-255,分频值+1,至少为PCLK的1/5,此时PCLK = 66MHZ,在2.5MHZ时钟下转换最快 #define ADCCON_SEL_MUX (0 << 3) //默认选择通道0 #define ADCCON_STDBM (0 << 2) //正常模式 #define ADCCON_READ_START (0 << 1) //关闭启动开始读操作 #define ADCCON_ENABLE_START (0 << 0) //如果READ_START 启用,这个值是无效的。 //ADCDLY #define ADCDLY_DELAY 500 //自动采样延时时间, /************************************************************************************************************************* *函数 : void SetADC_Channel(u8 ch) *功能 : 设置ADC输入通道 *参数 : ch:通道号,0-7 *返回 : 无 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 20120513 *最后修改时间: 20120513 *说明 : ADC输入通道选择 *************************************************************************************************************************/ void SetADC_Channel(u8 ch) { ADC->CON &= ~(7 << 3); //清除通道 ADC->CON |= ch & (0x07); //设置通道号 } /************************************************************************************************************************* *函数 : void ADC_Init(void) *功能 : ADC初始始化 *参数 : 无 *返回 : 无 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 20120312 *最后修改时间: 20120313 *说明 : ADC初始始化 *************************************************************************************************************************/ void ADC_Init(void) { //ADC的控制寄存器配置;12BIT模式 ADC->CON = ADCCON_RESSEL_12BIT + ADCCON_ECFLG + ADCCON_PRSCEN + ADCCON_PRSCVL + ADCCON_SEL_MUX + ADCCON_STDBM + ADCCON_READ_START + ADCCON_ENABLE_START; ADC->DLY = ADCDLY_DELAY; //设置自动间隔采样时间 } /************************************************************************************************************************* *函数 : void ADC_SetMode(u8 Mode) *功能 : 设置ADC模式 *参数 : 无 *返回 : 无 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 20120313 *最后修改时间: 20120313 *说明 : 设置ADC模式 *************************************************************************************************************************/ void ADC_SetMode(u8 Mode) { ADC->TSC &= (1 << 8); //清除原先设置 ADC->CON &= ~BIT2; //退出待机模式 XP_UP_DISABLE(); //XP上拉禁止 Normal_ADC_Mode(); //普通ADC模式 switch(Mode) { case COMMON_AD_MODER: //普通ADC模式 Normal_ADC_Mode();break; case ASUNDER_X_MODER: //分离的X扫描模式 { ADCTSC_XP_VDD(); ADCTSC_XM_GND(); ADCTSC_YP_HZ(); ADCTSC_YM_HZ(); X_PosMode(); }break; //XP=外部电源,XM=GND,YP=AIN5,YM=高阻 case ASUNDER_Y_MODER: //分离的Y扫描模式 { ADCTSC_XP_HZ(); ADCTSC_XM_HZ(); ADCTSC_YP_VDD(); ADCTSC_YM_GND(); Y_PosMode(); }break; //XP=AIN7,XM=高阻,YP=外部电源,YM=GND case AUTO_XY_MODER: //自动XY扫描模式 { AUTO_XYPosition(); }break; case INT_AD_MODER: //等待中断模式 { ADCTSC_XP_HZ(); ADCTSC_XM_HZ(); ADCTSC_YP_HZ(); ADCTSC_YM_GND(); XP_UP_ENABLE(); //XP上拉使能 INT_WaitingMode(); }break;//XP上拉,XM=高阻,YP=AIN5,YM=GND case STANDBY_AD_MODER: //掉电模式 StandbyMode();break; default:break; } } /************************************************************************************************************************* *函数 : u16 ADC_ReadX(void) *功能 : 读取X坐标 *参数 : 无 *返回 : X坐标原始坐标值 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 20121006 *最后修改时间: 20121006 *说明 : 读取的是ADC转换寄存器0 * 需要先设置ADC模式 *************************************************************************************************************************/ u16 ADC_ReadX(void) { ADC_Start(); //开始一次ADC转换 ADC_Wait(); //等待转换完成 return ADC_ReadData0(); } /************************************************************************************************************************* *函数 : u16 ADC_ReadY(void) *功能 : 读取Y坐标 *参数 : 无 *返回 : Y坐标原始坐标值 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 20121006 *最后修改时间: 20121006 *说明 : 读取的是ADC转换寄存器1 * 需要先设置ADC模式 *************************************************************************************************************************/ u16 ADC_ReadY(void) { ADC_Start(); //开始一次ADC转换 ADC_Wait(); //等待转换完成 return ADC_ReadData1(); } /************************************************************************************************************************* *函数 : u8 Get_TouchState(void) *功能 : 获取触摸状态 *参数 : 无 *返回 : 1:笔抬起;0:笔按下 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 20120315 *最后修改时间: 20120315 *说明 : 通过读取ADCDAT1的BIT15来确定状态 *************************************************************************************************************************/ u8 Get_TouchState(void) { return((ADC->DAT1 & BIT15) ? TOUCH_UP : TOUCH_DOWN); } //触摸屏中断服务函数 void __irq Isr_Touch(void) { TOUCH_ClearInt(); //清除触摸屏中断标志 VICInterruptEnd(); //中断结束 }
/************************************************************************************************************* * 文件名: ADC.h * 功能: S3C6410 触摸屏ADC底层驱动函数 * 作者: 陈鹏 * 创建时间: 2012年3月12日21:05 * 最后修改时间:2012年3月12日 * 详细: 触摸屏驱动以及相关ADC驱动 *************************************************************************************************************/ #ifndef _ADC_H_ #define _ADC_H_ //按键状态 #define TOUCH_DOWN 0 #define TOUCH_UP 1 #define TOUCH_Posedge 0x01//笔抬起事件 #define TOUCH_Negedge 0x02//笔按下事件 //ADC采样模式 #define COMMON_AD_MODER 0 //普通的AD转换模式 #define ASUNDER_X_MODER 1 //分离的X采样模式 #define ASUNDER_Y_MODER 2 //分离的Y采样模式 #define AUTO_XY_MODER 3 //自动的X,Y采样模式//不知道为何不准,只能用分离的X,Y扫描模式 #define INT_AD_MODER 4 //等待中断的采样模式 #define STANDBY_AD_MODER 5 //掉电模式 //ADC通道选择 #define ADC_CH_AIN0 0 #define ADC_CH_AIN1 1 #define ADC_CH_AIN2 2 #define ADC_CH_AIN3 3 #define ADC_CH_YM 4 #define ADC_CH_YP 5 #define ADC_CH_XM 6 #define ADC_CH_XP 7 //读取转换寄存器0 #define ADC_ReadData0() (ADC->DAT0&0xfff) #define ADC_ReadData1() (ADC->DAT1&0xfff) //相关函数 void ADC_Init(void); //初始化ADC void SetADC_Channel(u8 ch); //ADC通道选择 void ADC_SetMode(u8 Mode); //ADC工作模式设置 u8 Get_TouchState(void); //获取触摸笔状态 u16 ADC_ReadX(void); //读取X坐标 u16 ADC_ReadY(void); //读取Y坐标 //使能笔抬起中断 __inline void ADCTSC_UD_SEN (u8 EN) { ADC->TSC &= ~BIT8; //笔向下中断 if(EN == ENABLE) ADC->TSC |= BIT8; } //YM接GMD无效,接HZ __inline void ADCTSC_YM_HZ(void) { ADC->TSC &= ~BIT7; } //YM接GMD有效,接GND __inline void ADCTSC_YM_GND(void) { ADC->TSC |= BIT7; } //YP接VDD无效,接HZ __inline void ADCTSC_YP_HZ(void) { ADC->TSC |= BIT6; } //YP接VDD有效,接VDDA __inline void ADCTSC_YP_VDD(void) { ADC->TSC &= ~BIT6; } //XM接GMD无效,接HZ __inline void ADCTSC_XM_HZ(void) { ADC->TSC &= ~BIT5; } //XM接GMD有效,接GND __inline void ADCTSC_XM_GND(void) { ADC->TSC |= BIT5; } //XP接VDD无效,接HZ __inline void ADCTSC_XP_HZ(void) { ADC->TSC |= BIT4; } //XP接VDD有效,接VDDA __inline void ADCTSC_XP_VDD(void) { ADC->TSC &= ~BIT4; } //正常ADC转换模式 __inline void Normal_ADC_Mode(void) { ADC->TSC &= ~BIT2; //正常的ADC转换 } //待机模式 __inline void StandbyMode(void) { ADC->CON |= BIT2; } //自动X,Y转换 __inline void AUTO_XYPosition(void) { ADC->TSC &= ~(BIT0+BIT1); ADC->TSC |= BIT2; //自动X,Y转换 } //X,Y手动测量模式,没有运行模式 __inline void NO_OpeMode(void) { ADC->TSC &= ~(BIT0+BIT1); } //X,Y手动测量模式,X坐标转换模式 __inline void X_PosMode(void) { NO_OpeMode(); //清除设置 ADC->TSC |= 1; } //X,Y手动测量模式,Y坐标转换模式 __inline void Y_PosMode(void) { NO_OpeMode(); //清除设置 ADC->TSC |= 2; } //X,Y手动测量模式,等待中断模式 __inline void INT_WaitingMode(void) { NO_OpeMode(); //清除设置 ADC->TSC |= 3; } //XP上拉启动 __inline void XP_UP_ENABLE(void) { ADC->TSC &= ~BIT3; } //XP上拉禁止 __inline void XP_UP_DISABLE(void) { ADC->TSC |= BIT3; } //清除ADC唤醒中断 __inline void ADC_ClearInt(void) { ADC->CLRINT = 0xffffffff; //写入任何值清除中断标志 } //清除触摸屏中断中断 __inline void TOUCH_ClearInt(void) { ADC->UPDN = 0; //清除ADC的触摸屏UP-DOWN寄存器 ADC->CLRINTPNDNUP = 0xffffffff; //写入任何值清除中断标志 } //开始一次ADC转换 __inline void ADC_Start(void) { ADC->CON |= BIT0; //开始ADC转换 } //等待ADC转换完成 __inline void ADC_Wait(void) { while(!(ADC->CON & BIT15)); } #endif
/************************************************************************************************************* * 文件名: Touch.c * 功能: S3C6410 电阻触摸屏驱动 * 作者: [email protected] * 创建时间: 2012年10月6日17:31 * 最后修改时间:2012年10月6日 * 详细: 需要底层的ADC支持 *************************************************************************************************************/ #include "system.h" #include "adc.h" #include "touch.h" Pen_Holder Pen_Point;//定义笔实体 //开启触摸屏校准,需要其它支持 #define _TOUCH_ADJUST 1 #if _TOUCH_ADJUST void TOUCH_Adjust(void); //触摸屏校准 #endif //_TOUCH_ADJUST /************************************************************************************************************************* *函数 : void TOUCH_Init(FunctionalState EnableInt) *功能 : 触摸屏初始始化 *参数 : EnableInt:笔中断使能 *返回 : 无 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 20120313 *最后修改时间: 20121006 *说明 : 触摸屏初始始化 *************************************************************************************************************************/ void TOUCH_Init(FunctionalState EnableInt) { ADC_Init(); //初始化ADC TOUCH_ClearInt(); //清除触摸屏中断标志 ADC_ClearInt(); //清除ADC中断 ADC_SetMode(INT_AD_MODER); //等待中断模式 ADCTSC_UD_SEN(DISABLE); //设置为按下中断 if(EnableInt == ENABLE) //开启笔中断 { //Set_IsrAddr(INT_PENDNUP,(u32)Isr_Touch); //设置中断矢量入口 //Set_IntEnable(INT_PENDNUP,ENABLE); //开启触摸屏按下 } #if _TOUCH_ADJUST TOUCH_Adjust(); //触摸屏校准 #endif //_TOUCH_ADJUST } /************************************************************************************************************************* * 函数 : u16 ADS_Read_XY(u16(*ADC_ReadXY)(void)) * 功能 : 使用冒泡法读取一次坐标 * 参数 : ADC_ReadXY:X或Y坐标读取函数 * 返回 : 转换结果 * 依赖 : ADC * 作者 : [email protected] * 时间 : 20121006 * 最后修改时间 : 20121006 * 说明 : 连续读取READ_TIMES次数据,对这些数据升序排列, 然后去掉最低和最高LOST_VAL个数,取平均值 *************************************************************************************************************************/ #define READ_TIMES 15 //读取次数 #define LOST_VAL 5 //丢弃值 u16 ADS_Read_XY(u16(*ADC_ReadXY)(void)) { u16 i, j; u16 buff[READ_TIMES]; u16 sum=0; u16 temp; for(i = 0;i < READ_TIMES;i ++) { buff[i] = ADC_ReadXY(); } for(i = 0;i < READ_TIMES - 1;i ++)//排序 { for(j = i + 1;j < READ_TIMES;j ++) { if(buff[i] > buff[j])//升序排列 { temp = buff[i]; buff[i] = buff[j]; buff[j] = temp; } } } sum = 0; for(i = LOST_VAL;i < READ_TIMES - LOST_VAL;i ++) sum += buff[i]; temp = sum / (READ_TIMES - 2 * LOST_VAL); return temp; } /************************************************************************************************************************* * 函数 : u8 Read_ADS(u16 *x,u16 *y) * 功能 : 带滤波的读取X,Y坐标 * 参数 : X,Y坐标值缓冲区指针 * 返回 : 1:转换结果有效;0:转换结果无效 * 依赖 : XPT2046底层函数 * 作者 : [email protected] * 时间 : 20120914 * 最后修改时间 : 20120914 * 说明 : 带滤波的坐标读取 最小值不能少于MINI_ADC_DATA. *************************************************************************************************************************/ #define MINI_ADC_DATA 100 u8 Read_ADS(u16 *x,u16 *y) { u16 xtemp, ytemp; ADC_SetMode(ASUNDER_X_MODER); //设置ADC为分离的X采样模式 xtemp = ADS_Read_XY(ADC_ReadX); //读取X坐标 ADC_SetMode(ASUNDER_Y_MODER); //设置ADC为分离的Y采样模式 ytemp = ADS_Read_XY(ADC_ReadY); //读取Y坐标 ADC_SetMode(INT_AD_MODER); //设置ADC为等待中断模式 if(xtemp < MINI_ADC_DATA || ytemp < MINI_ADC_DATA) return 0;//读数失败 *x = xtemp; *y = ytemp; return 1;//读数成功 } /************************************************************************************************************************* * 函数 : u8 Read_ADS2(u16 *x,u16 *y) * 功能 : 连续读取2次有效的AD值 * 参数 : X,Y坐标值缓冲区指针 * 返回 : 1:转换结果有效;0:转换结果无效 * 依赖 : u8 Read_ADS(u16 *x,u16 *y) * 作者 : [email protected] * 时间 : 20120914 * 最后修改时间 : 20120914 * 说明 : 连续读取2次有效的AD值,且这两次的偏差不能超过ERR_RANGE 满足条件,则认为读数正确,否则读数错误. 该函数能大大提高准确度 *************************************************************************************************************************/ #define ERR_RANGE 50 //误差范围 u8 Read_ADS2(u16 *x,u16 *y) { u16 x1,y1; u16 x2,y2; u8 flag; flag = Read_ADS(&x1,&y1); if(flag == 0) return(0); flag = Read_ADS(&x2,&y2); if(flag == 0) return(0); if(((x2 <= x1 && x1 < x2 + ERR_RANGE) || (x1 <= x2 && x2 < x1 + ERR_RANGE)) && ((y2 <= y1 && y1 < y2 + ERR_RANGE) || (y1 <= y2 && y2 < y1 + ERR_RANGE))) //前后两次采样在+-ERR_RANGE内 { *x = (x1 + x2) / 2; *y = (y1 + y2) / 2; return 1; } else return 0; } /************************************************************************************************************************* * 函数 : u8 TOUCH_ReadOneTP(void) * 功能 : 读取一次原始坐标 * 参数 : 无 * 返回 : 1:转换结果有效;0:转换结果无效 * 依赖 : u8 Read_ADS2(u16 *x,u16 *y) * 作者 : [email protected] * 时间 : 20120914 * 最后修改时间 : 20120914 * 说明 : 调用Read_ADS2函数进行读取,如果Read_ADS2读取失败,重复读取,最多读取MAX_READ_ADS次 如果失败,将返回0,注意返回1代表结果有效 转换的结果存放在结构体Pen_Holder,的x0,y0中 *************************************************************************************************************************/ #define MAX_READ_ADS 5 //最大重试次数 u8 TOUCH_ReadOneTP(void) { u8 i; u16 x,y; for(i = MAX_READ_ADS;i != 0;i --) { if(Read_ADS2(&x,&y)) { Pen_Point.x0 = x; //转换有效,存储结果 Pen_Point.y0 = y; return 1; //返回成功 } } return 0; //返回失败 } /************************************************************************************************************************* * 函数 : void TOUCH_ConvertPos(void) * 功能 : 采集并转换触摸坐标 * 参数 : 无 * 返回 : 无 * 依赖 : LCD.C,触摸屏ADC底层 * 作者 : [email protected] * 时间 : 20120914 * 最后修改时间 : 20121006 * 说明 : 根据触摸屏的校准参数来决定转换后的结果,保存在x,y中 * 需要先进行触摸校准 *************************************************************************************************************************/ void TOUCH_ConvertPos(void) { if(TOUCH_ReadOneTP()) { Pen_Point.x = Pen_Point.xfac * Pen_Point.x0 + Pen_Point.xoff; Pen_Point.y = Pen_Point.yfac * Pen_Point.y0 + Pen_Point.yoff; } } //触摸屏校准相关 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// #if _TOUCH_ADJUST #include "TFT_LCD.h" #include "stdlib.h" #include "math.h" #include "delay.h" /************************************************************************************************************************* * 函数 : void Drow_Touch_Point(u16 x,u16 y) * 功能 : 画一个触摸点,用于校准 * 参数 : x,y:触摸点中心位置 * 返回 : 无 * 依赖 : LCD.C * 作者 : [email protected] * 时间 : 20120914 * 最后修改时间 : 20120914 * 说明 : 会调用LCD.C中的画圆,画线,画矩形等函数 *************************************************************************************************************************/ void Drow_Touch_Point(u16 x,u16 y) { Draw_Circle(x,y,10,0xf0f0);//画圆 Draw_Circle(x,y,3,0xf0f0);//画圆 LCD_DrawLine(x - 15, y, x + 15, y,0xf0f0);//画线 LCD_DrawLine(x, y - 15, x, y + 15,0xf0f0);//画线 LCD_DrawRectangle(x - 10,y - 10,x + 10,y + 10,0xf0f0);//画矩形 } /************************************************************************************************************************* * 函数 : void TOUCH_Adjust(void) * 功能 : 进行触摸屏校准 * 参数 : 无 * 返回 : 无 * 依赖 : LCD.C,触摸屏ADC底层 * 作者 : [email protected] * 时间 : 20120914 * 最后修改时间 : 20120914 * 说明 : 得到四个校准值 * (20,20) (LCD_XSIZE-20,20) * * * (20,LCD_YSIZE-20) (LCD_XSIZE-20,LCD_YSIZE-20) *************************************************************************************************************************/ void TOUCH_Adjust(void) { u16 pos_temp[4][2];//坐标缓存值 u8 cnt=0; u16 d1,d2; u32 tem1,tem2; float fac; cnt=0; LCD_ClearScreen(0xffff);//清屏 Drow_Touch_Point(20,20);//画点1 //Pen_Point.xfac=0;//xfac用来标记是否校准过,所以校准之前必须清掉!以免错误 while(1) { if(GetPenStartus() == TOUCH_DOWN)//按键按下了 { if(TOUCH_ReadOneTP())//得到单次按键值 { pos_temp[cnt][0]=Pen_Point.x0; pos_temp[cnt][1]=Pen_Point.y0; cnt++; } while(GetPenStartus() == TOUCH_DOWN); //等待按键抬起 switch(cnt) { case 1: LCD_ClearScreen(0xffff);//清屏 Drow_Touch_Point(LCD_XSIZE-20,20);//画点2 break; case 2: LCD_ClearScreen(0xffff);//清屏 Drow_Touch_Point(20,LCD_YSIZE-20);//画点3 break; case 3: LCD_ClearScreen(0xffff);//清屏 Drow_Touch_Point(LCD_XSIZE-20,LCD_YSIZE-20);//画点4 break; case 4: //全部四个点已经得到 //对边相等 tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2 tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2 tem1*=tem1; tem2*=tem2; d1=sqrt(tem1+tem2);//得到1,2的距离 tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4 tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4 tem1*=tem1; tem2*=tem2; d2=sqrt(tem1+tem2);//得到3,4的距离 fac=(float)d1/d2; if(fac<0.95||fac>1.05||d1==0||d2==0)//不合格 { cnt=0; LCD_ClearScreen(0xffff);//清屏 Drow_Touch_Point(20,20); continue; } tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3 tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3 tem1*=tem1; tem2*=tem2; d1=sqrt(tem1+tem2);//得到1,3的距离 tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4 tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4 tem1*=tem1; tem2*=tem2; d2=sqrt(tem1+tem2);//得到2,4的距离 fac=(float)d1/d2; if(fac<0.95||fac>1.05)//不合格 { cnt=0; LCD_ClearScreen(0xffff);//清屏 Drow_Touch_Point(20,20); continue; }//正确了 //对角线相等 tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3 tem2=abs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3 tem1*=tem1; tem2*=tem2; d1=sqrt(tem1+tem2);//得到1,4的距离 tem1=abs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4 tem2=abs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4 tem1*=tem1; tem2*=tem2; d2=sqrt(tem1+tem2);//得到2,3的距离 fac=(float)d1/d2; if(fac<0.95||fac>1.05)//不合格 { cnt=0; LCD_ClearScreen(0xffff);//清屏 Drow_Touch_Point(20,20); continue; }//正确了 //计算结果 Pen_Point.xfac=(float)(LCD_XSIZE-40)/(pos_temp[1][0]-pos_temp[0][0]);//得到xfac Pen_Point.xoff=(LCD_XSIZE-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;//得到xoff Pen_Point.yfac=(float)(LCD_YSIZE-40)/(pos_temp[2][1]-pos_temp[0][1]);//得到yfac Pen_Point.yoff=(LCD_YSIZE-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到yoff //Wire_Touch(); //存储校准结果 LCD_ClearScreen(0xffff);//清屏 Show_Char(35,LCD_YSIZE/2,"Touch Screen Adjust OK!",0xf800,0xffff,0x80); Delay_MS(1000); LCD_ClearScreen(0xffff);//清屏 return;//校正完成 } } } } #endif //_TOUCH_ADJUST ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/************************************************************************************************************* * 文件名: Touch.h * 功能: S3C6410 电阻触摸屏驱动 * 作者: [email protected] * 创建时间: 2012年10月6日17:31 * 最后修改时间:2012年10月6日 * 详细: 需要底层的ADC支持 *************************************************************************************************************/ #ifndef TOUCH_H_ #define TOUCH_H_ #include "adc.h" #ifndef TOUCH_DOWN #define TOUCH_DOWN 0 #endif //TOUCH_DOWN #ifndef TOUCH_UP #define TOUCH_UP 1 #endif //TOUCH_UP //笔杆结构体 typedef struct { u16 x0;//原始坐标 u16 y0; u16 x; //最终/暂存坐标 u16 y; u8 Touch_Sta;//笔的状态 //触摸屏校准参数 float xfac; float yfac; short xoff; short yoff; }Pen_Holder; extern Pen_Holder Pen_Point;//定义一个笔杆的结构变量 void TOUCH_Init(FunctionalState EnableInt); //触摸屏初始化函数 u8 TOUCH_ReadOneTP(void); //读取一次坐标 #define GetPenStartus() Get_TouchState() //获取触摸笔状态 void TOUCH_ConvertPos(void); //获取转换后的实际坐标 #endif /*TOUCH_H_*/
main.c
#include "system.h" #include "uart.h" #include "tft_lcd.h" #include "other.h" #include "delay.h" #include "timer.h" #include "touch.h" //LED1闪烁程序,在定时器0中断服务程序中闪烁,周期400MS void LED1_flash(void) { LED1_FLASH(); } int main(void) { LCD_Init(); //初始化LCD UART0_Init(DISABLE,115200); //初始化串口,失能中断接收,波特率115200 LED_Init(); //初始化LED Timer1_Init(400000-1,ENABLE,LED1_flash); //初始化定时器0,周期400ms TOUCH_Init(DISABLE); //初始化触摸屏 lcd_printf("Get_FCLK : %d Hz\n",Get_FCLK()); lcd_printf("Get_PCLK : %d Hz\n",Get_PCLK()); while(1) { //LED2_FLASH(); //LED2闪烁 //Delay_US(600000); if(GetPenStartus() == TOUCH_DOWN) //笔按下 { TOUCH_ConvertPos(); //lcd_printf("X:%d; Y:%d\n",Pen_Point.x,Pen_Point.y); Draw_Big_Point(Pen_Point.x,Pen_Point.y,0xf800); Delay_MS(1); } } }
//补充ADC相关寄存器结构
#define ADC_BASE 0x7E00B000 //ADC 寄存器 typedef struct { vu32 CON; //ADC控制寄存器 vu32 TSC; //触摸屏控制寄存器 vu32 DLY; //ADC开始延迟寄存器 vu32 DAT0; //ADC数据寄存器0 vu32 DAT1; //ADC数据寄存器1 vu32 UPDN; //触摸屏UP-DOWN寄存器 vu32 CLRINT; //ADC中断清除寄存器 u32 Reserved; vu32 CLRINTPNDNUP; //触摸屏笔中断寄存器 }ADC_TypeDef; #define ADC ((ADC_TypeDef*)ADC_BASE)