触摸屏的工作模式探寻 in search touchscreen inside
2007-07-01 22:50
501 查看
实验平台: 深圳Embest EduKit II
实验目的:找出电阻式触摸屏的工作方式,尤其是采点的工作模式
实验计划及结果:
1、利用示例程序实现从UART(串口)报告触摸点坐标的功能;
注意到,此时笔在触摸屏上移动时,串口并不报告点的坐标,而在最后笔离开触摸屏时会报告一次点的坐标。审视源代码中的touchscreen_init(),注释中提示:
rEXTINT = (rEXTINT & 0x7FFFFFF0) | 0x2; // falling edge trigger
2、利用示例程序实现在LCD上描绘曲线的功能(用折线迭代逼近的方式) ;
3、将两个模块整合起来,实现报告触摸点坐标和在LCD相应位置画点的功能,建立起实验原型;
此处,touchscreen_init() lcd_init()两个初始化过程不能连续行进,为此在lcd_init()后加入一条welcome()语句,相当于延时后再开始touchscreen的初始化可以成功启动touchscreen和lcd。
4、在实验原型上探寻如何实现触摸点的跟踪描绘。
根据SAMSUNG的芯片说明书S3C44B0X-datasheet中关于外部中断的说明
EXTINT (EXTERNAL INTERRUPT CONTROL REGISTER)
The 8 external interrupts can be requested by various signaling methods. The EXTINT register configures the
signaling method between the level trigger and edge trigger for the external interrupt request, and also configures the
signal polarity.
Register Address R/W Description Reset Value
EXTINT 0x01D20050 R/W External Interrupt control Register 0x000000
Table 8-10. External Interrupt Control Register (EXTINT)
EXTINT Bit Description
EINT7 [30:28] Setting the signaling method of the EINT7.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT6 [26:24] Setting the signaling method of the EINT6.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT5 [22:20] Setting the signaling method of the EINT5.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT4 [18:16] Setting the signaling method of the EINT4.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT3 [14:12] Setting the signaling method of the EINT3.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT2 [10:8] Setting the signaling method of the EINT2.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT1 [6:4] Setting the signaling method of the EINT1.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT0 [2:0] Setting the signaling method of the EINT0.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
NOTE: Because each external interrupt pin has a digital filter, the interrupt controller can recognize a request signal
that is longer than 3 clocks.
修改touchscreen_init() 如下:
void touchscreen_init(void)
...{
#ifndef S3CEV40
// TSPX(GPC1_Q4(-)) TSPY(GPC3_Q3(-)) TSMY(GPC0_Q2(-)) TSMX(GPC2_Q1(+))
// 1 1 0 1
rPCONC = (rPCONC & 0xffffff00) | 0x55;
rPUPC = (rPUPE & 0xfff0); // Pull up
rPDATC = (rPDATC & 0xfff0 ) | 0xe; // should be enabled
#else
// S3CEV40
// TSPX(GPE4_Q4(+)) TSPY(GPE5_Q3(-)) TSMY(GPE6_Q2(+)) TSMX(GPE7_Q1(-))
// 0 1 1 0
rPCONE = (rPCONE & 0x300ff) | 0x5500;
rPUPE = (rPUPE & 0xF);
rPDATE = 0xb8;
#endif
delay(100);
// set interrupt
#ifndef S3CEV40
rPUPG = (rPUPG & 0xFE) | 0x1;
pISR_EINT0=(int)touchscreen_int; // set interrupt handler
//rEXTINT = (rEXTINT & 0x7FFFFFF0) | 0x2; // falling edge trigger
rEXTINT = (rEXTINT & 0x7FFFFFF0) | 0x0; // both edge trigger
rI_ISPC |= BIT_EINT0; // clear pending_bit
rINTMSK =~(BIT_GLOBAL|BIT_EINT0);
#else
pISR_EINT2=(int)touchscreen_int; // set interrupt handler
rEXTINT = (rEXTINT & 0x7FFFF0FF) | 0x200; // falling edge trigger
rI_ISPC |= BIT_EINT2; // clear pending_bit
rINTMSK =~(BIT_GLOBAL|BIT_EINT2);
#endif
rCLKCON = (rCLKCON & 0x6FFF) | 0x1000; // enable clock
rADCPSR = 24; // A/D prescaler
}
另一方面,程序的主体功能在触摸屏的中断服务例程中直接实现:
void touchscreen_int(void)
...{
UINT32T unPointX[5], unPointY[6];
int i;
int X,Y;
static int cnt=0;
static int oldX,oldY;
#ifndef S3CEV40
// <X-Position Read>
// TSPX(GPC1_Q4(+)) TSPY(GPC3_Q3(-)) TSMY(GPC0_Q2(+)) TSMX(GPC2_Q1(-))
// 0 1 1 0
rPDATC = (rPDATC & 0xfff0 ) | 0x9;
rADCCON= 0x0014; // AIN5
#else
// TSPX(GPE4_Q4(+)) TSPY(GPE5_Q3(-)) TSMY(GPE6_Q2(+)) TSMX(GPE7_Q1(-))
// 0 1 1 0
rPDATE =0x68;
rADCCON=0x1<<2; // AIN1
#endif
delay(100); // delay to set up the next channel
for(i=0; i<5; i++)
...{
rADCCON |= 0x1; // Start X-position A/D conversion
while(rADCCON & 0x1 == 1); // Check if AD conversion starts
while((rADCCON & 0x40) == 0); // Check end of AD conversion
unPointX[i] = (0x3ff&rADCDAT);
}
// read X-position average value
unPosX = (unPointX[0]+unPointX[1]+unPointX[2]+unPointX[3]+unPointX[4])/5;
f_unPosX = unPosX;
#ifndef S3CEV40
// <Y-Position Read>
// TSPX(GPC1_Q4(-)) TSPY(GPC3_Q3(+)) TSMY(GPC0_Q2(-)) TSMX(GPC2_Q1(+))
// 1 0 0 1
rPDATC = (rPDATC & 0xfff0 ) | 0x6;
rADCCON= 0x001C; // AIN70
#else
// TSPX(GPE4_Q4(-)) TSPY(GPE5_Q3(+)) TSMY(GPE6_Q2(-)) TSMX(GPE7_Q1(+))
// 1 0 0 1
rPDATE =0x98;
rADCCON=0x0<<2; // AIN0
#endif
delay(100); // delay to set up the next channel
for(i=0; i<5; i++)
...{
rADCCON |= 0x1; // Start Y-position conversion
while(rADCCON & 0x1 == 1); // Check if AD conversion starts
while((rADCCON & 0x40) == 0); // Check end of AD conversion
unPointY[i] = (0x3ff&rADCDAT);
}
// read Y-position average value
unPosY = (unPointY[0]+unPointY[1]+unPointY[2]+unPointY[3]+unPointY[4])/5;
f_unPosY = unPosY;
#ifndef S3CEV40
rPDATC = (rPDATC & 0xfff0 ) | 0xe; // should be enabled
#else
rPDATE = 0xb8; // should be enabled
#endif
//delay(1000);
delay(100);
/**///////////////////////////////////////////////////////////////////////////////
if(ready)
...{ if(f_unPosX<f_unMaxX && f_unPosX>f_unMinX && f_unPosY<f_unMaxY && f_unPosY>f_unMinY)
...{
X = 320*(f_unPosX - f_unMinX)/(f_unMaxX - f_unMinX);
Y = 240-240*(f_unPosY - f_unMinY)/(f_unMaxY - f_unMinY);
uart_printf("%d : X=%04d, Y=%04d ", ++cnt, X, Y);
lcd_draw_line(oldX, oldY, X, Y, RED, 1);
oldX = X,oldY = Y;
}
}
f_unTouched = 1;
/**//////////////////////////////////////////////////////////////////////////
#ifndef S3CEV40
rI_ISPC |= BIT_EINT0; // clear pending_bit
#else
rI_ISPC |= BIT_EINT2; // clear pending_bit
#endif
}
实验总结:电阻式触摸屏连续地将感受到的触摸点以模拟电压的方式输入到ARM7的ADC模块,而ADC模块又在ARM7的时钟配合下将模拟信号转换为串行的数字信号输出,同时以中断方式通知CPU。中断触发的方式定义了5种:高电平触发、低电平触发、上跳沿触发、下跳沿触发和双边沿触发。示例里面采用的是功能最简单的下跳沿触发方式,可以在触摸笔接触和离开触摸屏的两个时刻触发中断;而要实现连续采点以便在LCD上跟踪触摸笔的位置画点,可以采用双边沿触发方式(both edge trigger)。
在实验过程中仍然很容易出现采集的点的值越出最初进行触摸屏校正时得到的边界值,估计是触摸屏本身硬件的问题,点的输出值与触摸点的电压变化不是线性关系所致。
实验目的:找出电阻式触摸屏的工作方式,尤其是采点的工作模式
实验计划及结果:
1、利用示例程序实现从UART(串口)报告触摸点坐标的功能;
注意到,此时笔在触摸屏上移动时,串口并不报告点的坐标,而在最后笔离开触摸屏时会报告一次点的坐标。审视源代码中的touchscreen_init(),注释中提示:
rEXTINT = (rEXTINT & 0x7FFFFFF0) | 0x2; // falling edge trigger
2、利用示例程序实现在LCD上描绘曲线的功能(用折线迭代逼近的方式) ;
3、将两个模块整合起来,实现报告触摸点坐标和在LCD相应位置画点的功能,建立起实验原型;
此处,touchscreen_init() lcd_init()两个初始化过程不能连续行进,为此在lcd_init()后加入一条welcome()语句,相当于延时后再开始touchscreen的初始化可以成功启动touchscreen和lcd。
4、在实验原型上探寻如何实现触摸点的跟踪描绘。
根据SAMSUNG的芯片说明书S3C44B0X-datasheet中关于外部中断的说明
EXTINT (EXTERNAL INTERRUPT CONTROL REGISTER)
The 8 external interrupts can be requested by various signaling methods. The EXTINT register configures the
signaling method between the level trigger and edge trigger for the external interrupt request, and also configures the
signal polarity.
Register Address R/W Description Reset Value
EXTINT 0x01D20050 R/W External Interrupt control Register 0x000000
Table 8-10. External Interrupt Control Register (EXTINT)
EXTINT Bit Description
EINT7 [30:28] Setting the signaling method of the EINT7.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT6 [26:24] Setting the signaling method of the EINT6.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT5 [22:20] Setting the signaling method of the EINT5.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT4 [18:16] Setting the signaling method of the EINT4.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT3 [14:12] Setting the signaling method of the EINT3.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT2 [10:8] Setting the signaling method of the EINT2.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT1 [6:4] Setting the signaling method of the EINT1.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
EINT0 [2:0] Setting the signaling method of the EINT0.
000 = Low level interrupt 001 = High level interrupt
01x = Falling edge triggered 10x = Rising edge triggered
11x = Both edge triggered
NOTE: Because each external interrupt pin has a digital filter, the interrupt controller can recognize a request signal
that is longer than 3 clocks.
修改touchscreen_init() 如下:
void touchscreen_init(void)
...{
#ifndef S3CEV40
// TSPX(GPC1_Q4(-)) TSPY(GPC3_Q3(-)) TSMY(GPC0_Q2(-)) TSMX(GPC2_Q1(+))
// 1 1 0 1
rPCONC = (rPCONC & 0xffffff00) | 0x55;
rPUPC = (rPUPE & 0xfff0); // Pull up
rPDATC = (rPDATC & 0xfff0 ) | 0xe; // should be enabled
#else
// S3CEV40
// TSPX(GPE4_Q4(+)) TSPY(GPE5_Q3(-)) TSMY(GPE6_Q2(+)) TSMX(GPE7_Q1(-))
// 0 1 1 0
rPCONE = (rPCONE & 0x300ff) | 0x5500;
rPUPE = (rPUPE & 0xF);
rPDATE = 0xb8;
#endif
delay(100);
// set interrupt
#ifndef S3CEV40
rPUPG = (rPUPG & 0xFE) | 0x1;
pISR_EINT0=(int)touchscreen_int; // set interrupt handler
//rEXTINT = (rEXTINT & 0x7FFFFFF0) | 0x2; // falling edge trigger
rEXTINT = (rEXTINT & 0x7FFFFFF0) | 0x0; // both edge trigger
rI_ISPC |= BIT_EINT0; // clear pending_bit
rINTMSK =~(BIT_GLOBAL|BIT_EINT0);
#else
pISR_EINT2=(int)touchscreen_int; // set interrupt handler
rEXTINT = (rEXTINT & 0x7FFFF0FF) | 0x200; // falling edge trigger
rI_ISPC |= BIT_EINT2; // clear pending_bit
rINTMSK =~(BIT_GLOBAL|BIT_EINT2);
#endif
rCLKCON = (rCLKCON & 0x6FFF) | 0x1000; // enable clock
rADCPSR = 24; // A/D prescaler
}
另一方面,程序的主体功能在触摸屏的中断服务例程中直接实现:
void touchscreen_int(void)
...{
UINT32T unPointX[5], unPointY[6];
int i;
int X,Y;
static int cnt=0;
static int oldX,oldY;
#ifndef S3CEV40
// <X-Position Read>
// TSPX(GPC1_Q4(+)) TSPY(GPC3_Q3(-)) TSMY(GPC0_Q2(+)) TSMX(GPC2_Q1(-))
// 0 1 1 0
rPDATC = (rPDATC & 0xfff0 ) | 0x9;
rADCCON= 0x0014; // AIN5
#else
// TSPX(GPE4_Q4(+)) TSPY(GPE5_Q3(-)) TSMY(GPE6_Q2(+)) TSMX(GPE7_Q1(-))
// 0 1 1 0
rPDATE =0x68;
rADCCON=0x1<<2; // AIN1
#endif
delay(100); // delay to set up the next channel
for(i=0; i<5; i++)
...{
rADCCON |= 0x1; // Start X-position A/D conversion
while(rADCCON & 0x1 == 1); // Check if AD conversion starts
while((rADCCON & 0x40) == 0); // Check end of AD conversion
unPointX[i] = (0x3ff&rADCDAT);
}
// read X-position average value
unPosX = (unPointX[0]+unPointX[1]+unPointX[2]+unPointX[3]+unPointX[4])/5;
f_unPosX = unPosX;
#ifndef S3CEV40
// <Y-Position Read>
// TSPX(GPC1_Q4(-)) TSPY(GPC3_Q3(+)) TSMY(GPC0_Q2(-)) TSMX(GPC2_Q1(+))
// 1 0 0 1
rPDATC = (rPDATC & 0xfff0 ) | 0x6;
rADCCON= 0x001C; // AIN70
#else
// TSPX(GPE4_Q4(-)) TSPY(GPE5_Q3(+)) TSMY(GPE6_Q2(-)) TSMX(GPE7_Q1(+))
// 1 0 0 1
rPDATE =0x98;
rADCCON=0x0<<2; // AIN0
#endif
delay(100); // delay to set up the next channel
for(i=0; i<5; i++)
...{
rADCCON |= 0x1; // Start Y-position conversion
while(rADCCON & 0x1 == 1); // Check if AD conversion starts
while((rADCCON & 0x40) == 0); // Check end of AD conversion
unPointY[i] = (0x3ff&rADCDAT);
}
// read Y-position average value
unPosY = (unPointY[0]+unPointY[1]+unPointY[2]+unPointY[3]+unPointY[4])/5;
f_unPosY = unPosY;
#ifndef S3CEV40
rPDATC = (rPDATC & 0xfff0 ) | 0xe; // should be enabled
#else
rPDATE = 0xb8; // should be enabled
#endif
//delay(1000);
delay(100);
/**///////////////////////////////////////////////////////////////////////////////
if(ready)
...{ if(f_unPosX<f_unMaxX && f_unPosX>f_unMinX && f_unPosY<f_unMaxY && f_unPosY>f_unMinY)
...{
X = 320*(f_unPosX - f_unMinX)/(f_unMaxX - f_unMinX);
Y = 240-240*(f_unPosY - f_unMinY)/(f_unMaxY - f_unMinY);
uart_printf("%d : X=%04d, Y=%04d ", ++cnt, X, Y);
lcd_draw_line(oldX, oldY, X, Y, RED, 1);
oldX = X,oldY = Y;
}
}
f_unTouched = 1;
/**//////////////////////////////////////////////////////////////////////////
#ifndef S3CEV40
rI_ISPC |= BIT_EINT0; // clear pending_bit
#else
rI_ISPC |= BIT_EINT2; // clear pending_bit
#endif
}
实验总结:电阻式触摸屏连续地将感受到的触摸点以模拟电压的方式输入到ARM7的ADC模块,而ADC模块又在ARM7的时钟配合下将模拟信号转换为串行的数字信号输出,同时以中断方式通知CPU。中断触发的方式定义了5种:高电平触发、低电平触发、上跳沿触发、下跳沿触发和双边沿触发。示例里面采用的是功能最简单的下跳沿触发方式,可以在触摸笔接触和离开触摸屏的两个时刻触发中断;而要实现连续采点以便在LCD上跟踪触摸笔的位置画点,可以采用双边沿触发方式(both edge trigger)。
在实验过程中仍然很容易出现采集的点的值越出最初进行触摸屏校正时得到的边界值,估计是触摸屏本身硬件的问题,点的输出值与触摸点的电压变化不是线性关系所致。
相关文章推荐
- linux 3.15.2 触摸屏移植之selected device is not a touchscreen I understand
- 带有文本的触摸屏界面设计(Labeling Touchscreen Interfaces)
- Thinking In Design Pattern——Unit Of Work(工作单元)模式探索
- android中如何设计触摸屏驱动touch screen driver
- Thinking In Design Pattern——Unit Of Work(工作单元)模式探索
- linux内核usb触摸屏驱动bug调试- selected device is not a touchscreen I understand
- (OpenSessionInView模式)spring对session和事务的管理以及OpenSessionInViewFilter是如何工作的
- s3c6410硬件ADC & TOUCH SCREEN INTERFACE(AD转化和触摸屏接口)
- Monitor Screen Touch Event in Android
- iPhone: Detecting user inactivity/idle time since last screen touch
- Planning for Multiple Touchscreen Sizes 规划多个触摸屏尺寸
- VS代码段扩展Snippet Designer is a Visual Studio plug in which allows you to create and search for snippets inside the IDE
- S3C2410的ADC和触摸屏接口的5种工作模式
- android中如何设计触摸屏驱动touch screen driver
- linux内核usb触摸屏驱动bug调试- selected device is not a touchscreen I understand
- Linux ——usb触摸屏驱动 - usbtouchscreen
- S3C2410的ADC和触摸屏接口的5种工作模式
- Thinking In Design Pattern——Unit Of Work(工作单元)模式探索
- Content Query Web Part VS the Content Search Web Part in SharePoint
- 打造前端 Deepin Linux 工作环境——配置 XAMPP 集成环境2 虚拟主机、数据库