使用的是RVDS4.0编译的
大家主要是看看如何配置模式的
我之前一直使用自动X,Y采样,但是读取的都不准,最后采样分离的,才可以,需要注意的是使能ADC读开始后需要先读转换结果寄存器,但是此时读取的是上一次的转换结果,如果是连续读取需要等待转换完成,否则转换结果不准.
adc.c
/*************************************************************************************************************
* 文件名: ADC.c
* 功能: S3C6410 ADC底层驱动函数
* 作者: cp1300@139.com
* 创建时间: 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
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20120513
*最后修改时间: 20120513
*说明 : ADC输入通道选择
*************************************************************************************************************************/
void SetADC_Channel(u8 ch)
{
ADC->CON &= ~(7 << 3); //清除通道
ADC->CON |= ch & (0x07); //设置通道号
}
/*************************************************************************************************************************
*函数 : void ADC_Init(void)
*功能 : ADC初始始化
*参数 : 无
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 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模式
*参数 : 无
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 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坐标原始坐标值
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20121006
*最后修改时间: 20121006
*说明 : 读取的是ADC转换寄存器0
* 需要先设置ADC模式
*************************************************************************************************************************/
u16 ADC_ReadX(void)
{
ADC_Start(); //开始一次ADC转换
ADC_Wait(); //等待转换完成
return ADC_ReadData0();
}
/*************************************************************************************************************************
*函数 : u16 ADC_ReadY(void)
*功能 : 读取Y坐标
*参数 : 无
*返回 : Y坐标原始坐标值
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 20121006
*最后修改时间: 20121006
*说明 : 读取的是ADC转换寄存器1
* 需要先设置ADC模式
*************************************************************************************************************************/
u16 ADC_ReadY(void)
{
ADC_Start(); //开始一次ADC转换
ADC_Wait(); //等待转换完成
return ADC_ReadData1();
}
/*************************************************************************************************************************
*函数 : u8 Get_TouchState(void)
*功能 : 获取触摸状态
*参数 : 无
*返回 : 1:笔抬起;0:笔按下
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 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
/*************************************************************************************************************
* 文件名: 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
/*************************************************************************************************************
* 文件名: Touch.c
* 功能: S3C6410 电阻触摸屏驱动
* 作者: cp1300@139.com
* 创建时间: 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:笔中断使能
*返回 : 无
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 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
* 作者 : cp1300@139.com
* 时间 : 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底层函数
* 作者 : cp1300@139.com
* 时间 : 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)
* 作者 : cp1300@139.com
* 时间 : 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)
* 作者 : cp1300@139.com
* 时间 : 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底层
* 作者 : cp1300@139.com
* 时间 : 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
* 作者 : cp1300@139.com
* 时间 : 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底层
* 作者 : cp1300@139.com
* 时间 : 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
/*************************************************************************************************************
* 文件名: Touch.h
* 功能: S3C6410 电阻触摸屏驱动
* 作者: cp1300@139.com
* 创建时间: 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)
上一篇:OK6410开发板裸机DS18B20驱动
下一篇:OK6410裸机简单的NAND FLASH驱动
- 热门资源推荐
- 热门放大器推荐
设计资源 培训 开发板 精华推荐
- Allegro MicroSystems 在 2024 年德国慕尼黑电子展上推出先进的磁性和电感式位置感测解决方案
- 左手车钥匙,右手活体检测雷达,UWB上车势在必行!
- 狂飙十年,国产CIS挤上牌桌
- 神盾短刀电池+雷神EM-i超级电混,吉利新能源甩出了两张“王炸”
- 浅谈功能安全之故障(fault),错误(error),失效(failure)
- 智能汽车2.0周期,这几大核心产业链迎来重大机会!
- 美日研发新型电池,宁德时代面临挑战?中国新能源电池产业如何应对?
- Rambus推出业界首款HBM 4控制器IP:背后有哪些技术细节?
- 村田推出高精度汽车用6轴惯性传感器
- 福特获得预充电报警专利 有助于节约成本和应对紧急情况