程序功能:
1)触屏校准:
按下预设的4个坐标点,利用ADC转换功能采集对应物理坐标,得出物理坐标与屏幕像素坐标之间的关系。
物理坐标和象素坐标的转换表达式如下:
hor_pix = (int)(mul_x * X + add_x)
ver_pix = (int)(mul_y * Y + add_y)
其中:(X, Y)表示物理坐标,(hor_pix, ver_pix)表示象素坐标。
2)触屏坐标测试:
随机按下触屏,根据以上公式,程序自动给出相应象素坐标值。
3)信息显示:
整个过程中的提示信息,均以ASCII字符形式显示在屏幕上。
功能模块说明:
本程序以2440触屏测试程序源码为基础,增加了以下功能模块:
1)ascii码字符串输出函数:以象素点阵画出ascii码字符并在屏幕上显示。
2)字符串滚动显示函数:参考操作系统终端的显示方式,设定一个固定显示8行字符的区域,新的一行字符显示出来的时候会使其上所有字符上移一行。
3)同一行追加显示函数:要显示的字符串不另起一行,而是在最后一行的尾部以追加的方式显示。
4)全屏刷新函数:在屏幕滚动显示的时候,显示效果与显存内容不同步,在滚动结束时,需调用此函数进行处理。
5)画十字函数:在指定位置画出十字,以显示校准点。
6)带轨迹移动十字函数:按指定偏移量水平或垂直移动十字, 并显示移动轨迹。
7)校准数据采集有效性判断函数:根据设定的阀值判断采集到的物理坐标是否有效,以保证准确按下校准点。
8)浮点数/整型数转字符串函数:为了将数值显示于屏幕上,需预先转换为字符串类型。
9)触屏按下处理函数:判断当前按下的点是校准点还是测试点,并做出相应处理,若为校准点将会在屏幕上显示下一步操作提示信息,为测试点的话会显示相应位置的象素坐标。
10)触屏弹起处理函数:判断触屏校准工作是否完成,完成的话将会显示象素坐标的计算公式,否则会给出下一步操作信息。
11)行清理函数:以背景色填充指定行。
程序执行效果:

代码文件:
1)触屏校准函数库文件,包含以上所有功能模块。
/*****************************************
NAME: adj_sc.c
DESC: Adjusting Touch screen & test
HISTORY:
2011.09.01:Joshua Chan: draft ver 1.0
*****************************************/
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"
#include "profile.h"
#include "memtest.h"
#include "main.h"
#include "adj_sc.h"
/* 定义320行,240列的数组,用于存放显示数据 */
volatile unsigned short LCD_BUFFER[SCR_YSIZE][SCR_XSIZE];
/* 用(current_x, current_y)来记录下次显示字符的起始坐标 */
int current_x = 0;
int current_y = 0;
/*
* (x1, y1), (x2, y2), (x3, y3), (x4, y4)用来采集4个校准点物理坐标
* 4个屏幕校准点象素坐标分别为: (40, 30), (280, 30), (280, 210), (40, 210)
*/
int x1=0, x2=0, x3=0, x4=0;
int y1=0, y2=0, y3=0, y4=0;
int collect_count = 0;
/* current_row记录下次打印起始行, 第一次打印从57行开始 */
int current_row = 57;
/*
* 物理坐标和象素坐标的转换表达式如下:
* hor_pix = (int)(mul_x * X + add_x)
* ver_pix = (int)(mul_y * Y + add_y)
* 其中: (X, Y)表示物理坐标, (hor_pix, ver_pix)表示象素坐标
*/
float mul_x = 0.0;
float mul_y = 0.0;
float add_x = 0.0;
float add_y = 0.0;
/*
* 用象素点阵画出ascii码字符
* 每个文字点阵8x16, 长度16字节, 即 1 bit 表示 1 象素
* 排列方式:横向顺序,横排
* @*ch: 字模数组地址
* @swi: 起始坐标选择开关, 值为0时, 表示起始坐标为(x0, y0),
* 值为1时, 表示起始坐标为(current_x, current_y),
* 即最后画的那一个字符后面的位置.
*/
void draw_char(int x0, int y0, U16 front_color, U16 back_color, char *ch, int swi)
{
int x=0, y=0;
unsigned char tmp = 0;
U32 c=0;
char *p = ch;
if (swi == 1) {
x0 = current_x;
y0 = current_y;
}
while (*p) {
for (y=y0; y<y0+16; y++)="" {
for (x=x0; x<x0+8; x++)="" {
/* 用tmp取出数组中对应的元素, 长度为1字节,
* 取出tmp中相应的1位, 并转换为2字节的颜色信息,
* 并存入显存相应位置 */
tmp = ASCII[(*p)*16+y-y0];
c = (tmp & (1<<(8-(x-x0))))?(front_color) back_color);
LCD_BUFFER[y][x] = c;
}
}
x0 = x0 + 8;
p++;
}
current_x = x;
current_y = y0;
}
/*
* 在高度为128的象素区滚动显示字符点阵
* 因为每个文字点阵8x16, 所以此区域共可显示8行文字
* 起始垂直象素坐标57, 结束坐标为184
* 第一行文字从坐标57开始, 末行文字从坐标169开始
* @*ch: 要显示的字符串地址
*/
void scroll_display(char *ch)
{
int x0 = 10;
int i, j, k;
if (current_row > 169) {
current_row = 169;
for (i=0; i<16; i++) {
for (j=57; j<184-i; j++) {
clear_line(j);
for (k=1; k<320; k++) {
LCD_BUFFER[j][k] = LCD_BUFFER[j+1][k];
}
}
clear_line(184 - i);
}
}
draw_char(x0, current_row, F_COLOR, B_COLOR, ch, 0);
current_row += 16;
refresh_screen();
}
/*
* 挨着上次的字符显示指定字符串
*/
void add_display(char *ch)
{
draw_char(0, 0, F_COLOR, B_COLOR, ch, 1);
refresh_screen();
}
/*
* 用背景色填充指定行
*/
void clear_line(int line)
{
int i;
for (i=1; i<320; i++)
LCD_BUFFER[line] = B_COLOR;
}
/*
* 全屏刷新
* 在屏幕滚动显示的时候, 显示效果与显存内容不同步,
* 在滚动结束时, 需调用此函数处理
*/
void refresh_screen(void)
{
int i, j;
for( i = 0 ; i < SCR_YSIZE ; i++ )
for( j = 0 ; j < SCR_XSIZE ; j++ )
LCD_BUFFER[j] = LCD_BUFFER[j] ;
}
/*
* 以(x0, y0)为中心画十字
*/
void draw_cross(int x0, int y0, int size, U16 d_color)
{
int x=0, y=0;
int tmp = size/2;
for (x=(x0-tmp); x<(x0+tmp+1); x++)
LCD_BUFFER[y0][x] = d_color;
for (y=(y0-tmp); y<(y0+tmp+1); y++)
LCD_BUFFER[y][x0] = d_color;
}
/*
* 水平或垂直移动十字, 并显示移动轨迹
* 在移动的过程中, 用背景色画十字来清除轨迹
* (x0, y0) 为起始坐标
* @x_of: X 方向偏移量
* @y_of: Y 方向偏移量
* "x_of" 与 "y_of" 二者必须要有一个值为0
*/
void move_cross(int x0, int y0, int siz, int x_of, int y_of)
{
int i = 0;
if (x_of!=0 && y_of!=0)
return;
if (x_of > 0)
for (i=0; i<x_of; i++)="" {
draw_cross(x0+i-1, y0, siz, B_COLOR);
draw_cross(x0+i+1, y0, siz, B_COLOR);
draw_cross(x0, y0-1, siz, B_COLOR);
draw_cross(x0, y0+1, siz, B_COLOR);
draw_cross(x0+i, y0, siz, F_COLOR);
delay(600);
}
else if (x_of < 0)
for (i=0; i>x_of; i--) {
draw_cross(x0+i-1, y0, siz, B_COLOR);
draw_cross(x0+i+1, y0, siz, B_COLOR);
draw_cross(x0, y0-1, siz, B_COLOR);
draw_cross(x0, y0+1, siz, B_COLOR);
draw_cross(x0+i, y0, siz, F_COLOR);
delay(600);
}
else if (y_of > 0)
for (i=0; i<y_of; i++)="" {
draw_cross(x0-1, y0, siz, B_COLOR);
draw_cross(x0+1, y0, siz, B_COLOR);
draw_cross(x0, y0+i-1, siz, B_COLOR);
draw_cross(x0, y0+i+1, siz, B_COLOR);
draw_cross(x0, y0+i, siz, F_COLOR);
delay(600);
}
else if (y_of < 0)
for (i=0; i>y_of; i--) {
draw_cross(x0-1, y0, siz, B_COLOR);
draw_cross(x0+1, y0, siz, B_COLOR);
draw_cross(x0, y0+i-1, siz, B_COLOR);
draw_cross(x0, y0+i+1, siz, B_COLOR);
draw_cross(x0, y0+i, siz, F_COLOR);
delay(600);
}
}
/*
* 取字符串长度
*/
int str_len(char *ch)
{
char *p = ch;
int ret = 0;
while (*p) {
ret++;
p++;
}
return ret;
}
/*
* 取绝对值
*/
float abs_val(float f)
{
float ret = f;
if (ret < 0)
ret = (-1) * ret;
return ret;
}
/*
* 对采集到的坐标进行有效性判断
* 允许偏差值可以通过 @allow_val 设置
*/
int check_data(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
int allow_val = 20;
int ret = 0;
if (abs_val(y2-y1) > allow_val)
ret = 1;
if (abs_val(x3-x2) > allow_val)
ret = 1;
if (abs_val(y4-y3) > allow_val)
ret = 1;
if (abs_val(x4-x1) > allow_val)
ret = 1;
return ret;
}
/* |