s3c2440裸机-电阻触摸屏-6-触摸屏校准实现-五点校准法

发布者:WhisperingSoul最新更新时间:2024-07-03 来源: elecfans关键字:电阻触摸屏  触摸屏校准 手机看文章 扫描二维码
随时随地手机看文章

前面我们讲过触摸屏触摸屏校准原理就是让lcd能够与触摸屏坐标对应起来。


一、五点法校准实现

一、我们取A,B,C,D,E这五个点,那么这个时候我们需要把该5个点的触摸屏和LCD的坐标对应起来,这就是校准的过程。


①在LCD显示屏上A点显示一个“十字”形状

②用户在触摸屏上点击对应A点的“十字”形状

③记录触摸屏的数据坐标

同理在B,C, D, E点循环该①②③过程,就能得到这五点触摸屏坐标。

二 、然后根据这5个触摸屏坐标数据确定公式。

三 、以后得到TS触点坐标,即可校准出期待的TS坐标。

下面开始函数实现:

在LCD上显示'十字'形状,定义为函数fb_disp_cross()

记录触摸屏坐标,定义函数为ts_read_raw()

根据这触摸屏坐标数据确定公式,定义函数为ts_calibrate()

以后得到TS触点坐标,即可校准出期待的TS坐标,定位函数为ts_read()1.画线画圆函数实现

前面的五、LCD上实现画点、线、圆实现了画点函数fb_put_pixel。基于画点函数即可画出线段以及各种图案。


动图封面

动图封面

//-------------画圆函数。参数:圆心,半径,颜色---------- // 画1/8圆 然后其他7/8对称画 // ---------------->X // |(0,0) 0 // | 7 1 // | 6 2 // | 5 3 // (Y)V 4 // // L = x^2 + y^2 - r^2 void draw_circle(int x, int y, int r, int color) { int a, b, num; a = 0; b = r; while(22 * b * b >= r * r) // 1/8圆即可 { fb_put_pixel(x + a, y - b,color); // 0~1 fb_put_pixel(x - a, y - b,color); // 0~7 fb_put_pixel(x - a, y + b,color); // 4~5 fb_put_pixel(x + a, y + b,color); // 4~3 fb_put_pixel(x + b, y + a,color); // 2~3 fb_put_pixel(x + b, y - a,color); // 2~1 fb_put_pixel(x - b, y - a,color); // 6~7 fb_put_pixel(x - b, y + a,color); // 6~5 a++; num = (a * a + b * b) - r*r; if(num > 0) { b--; a--; } } } //-----------画线。参数:起始坐标,终点坐标,颜色-------- void draw_line(int x1,int y1,int x2,int y2,int color) { int dx,dy,e; dx=x2-x1; dy=y2-y1; if(dx>=0) { if(dy >= 0) // dy>=0 { if(dx>=dy) // 1/8 octant { e=dy-dx/2; while(x1<=x2) { fb_put_pixel(x1,y1,color); if(e>0){y1+=1;e-=dx;} x1+=1; e+=dy; } } else // 2/8 octant { e=dx-dy/2; while(y1<=y2) { fb_put_pixel(x1,y1,color); if(e>0){x1+=1;e-=dy;} y1+=1; e+=dx; } } } else // dy<0 { dy=-dy; // dy=abs(dy) if(dx>=dy) // 8/8 octant { e=dy-dx/2; while(x1<=x2) { fb_put_pixel(x1,y1,color); if(e>0){y1-=1;e-=dx;} x1+=1; e+=dy; } } else // 7/8 octant { e=dx-dy/2; while(y1>=y2) { fb_put_pixel(x1,y1,color); if(e>0){x1+=1;e-=dy;} y1-=1; e+=dx; } } } } else //dx<0 { dx=-dx; //dx=abs(dx) if(dy >= 0) // dy>=0 { if(dx>=dy) // 4/8 octant { e=dy-dx/2; while(x1>=x2) { fb_put_pixel(x1,y1,color); if(e>0){y1+=1;e-=dx;} x1-=1; e+=dy; } } else // 3/8 octant { e=dx-dy/2; while(y1<=y2) { fb_put_pixel(x1,y1,color); if(e>0){x1-=1;e-=dy;} y1+=1; e+=dx; } } } else // dy<0 { dy=-dy; // dy=abs(dy) if(dx>=dy) // 5/8 octant { e=dy-dx/2; while(x1>=x2) { fb_put_pixel(x1,y1,color); if(e>0){y1-=1;e-=dx;} x1-=1; e+=dy; } } else // 6/8 octant { e=dx-dy/2; while(y1>=y2) { fb_put_pixel(x1,y1,color); if(e>0){x1-=1;e-=dy;} y1-=1; e+=dx; } } } } }

View Code

2.画一个十字架

要画一个十字架,只需要用画两条短线段即可。


void fb_disp_cross(int x, int y, unsigned int color) { draw_line(x-10, y, x+10, y, color); draw_line(x, y-10, x, y+10, color); }

3.记录触摸点原始坐标

以前4.1获取触摸屏坐标)记录触摸屏坐标是在Isr_Adc中实现的,只是把转换结束后的坐标打印了出来,那现在我们把它先记录下来。

static int g_ts_x; static int g_ts_y; static volatile int g_ts_data_valid = 0; void report_ts_xy(int x, int y) { //printf('x = %08d, y = %08dnr', x, y); if (g_ts_data_valid == 0) { g_ts_x = x; g_ts_y = y; g_ts_data_valid = 1; } } void ts_read_raw(int *px, int *py) { while (g_ts_data_valid == 0); *px = g_ts_x; *py = g_ts_y; g_ts_data_valid = 0; }

void get_calibrate_point_data(int lcd_x, int lcd_y, int *px, int *py)
{ fb_disp_cross(lcd_x, lcd_y, 0xffffff); /* 等待点击 */ ts_read_raw(px, py); }

这里 ts_read_raw是阻塞式的读取数据,当一开始没有按下触摸屏,那么不会产生adc interrupt,那么ts_read_raw会被阻塞住。只有当用户按下后,才会立马返回坐标数据。

这里对g_ts_data_valid用volatile来修饰就是不让编译器优化,表示要让这个变量读取时一定是从内存里面读到的,对这个变量写入时,一定会把它写到内存中去。

4.校准公式ts_calibrate()

先获取lcd参数

再显示5个校准点,且获取5个点的ts实际坐标

确定校准公式

static double g_kx; static double g_ky; static int g_ts_xc, g_ts_yc; static int g_lcd_xc, g_lcd_yc; static int g_ts_xy_swap = 0;int is_ts_xy_swap(int a_ts_x, int a_ts_y, int b_ts_x, int b_ts_y) { int dx = b_ts_x - a_ts_x; int dy = b_ts_y - a_ts_y; if (dx < 0) dx = 0 - dx; if (dy < 0) dy = 0 - dy; if(dx > dy) return 0; /* xy没有反转 */ else return 1; /* xy反了 */ } void swap_xy(int *px, int *py) { int tmp = *px; *px = *py; *py = tmp; } /* ---------------------------- | | | +(A) (B)+ | | | | | | | | +(E) | | | | | | | | +(D) (C)+ | | | ---------------------------- */ void ts_calibrate(void) { unsigned int fb_base; int xres, yres, bpp; int a_ts_x, a_ts_y; int b_ts_x, b_ts_y; int c_ts_x, c_ts_y; int d_ts_x, d_ts_y; int e_ts_x, e_ts_y; /* X轴方向 */ int ts_s1, ts_s2; int lcd_s; /* Y轴方向 */ int ts_d1, ts_d2; int lcd_d; /* 获得LCD的参数: fb_base, xres, yres, bpp */ get_lcd_params(&fb_base, &xres, &yres, &bpp); /* 对于ABCDE, 循环: 显示'+'、点击、读ts原始值 */ /* A(50, 50) */ get_calibrate_point_data(50, 50, &a_ts_x, &a_ts_y); /* B(xres-50, 50) */ get_calibrate_point_data(xres-50, 50, &b_ts_x, &b_ts_y); /* C(xres-50, yres-50) */ get_calibrate_point_data(xres-50, yres-50, &c_ts_x, &c_ts_y); /* D(50, yres-50) */ get_calibrate_point_data(50, yres-50, &d_ts_x, &d_ts_y); /* E(xres/2, yres/2) */ get_calibrate_point_data(xres/2, yres/2, &e_ts_x, &e_ts_y); /* 确定触摸屏数据XY是否反转 */ g_ts_xy_swap = is_ts_xy_swap(a_ts_x, a_ts_y, b_ts_x, b_ts_y); if (g_ts_xy_swap) { /* 对调所有点的XY坐标 */ swap_xy(&a_ts_x, &a_ts_y); swap_xy(&b_ts_x, &b_ts_y); swap_xy(&c_ts_x, &c_ts_y); swap_xy(&d_ts_x, &d_ts_y); swap_xy(&e_ts_x, &e_ts_y); } /* 确定公式的参数并保存 */ ts_s1 = b_ts_x - a_ts_x; ts_s2 = c_ts_x - d_ts_x; lcd_s = xres-50 - 50; ts_d1 = d_ts_y - a_ts_y; ts_d2 = c_ts_y - b_ts_y; lcd_d = yres-50-50; g_kx = ((double)(2*lcd_s)) / (ts_s1 + ts_s2); g_ky = ((double)(2*lcd_d)) / (ts_d1 + ts_d2); g_ts_xc = e_ts_x; g_ts_yc = e_ts_y; g_lcd_xc = xres/2; g_lcd_yc = yres/2; }

这里还补充了一点,这里可以软件进行矫正触摸屏与LCD贴错位的情况导致x,y轴坐标反转的问题。这里用a,b两个点的触摸屏实际坐标进行比对,如果从a点到b点的x坐标变化明显,y坐标变化不明显,表示x,y方向没有贴反。反之则表示x,y方向贴反了,需要反转坐标轴。

5. ts_read()读出校准后(期望)的坐标

/* * 读TS原始数据, 转换为期望的坐标 */ void ts_read(int *lcd_x, int *lcd_y) {   int ts_x, ts_y;   ts_read_raw(&ts_x, ts_y);   if (g_ts_xy_swap) {   swap_xy(&ts_x, &ts_y); }   /* 使用公式计算 */   *lcd_x = g_kx * (ts_x - g_ts_xc) + g_lcd_xc;   *lcd_y = g_ky * (ts_y - g_ts_yc) + g_lcd_yc; }

二、测试

void clear_screen(unsigned int color) { int x, y; unsigned char *p0; unsigned short *p; unsigned int *p2; /* 往framebuffer中写数据 */ if (bpp == 8) { /* bpp: palette[color] */ p0 = (unsigned char *)fb_base; for (x = 0; x < xres; x++) for (y = 0; y < yres; y++) *p0++ = color; } else if (bpp == 16) { /* 让LCD输出整屏的红色 */ /* 565: 0xf800 */ p = (unsigned short *)fb_base; for (x = 0; x < xres; x++) for (y = 0; y < yres; y++) *p++ = convert32bppto16bpp(color); } else if (bpp == 32) { p2 = (unsigned int *)fb_base; for (x = 0; x < xres; x++) for (y = 0; y < yres; y++) *p2++ = color; } } void touchscreen_test(void) { unsigned int fb_base; int xres, yres, bpp; int x, y, pressure; /* 获得LCD的参数: fb_base, xres, yres, bpp */ get_lcd_params(&fb_base, &xres, &yres, &bpp); touchscreen_init(); /* 清屏 */ clear_screen(0);/*LCD章节有介绍*/ /* 显示文字提示较准 */ fb_print_string(70, 70, 'Touc cross to calibrate touchscreen', 0xffffff); ts_calibrate(); /* 显示文字提示绘画 */ fb_print_string(70, yres - 70, 'OK! To draw!', 0xffffff); while (1) { if (ts_read(&x, &y) == 0) { printf(' x = %d, y = %dnr', x, y); fb_put_pixel(x, y, 0xff00); //显示点 } } }



这里我只点击了A点,怎么一下修改子跳出5个十字架。这里由于我们是点击一下可能时间会很长,几十甚至几百毫秒,那么会产生很多次TS intterrupt和ADC中断,那么我们需要用户松开后才认为触摸动作完成。


关键字:电阻触摸屏  触摸屏校准 引用地址:s3c2440裸机-电阻触摸屏-6-触摸屏校准实现-五点校准法

上一篇:s3c2440裸机-电阻触摸屏-7-触摸屏校准测试及优化
下一篇:s3c2440裸机-电阻触摸屏-5-触摸屏校准原理-五点校准法

推荐阅读最新更新时间:2026-03-21 16:09

s3c2440裸机-电阻触摸屏编程(6.触摸屏校准实现-校准)
前面我们讲过触摸屏触摸屏校准原理就是让lcd能够与触摸屏坐标对应起来。 一、五点法校准实现 一、我们取A,B,C,D,E这五个点,那么这个时候我们需要把该5个点的触摸屏和LCD的坐标对应起来,这就是校准的过程。 ①在LCD显示屏上A点显示一个“十字”形状 ②用户在触摸屏上点击对应A点的“十字”形状 ③记录触摸屏的数据坐标 同理在B,C, D, E点循环该①②③过程,就能得到这五点触摸屏坐标。 二 、然后根据这5个触摸屏坐标数据确定公式。 三 、以后得到TS触点坐标,即可校准出期待的TS坐标。 下面开始函数实现: 在LCD上显示 十字 形状,定义为函数fb_disp_cross() 记录触摸屏坐标,定义函数为ts_read_ra
[单片机]
<font color='red'>s3c2440</font><font color='red'>裸机</font>-<font color='red'>电阻</font><font color='red'>触摸屏</font>编程(6.<font color='red'>触摸屏</font><font color='red'>校准</font>实现-<font color='red'>五</font><font color='red'>点</font><font color='red'>校准</font><font color='red'>法</font>)
s3c2440裸机-电阻触摸屏-1-电阻触摸屏原理
一、电阻触摸屏原理 触摸屏包含上下叠合的两个透明层,一般覆盖在lcd表面,两个透明层是由均匀的电阻介质组成,如下图。 当触摸屏表面受到的压力(如通过笔尖或手指进行按压)足够大时,顶层与底层之间的薄膜会产生接触,此时会形成x方向和y方向的坐标。那么x,y坐标的值是怎么得来的呢?本质上就是通过ADC转换得来的。详解如下: 触摸屏的等效电路可以看成如下图: 计算触点的X,Y坐标分为如下两步(见下图): 1.计算Y坐标: 在Y+电极施加驱动电压Vdrive, Y-电极接地,由于上下两层膜形成触点,X+做为触点的引出端,测量得到接触点的电压,触点电压与Vdrive电压之比等于触点Y坐标与屏高度之比。如下图: 2.计算X坐标:
[单片机]
s3c2440裸机-电阻触摸屏编程(1.电阻触摸屏原理)
一、电阻触摸屏原理 触摸屏包含上下叠合的两个透明层,一般覆盖在lcd表面,两个透明层是由均匀的电阻介质组成,如下图。 当触摸屏表面受到的压力(如通过笔尖或手指进行按压)足够大时,顶层与底层之间的薄膜会产生接触,此时会形成x方向和y方向的坐标。那么x,y坐标的值是怎么得来的呢?本质上就是通过ADC转换得来的。详解如下: 触摸屏的等效电路可以看成如下图: 计算触点的X,Y坐标分为如下两步(见下图): 1.计算Y坐标: 在Y+电极施加驱动电压Vdrive, Y-电极接地,由于上下两层膜形成触点,X+做为触点的引出端,测量得到接触点的电压,触点电压与Vdrive电压之比等于触点Y坐标与屏高度之比。如下图: 2.计算X坐标: 在X+电
[单片机]
<font color='red'>s3c2440</font><font color='red'>裸机</font>-<font color='red'>电阻</font><font color='red'>触摸屏</font>编程(1.<font color='red'>电阻</font><font color='red'>触摸屏</font>原理)
S3C2440裸机------触摸屏_电阻触摸屏硬件原理
1.电阻触摸屏原理 2.电阻触摸屏等效电路 2.1触摸屏空闲状态 平时触摸屏没有被按下时,等效电路如图14.5所示。S4、S5闭合,S1、S2、S3断开,即YM接地、XP上拉、XP作为模拟输入(对CPU而言)、YP作为模拟输入、XM高阻。 平时触摸屏没有被按下时,由于上拉电阻的关系,Y_ADC为高电平,当x轴和y轴收挤压而接触导通后,Y_ADC的电压由于连通道y轴接地而变为低电平,此低电平可作为中断触发信号来通知CPU发生“Pen Down”事件。 2.2采样X_ADC电压 采样X_ADC电压,得到x坐标,等效电路如图14.6所示。 S1、S3闭合,S2、S4、S5断开,即XP 接上电源、XM接地、YP作
[单片机]
<font color='red'>S3C2440</font><font color='red'>裸机</font>------<font color='red'>触摸屏</font>_<font color='red'>电阻</font><font color='red'>触摸屏</font>硬件原理
十四、s3c2440裸机—中断控制器
14.1 中断体系 ARM 体系的CPU 有 7 种工作模式 用户模式(usr):ARM 处理器正常的程序执行状态 快速中断模式(fiq):用于高速数据传输或通道处理 中断模式(irq):用户通用的中断处理   管理模式(svc):操作系统使用的保护模式 数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护 系统模式(sys):运行具有特权的操作系统任务 未定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真   可通过软件来进行模式切换,或者发生各类中断、异常时CPU自动进入相应的模式。除用户模式外,其他6种工作模式都属于特权模式,
[单片机]
十四、<font color='red'>s3c2440</font><font color='red'>裸机</font>—中断控制器
s3c2440裸机开发调试环境(MDK4.72,Jlink v8,mini2440)
我的开发环境:windows 7 32位,J-linkv8,mini2440开发板一块。最后选择了:MDK4.72版本,J-ink v8的当前最新版本J-linkARM v4.94。 1)打开Keil uVision4新建一个工程: 2)新建一个目录用于存放我们的工程文件,这样我用新建一个test目录:并且取工程名为test并保存: 3)接下来选择CUP database:我们选择samsung的S3C2440A,点击OK;之后会出现第二个图问你是否拷贝'S3C2440.s'到工程文件夹并加入到工程里,S3C2440.s是启动代码我们选择YES 4)然后我们需要对S3C2440.s进行一些
[单片机]
<font color='red'>s3c2440</font><font color='red'>裸机</font>开发调试环境(MDK4.72,Jlink v8,mini2440)
S3c2440裸机-spi编程-2.OLED显示面板
1.OLED显示面板介绍 以QG-2864TMBEG01这款OLED为例,可见它支持Parallel/i2c/SPI这3种方式对它进行控制,这里仅对它进行SPI控制。它的product Specification见附件。 并行接口时序: SPI串行接口时序 Tr/Tf: 表示spi clk上升/下降延不能超过40ns Tclkl/Tclkh: 表示spi clk低/高电平持续至少20ns Tcycle: 表示spi clk一个时钟周期至少100ns Tdsw/Tdhw: 表示spi data的建立/持续时间至少15ms Tcss:片选建立时间至少20ns Tcsh:片选持续时间至少10ns Tas/Tah:地址建立/
[单片机]
<font color='red'>S3c2440</font><font color='red'>裸机</font>-spi编程-2.OLED显示面板
s3c2440裸机-内存控制器4-SDRAM编程实现
配置内存控制器-SDRAM编程配置 2440内存控制器共有13个寄存器。 BANK0--BANK5只需要设置BWSCON和BANKCONx(x为0~5)两个寄存器; BANK6、BANK7外接SDRAM时,除BWSCON和BANKCONx(x为6、7)外,还要设置REFRESH、BANKSIZE、MRSRB6、MRSRB7等4个寄存器。 下面分别说明各个寄存起的设置: 1.位宽和等待控制寄存器BWSCON(BUSWIDTH&WAITCONTROLREGISTER) 我们SDRAM的位宽为32,DW6 设置成10, 没有使用等待信号,所以WS6 =0。 bank7跟随bank6的配置, 因此BWSCON寄存器的值为:0x2
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved