📄 touch2410.c
字号:
/*
;************************************************************************************************************
;* 北京精仪达盛科技有限公司
;* 研 发 部
;*
;* http://www.techshine.com
;*
;*--------------------------------------------- 文件信息 ----------------------------------------------------
;*
;* 文件名称 : Touch2410.c
;* 文件功能 : 该文件为S3C2410硬件平台的触摸屏程序驱动程序
;* 补充说明 :
;*-------------------------------------------- 最新版本信息 -------------------------------------------------
;* 修改作者 : ARM开发小组
;* 修改日期 : 2004/04/25
;* 版本声明 : V1.0.1
;*-------------------------------------------- 历史版本信息 -------------------------------------------------
;* 文件作者 : ARM开发小组
;* 创建日期 : 2004/04/20
;* 版本声明 : v1.0.0
;*-----------------------------------------------------------------------------------------------------------
;*-----------------------------------------------------------------------------------------------------------
;************************************************************************************************************
;*/
#include "..\inc\touch2410.h"
#include "2410addr.h"
#include "..\..\Startup2410\INC\2410lib.h"
#include "LCDdriver.h"
static int TOUCH_X = 0;
static int TOUCH_Y = 0;
#define isDebug 0 //如果此值是1,可以串口输出信息,此值是0,不输出信息
const int ADCount = 20;
int ArrayDat0[ADCount];
#define avaverage 0
#define optimize 1
#define method avaverage
/*
***********************************************************************************************************
*
* ----***-- 配置宏 --***-----
*
***********************************************************************************************************
*/
#ifndef GUI_TOUCH_AD_LEFT // 由AD转换器返回的320X240屏的最左面的值
//#define GUI_TOUCH_AD_LEFT 610
#define GUI_TOUCH_AD_LEFT 40
#endif
#ifndef GUI_TOUCH_AD_RIGHT // 由AD转换器返回的320X240屏的最右面的值
#define GUI_TOUCH_AD_RIGHT 980
#endif
#ifndef GUI_TOUCH_AD_TOP // 由AD转换器返回的320X240屏的最上面的值
//#define GUI_TOUCH_AD_TOP 710
#define GUI_TOUCH_AD_TOP 102
#endif
#ifndef GUI_TOUCH_AD_BOTTOM // 由AD转换器返回的320X240屏的最下面的值
//#define GUI_TOUCH_AD_BOTTOM 360
#define GUI_TOUCH_AD_BOTTOM 942
#endif
#ifndef GUI_TOUCH_XSIZE
#define GUI_TOUCH_XSIZE 320
#endif
#ifndef GUI_TOUCH_YSIZE
#define GUI_TOUCH_YSIZE 240
#endif
/*
*************************************************************************************************************
- 函数名称: void Touch_Show(int x, int y)
- 函数功能:触摸屏触点显示函数
- 输入参数:x:横坐标,y:纵坐标
- 输出参数:无
*************************************************************************************************************
*/
void Touch_Show(int x, int y)
{
Uart_Printf("量化后的结果:x = %d, y = %d\n\n",x,y);
Fill_Circle (x, y, 1);
}
/*
*************************************************************************************************************
- 函数名称: void Touch_Init(void)
- 函数功能:初始化触摸屏控制器
- 输入参数:无
- 输出参数:无
*************************************************************************************************************
*/
void Touch_Init(void)
{
rADCDLY = (0x5000); // ADC Start or Interval Delay
rADCTSC = (0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3); //设置成为等待中断模式
//rADCTSC = (0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(1<<3)|(0<<2)|(3); //设置成为等待中断模式,disable int
rADCCON = (1<<14)|(49<<6)|(7<<3)|(0<<2)|(1<<1)|(0); //设置ADC控制寄存器
}
/*
*************************************************************************************************************
- 函数名称:void TouchINT_Init(void)
- 函数功能:触摸屏中断初始化
- 输入参数:无
- 输出参数:无
*************************************************************************************************************
*/
void TouchINT_Init(void) //触摸屏硬件接口使能
{
if ((rSRCPND & BIT_ADC)){ //清除中断挂起位
rSRCPND |= BIT_ADC;
}
if ((rINTPND & BIT_ADC)){
rINTPND |= BIT_ADC;
}
if ((rSUBSRCPND & BIT_SUB_TC)){
rSUBSRCPND |= BIT_SUB_TC;
}
if ((rSUBSRCPND & BIT_SUB_ADC)){
rSUBSRCPND |= BIT_SUB_ADC;
}
rINTMSK &= ~(BIT_ADC); //相关中断屏蔽位置0,使能中断
rINTSUBMSK &= ~(BIT_SUB_TC);
pISR_ADC = (unsigned)Touch_ISR; //设置中断向量
}
/*
*************************************************************************************************************
- 函数名称: void __irq Touch(void)
- 函数功能:触摸屏中断
- 输入参数:无
- 输出参数:无
*************************************************************************************************************
*/
void __irq Touch_ISR(void){
int AD_XY,yPhys,xPhys;
//关中断
rINTMSK |= (BIT_ADC);
rINTSUBMSK |= (BIT_SUB_ADC | BIT_SUB_TC); // 关闭子中断(ADC和TC)
//获取位置
AD_XY = GetTouch_XY_AD();
yPhys = (AD_XY) & 0xffff; //获取Y的AD值
xPhys = (AD_XY >> 16) & 0xffff;//获取X的AD值
TOUCH_X = AD2X(xPhys);
TOUCH_Y = AD2Y(yPhys);
//
Touch_Show(TOUCH_X,TOUCH_Y);
//开中断,清空挂起位
rSUBSRCPND |= BIT_SUB_TC;
ClearPending(BIT_ADC);
rINTMSK &= ~(BIT_ADC);
rINTSUBMSK &= ~(BIT_SUB_ADC);
rINTSUBMSK &= ~(BIT_SUB_TC);
}
/*
*************************************************************************************************************
- 函数名称: void selectsort(int* r,int n)
- 函数功能:选择排序
- 输入参数:r[] is struct rec,n是要排序记录的个数
- 输出参数:无
*************************************************************************************************************
*/
void selectsort(int* r,int n){ //r[] is struct rec,选择排序
int i,j,k;
int w;//struct rec
for(i = 0; i < n - 1; i ++){
k = i;
for (j = i + 1; j < n; j ++){
if (r[j] < r[k])
k = j;
}
if (k != i){
w=r[i];//交换
r[i]=r[k];
r[k]=w;
}
}
#if (isDebug == 1)
Uart_Printf("Sort::");
for (i = 0; i < n; i++)
Uart_Printf("%d, ", r[i]);
Uart_Printf(" end\n");
#endif
}
/*
*************************************************************************************************************
- 函数名称: int GetDat0(int* p)
- 函数功能:将采集到的数据进行处理,去除不稳定的抖动值,得到准确的AD转换值
- 输入参数:采集到的数据的指针
- 输出参数:准确的AD转换值
*************************************************************************************************************
*/
int GetDat0(int* p){
int Dat0;
//const int ADCount = 10;
int tmp[19];//ADCount - 1
int i, k, diftag = 0;
struct ARRAYCMP{
int difsize;
int continuecount;
}ArrayCmp[19];//ADCount - 1
#if (method == avaverage) //将采集的点数据平均处理
Dat0 = 0;
for(i = 0; i < ADCount; i ++){
Dat0 += p[i]; //转换结果累加,最后取平均
}
Dat0 /= ADCount;
#elif (method == optimize) //取最优点,即选取各点之间差别最小且连续个数最多的点,这是最稳定值
selectsort(p, ADCount); //将采集到的数据排序(由小到大)
for (i = 0; i < ADCount - 1; i ++){
tmp[i] = p[i + 1] - p[i]; //tmp[]存储各点之间的差值
}
#if (isDebug == 1)
Uart_Printf("tmp:\n ");
for (i = 0; i < ADCount - 1; i++){
Uart_Printf("%d,",tmp[i]);
}
Uart_Printf("\n");
#endif
//fill table
//ArrayCmp是一个表格,表格的第一列存储各点之间的差值,
//第二列存储相同的点连续存放的个数
/* 举例:
tmp[] : 2,0,0,0,2,0,0,2,2
ArrayCmp[]如下:
下标 差值 连续个数
0 2 0
1 0 2
2 0 -2
3 0 -1
4 2 0
5 0 1
6 0 -2
7 2 1
*/
ArrayCmp[0].difsize = tmp[0];
ArrayCmp[0].continuecount = 0;
k = 0;
for(i = 1; i < ADCount - 1; i++){
if ((tmp[i] == tmp[i - 1]) && (diftag == 0)){
ArrayCmp[i].difsize = tmp[i];
ArrayCmp[i].continuecount = -2;
ArrayCmp[i - 1].continuecount = 1;
diftag = 1;
k = i - 1;
}else if ((tmp[i] == tmp[i - 1]) && (diftag == 1)){
ArrayCmp[i].difsize = tmp[i];
ArrayCmp[i].continuecount = -1;
ArrayCmp[k].continuecount += 1;
diftag = 1;
}else{ //(tmp[i] != tmp[i - 1])
ArrayCmp[i].difsize = tmp[i];
ArrayCmp[i].continuecount = 0;
diftag = 0;
}
}
#if (isDebug == 1)
Uart_Printf("ArrayCmp:\n ");
for (i = 0; i < ADCount - 1; i++){
Uart_Printf("%d, %d, %d\n",i, ArrayCmp[i].difsize, ArrayCmp[i].continuecount);
}
Uart_Printf("\n");
#endif
//scan table
//扫描ArrayCmp[]中差值最小且连续个数最多的点的下标
k = 0;
for (i = 1; i < ADCount - 1; i++){
if (ArrayCmp[i].difsize < ArrayCmp[k].difsize)
k = i;
else if (ArrayCmp[i].difsize == ArrayCmp[k].difsize){
if (ArrayCmp[i].continuecount >= ArrayCmp[k].continuecount)
k = i;
}
}
Dat0 = p[k];
#endif
return Dat0;
}
/*
***********************************************************************************************************
* 函数名称: GetTouch_XY_AD(void)
*
* 函数功能: 写给触摸屏控制器控制字,把触摸屏控制器转换的AD值放到接收变量AD_XY中
*
* 输入参数: 无
*
* 返回值 : AD_XY
***********************************************************************************************************
*/
unsigned int GetTouch_XY_AD(void)
{
int Dat0, i;
int* p;
//转换次数
unsigned int x, y; //存放转换结果
unsigned int AD_XY = 0; //存放最终XY的转换结果
p = ArrayDat0; //初始化累加变量
while ((rADCDAT0 & 0x8000) | (rADCDAT1 & 0x8000));//测试rADCDAT的bit15是否等于0(触笔按下状态)
//X,Y分别转换模式
rGPGUP = 0xffff; //设置GPIO,禁止GPG上拉
rADCTSC=(0<<8)|(0<<7)|(1<<6)|(1<<5)|(0<<4)|(1<<3)|(0<<2)|(1); //设置转换X的位置
//rADCTSC=(0<<8)|(1<<7)|(0<<6)|(0<<5)|(1<<4)|(1<<3)|(0<<2)|(1); //设置转换X的位置
for(i = 0; i < ADCount; i++){ //开始转换X,共ADCount次
rADCCON = (1<<14)|(49<<6)|(7<<3)|(0<<2)|(0<<1)|(1); //设置控制寄存器
while(rADCCON & 0x1); //测试转换开始位
while(!(0x8000 & rADCCON)); // 测试ECFLG位,转换是否结束
Delay(20);
ArrayDat0[i] = (rADCDAT0) & 0x3ff;
//Dat0 += (rADCDAT0) & 0x3ff; //转换结果累加,最后取平均
}
Dat0 = GetDat0(p);
if (Dat0 != 0)
{ //如果X有效,继续转换Y
x = Dat0;
#if (isDebug == 1)
for (i = 0; i < ADCount; i ++){
Uart_Printf("%d, ", ArrayDat0[i]);
}
Uart_Printf("\n");
#endif
rADCTSC=(0<<8)|(1<<7)|(0<<6)|(0<<5)|(1<<4)|(1<<3)|(0<<2)|(2); //设置转换Y的位置
//rADCTSC=(0<<8)|(0<<7)|(1<<6)|(1<<5)|(0<<4)|(1<<3)|(0<<2)|(2); //设置转换Y的位置
Delay(100);
for (i = 0; i < ADCount; i++){ //开始转换Y,共ADCount次
rADCCON = (1<<14)|(49<<6)|(5<<3)|(0<<2)|(0<<1)|(1); //设置控制寄存器
while(rADCCON & 0x1); //测试转换开始位
while(!(0x8000 & rADCCON)); // 测试ECFLG位,转换是否结束
Delay(20);
//Dat0 += (rADCDAT1) & 0x3ff; //转换结果累加,最后取平均
ArrayDat0[i] = (rADCDAT1) & 0x3ff;
}
Dat0 = GetDat0(p);
y = Dat0;
#if (isDebug == 1)
for (i = 0; i < ADCount; i ++){
Uart_Printf("%d, ",ArrayDat0[i]);
}
Uart_Printf("\n",ArrayDat0[i]);
#endif
}
rGPGUP = 0x00; //设置GPIO,使能GPG上拉
Uart_Printf("采样结果::x: %d, y: %d\n",x, y);
#if (isDebug == 1)
Uart_Printf("采样结果::x: %d, y: %d\n",x, y);
#endif
AD_XY = (x << 16) | y; //高16位存放X,低16位存放Y
//恢复等待中断模式
Touch_Init();
Delay(1000);
while (!((rADCDAT0 & 0x8000) & (rADCDAT1 & 0x8000))); //测试rADCDAT的bit15是否等于1(触笔抬起状态)
return AD_XY;
}
/*
***********************************************************************************************************
* 函数名称: AD2X(int adx)
* 函数功能: 把AD值转换成X坐标值
* 输入参数: adx
* 返回值 : X坐标值
***********************************************************************************************************
*/
int AD2X(int adx) // 把AD值转换成坐标值 x
{
return GUI_TOUCH_XSIZE * (GUI_TOUCH_AD_LEFT - adx) / (GUI_TOUCH_AD_LEFT - GUI_TOUCH_AD_RIGHT);
}
/*
***********************************************************************************************************
* 函数名称: AD2Y(int ady)
* 函数功能: 把AD值转换成Y坐标值
* 输入参数: ady
* 返回值 : Y坐标值
***********************************************************************************************************
*/
int AD2Y(int ady) // 把AD值转换成坐标值 y
{
return GUI_TOUCH_YSIZE * (GUI_TOUCH_AD_TOP - ady) / (GUI_TOUCH_AD_TOP - GUI_TOUCH_AD_BOTTOM);
}
/*
*************************************************************************************************************
*- 结束文件 -*
*************************************************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -