⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsp.c

📁 用SMART2200低成本的实现OV9650摄像头驱动
💻 C
字号:
/**------------------------------------------------------------------------------------------------------
** Modified by:         Huangshaobin
** Modified date:       2005.6.1
** Version:             1.1
** Descriptions:  触摸屏校准程序。读取触摸屏左上角和右下角两个指定点的A/D值,保存
**                到E2PROM中(起始地址为0xF0),以后使用触摸屏就不需要再校准。
********************************************************************************************************/
#include "config.h"

 //定义E2PROM地址
#define     CAT1025        0xA0               
// 蜂鸣器控制口定义(P0.7)
#define     BEEPCON        (1<<7)
// 定义用于保存触摸屏(0,0)和两个校准点的坐标的电压值
uint16  g_vx_min, g_vy_min;
uint16  g_vinx0, g_viny0;
uint16  g_vinx1, g_viny1;
uint32  t0_time;
static  BITMAP  s_tsp[3];
extern const unsigned int   cur1_no;
extern const unsigned char  cur1_data[];
extern const unsigned int   cur2_no;
extern const unsigned char  cur2_data[];
extern const unsigned int   save_no;
extern const unsigned char  save_data[];
/****************************************************************************
* 名称:DelayNS()
* 功能:长软件延时(dly毫秒,与程序运行速度有关)
* 入口参数:dly		延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void  DelayNS(uint32  dly)
{  uint32  i;

   for(; dly>0; dly--) 
      for(i=0; i<800; i++);
}

/****************************************************************************
* 名称:Beep()
* 功能:控制蜂鸣器响一声。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void  Beep(void)
{   IO0CLR = BEEPCON;
    DelayNS(300);
    IO0SET = BEEPCON;
    DelayNS(150);
}


/****************************************************************************
* 名称:GetLCD_XY()
* 功能:读取触摸屏上触摸点的坐标。
*       程序会一直等待,直到有触摸输入。
* 入口参数:vx       用于保存触摸点x坐标(LCD)的变量指针
*           vy       用于保存触摸点y坐标(LCD)的变量指针
* 出口参数:无
* 说明:先通测量y轴的触摸输入,判断是否有触摸动作。如果有,则进行6次数据
*       采集,并进行去极值平均滤波处理。最后还要判断触摸输入是否合法,只有
*       当触摸输入合法时才返回。
****************************************************************************/
void  GetLCD_XY(uint16 *vx, uint16 *vy)
{   uint16  vx_dat, vy_dat;
    uint16  vx_dat1, vy_dat1;

    while(1)
    {   // 判断是否有触摸动作(通过ADS7843的PENIRQ引脚进行判断)
        while(1)
        {   vy_dat = ADS7843_WriteRead(AIN_Y);
            if(vy_dat != 0) break;            
            DelayNS(1); 
        } // end of while(1)...
    
        // 进行数据采集
        vx_dat = ADS7843_WriteRead(AIN_X);
        vy_dat = ADS7843_WriteRead(AIN_Y);
        vx_dat1 = ADS7843_WriteRead(AIN_X);
        vy_dat1 = ADS7843_WriteRead(AIN_Y);
        
        if((vy_dat<3) || (vy_dat1<3)) continue;
        
        if(vx_dat>vx_dat1) 
        {   if((vx_dat-vx_dat1) > 13) continue;
        }
        else
        {   if((vx_dat1-vx_dat) > 13) continue; 
        }
        
        if(vy_dat>vy_dat1) 
        {   if((vy_dat-vy_dat1) > 18) continue;
        }
        else
        {   if((vy_dat1-vy_dat) > 18) continue; 
        } 
        
        *vx = (vx_dat+vx_dat1) >> 1;
        *vy = (vy_dat+vy_dat1) >> 1;                          
        return;
    }
    
}



#define  VX_MIN_RANG        ((0x0FFF) * 1/5)
#define  VY_MIN_RANG        ((0x0FFF) * 1/5)
#define  VX_MAX_RANG        ((0x0FFF) * 4/5)
#define  VY_MAX_RANG        ((0x0FFF) * 4/5)
/****************************************************************************
* 名称:ChkTouch()
* 功能:触摸屏幕校准程序。会设置g_vx_min、g_vy_min和g_vinx0、g_viny0、
*       g_vinx1、g_viny1的值。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void  ChkTouch(void)
{   // 在坐标(0,0)上显示校准图标(十字光标),图标格式为20x20,校准点为(10,10)
    //GUI_LoadPic(0, 0, (uint8 *)CUR1_DATA, 20, 20);  
    FillBoxWithBitmap(0,0,&s_tsp[0]);  
    // 读取触摸输入点坐标值,并判断值是否在合法的范围内
    while(1)
    {   // 读取触摸输入
        GetLCD_XY(&g_vx_min, &g_vy_min);
        DelayNS(50);                    // 延时50mS,防抖
        GetLCD_XY(&g_vinx0, &g_viny0);
  
        // 判断触摸输入是否有效
        if((g_vy_min<3) || (g_viny0<3)) continue;
        
        if(g_vinx0>g_vx_min) 
        {   if((g_vinx0-g_vx_min) > 18) continue;
        }
        else
        {   if((g_vx_min-g_vinx0) > 18) continue; 
        }
        
        if(g_viny0>g_vy_min) 
        {   if((g_viny0-g_vy_min) > 13) continue;
        }
        else
        {   if((g_vy_min-g_viny0) > 13) continue; 
        } 
        
        // 取得两次触摸输入的平均值        
        g_vinx0 = (g_vinx0+g_vx_min) >> 1;
        g_viny0 = (g_viny0+g_vy_min) >> 1;      
  
        // 判断触摸输入是否有效
        if((g_vinx0<VX_MIN_RANG) && 
           (g_viny0<VY_MIN_RANG))
        {   GUI_RectangleFill(0, 0, 0+20, 0+20, WHITE); 
            Beep();
            break;
        }
    }
    
    // 在坐标(299,219)上显示校准图标(十字光标),图标格式为20x20,校准点为(309,229)
    //GUI_LoadPic(219, 299, (uint8 *)CUR1_DATA, 20, 20);
     FillBoxWithBitmap(219,299,&s_tsp[0]);  
    // 读取触摸输入点坐标值,并判断值是否在合法的范围内
    while(1)
    {   // 读取触摸输入
        GetLCD_XY(&g_vx_min, &g_vy_min);
        DelayNS(50);                    // 延时50mS,防抖
        GetLCD_XY(&g_vinx1, &g_viny1);
  
        // 判断触摸输入是否有效
        if((g_vy_min<3) || (g_viny1<3)) continue;
        
        if(g_vinx1>g_vx_min) 
        {   if((g_vinx1-g_vx_min) > 18) continue;
        }
        else
        {   if((g_vx_min-g_vinx1) > 18) continue; 
        }
        
        if(g_viny1>g_vy_min) 
        {   if((g_viny1-g_vy_min) > 13) continue;
        }
        else
        {   if((g_vy_min-g_viny1) > 13) continue; 
        } 
        
        // 取得两次触摸输入的平均值        
        g_vinx1 = (g_vinx1+g_vx_min) >> 1;
        g_viny1 = (g_viny1+g_vy_min) >> 1;      
  
        // 判断触摸输入是否有效
        if((g_vinx1>VX_MAX_RANG) && 
           (g_viny1>VY_MAX_RANG))
        {   GUI_RectangleFill(219, 299, 219+20, 299+20, BLACK); 
            Beep();
            break;
        }
    }
    
    // 对数据进行转换,以便于得到(0,0)点的电压值   
    g_vx_min = g_vinx0 - (g_vinx1 - g_vinx0) * 10 /(229 - 10);
    g_vy_min = g_viny0 - (g_viny1 - g_viny0) * 10 /(309 - 10);
}



/****************************************************************************
* 名称:DispCommButton()
* 功能:在屏幕上显示“保存”、“重新校准”按钮。
*       图片大小为70*70,显示位置为(250,0)--(319,69)
* 入口参数:无
* 出口参数:无
****************************************************************************/ 
void  DispCommButton(void)
{    
     FillBoxWithBitmap( 0,320-70, &s_tsp[2]);
} 


/****************************************************************************
* 名称:SaveChkData()
* 功能:将触摸屏校准的数据保存到E2PROM中,保存地址为0xE0--0xFF。
* 入口参数:无
* 出口参数:无
* 说明:0xE0、0xE1保存触摸屏是否校准标志,为0x5A、0xA5时表示校准过;
*
*       0xE2、0xE3保存(0,0)点坐标的电压转换值g_vx_min; 
*       0xE4、0xE5保存(0,0)点坐标的电压转换值g_vy_min;
*       0xE6、0xE7保存第1个校验点的电压转换值g_vinx0;
*       0xE8、0xE9保存第1个校验点的电压转换值g_viny0;
*       0xEA、0xEB保存第2个校验点的电压转换值g_vinx1;
*       0xEC、0xED保存第2个校验点的电压转换值g_viny1;
*
*       0xF0、0xF1保存第1、2校验点之间的x轴点数wide;
*       0xF2、0xF4保存第1、2校验点之间的y轴点数high;
*        
*       其它单元保留。
****************************************************************************/
void  SaveChkData(void)
{   uint8  dat_buf1[20];
    //uint8  dat_buf2[20];
   // int    i;       

    // 设置数据
    dat_buf1[0] = 0x5A; // 校准标志
    dat_buf1[1] = 0xA5;
    
    dat_buf1[2] = g_vx_min >> 8;
    dat_buf1[3] = g_vx_min & 0x00FF;
    
    dat_buf1[4] = g_vy_min >> 8;
    dat_buf1[5] = g_vy_min & 0x00FF;
    
    dat_buf1[6] = g_vinx0 >> 8;
    dat_buf1[7] = g_vinx0 & 0x00FF;
    
    dat_buf1[8] = g_viny0 >> 8;
    dat_buf1[9] = g_viny0 & 0x00FF;
    
    dat_buf1[10] = g_vinx1 >> 8;
    dat_buf1[11] = g_vinx1 & 0x00FF;
    
    dat_buf1[12] = g_viny1 >> 8;
    dat_buf1[13] = g_viny1 & 0x00FF;
    
    dat_buf1[14] =  0x01;           // 值为309 - 10,即0x012B
    dat_buf1[15] =  0x2B;
    
    dat_buf1[16] =  0x00;           // 值为229 - 10,即0x00DB
    dat_buf1[17] =  0xDB;
    
                  
    // 写入数据
    I2cWrite(CAT1025, dat_buf1, 14);
    DelayNS(10);                    // 10mS写周期
    I2cWrite(CAT1025, &dat_buf1[14], 4);
    DelayNS(10);                    // 10mS写周期
            
    /* 读出校验,若出错,则控制蜂鸣器响5声
    I2cRead(CAT1025,dat_buf2, 0xE0, 1,14);
    I2cRead(CAT1025,&dat_buf2[14], 0xF0, 1, 4);
    for(i=0; i<18; i++)
    {   if(dat_buf2[i] != dat_buf1[i])
        {   Beep();
            Beep();
            Beep();
            Beep();
            Beep();
            break;
        }
    }**/ 
}  


/****************************************************************************
* 名称:TestDelayNS()
* 功能:测试DelayNS函数的延时时间。通过观察t0_time的值计算出实际延时时间。
* 入口参数:无
* 出口参数:无
****************************************************************************/          
void  TestDelayNS(void)
{   int  i;

    T1PR = 0;			            // 设置定时器0分频为1分频,计数频率为Fpclk    
    for(i=0; i<10; i++)
    {   T1TC = 0;
        T1TCR = 0x01;               // 启动定计器        
        DelayNS(1);                 // 调用软件延时
        T1TCR = 0x00;               // 停止定时器
        t0_time = T1TC;             // 读取定时计数值
    }    
}


/****************************************************************************
* 名称:tsp_check()
* 功能:触摸屏校准,并将校准参数保存到E2PROM中。
****************************************************************************/ 
int  tsp_check(void)
{   int     x_1, y_1;    
    uint16  x1_bak, y1_bak;
    uint16  vx1, vy1;
    
    // 测试软件延时函数延时时间
    TestDelayNS();    
    // 初始化控制I/O
    PINSEL0 = PINSEL0 & 0xFFFF3FFF;	
	IO0DIR = BEEPCON;
	IO0SET = BEEPCON;
	IO2DIR = ADS7843_CS|ADS7843_DIN|ADS7843_DCLK;  
    LoadBitmapFromMem(&s_tsp[0], cur1_data, cur1_no);
    LoadBitmapFromMem(&s_tsp[1], cur2_data, cur2_no);
    LoadBitmapFromMem(&s_tsp[2], save_data, save_no);
    while(1)
    {   
        GUI_ClearSCR();             // 清屏 
        // 进入触摸屏幕校准程序,会设置g_vx_min、g_vy_min和g_vinx0、g_viny0、
        // g_vinx1、g_viny1的值。
        ChkTouch();    
        // 显示操作按钮
        DispCommButton();
       
        // 显示原始光标  
                  
        //GUI_LoadPic_EN(0, 0, (uint8 *)CUR_DATA, 32, 32);
        FillBoxWithBitmap(0, 0, &s_tsp[1]); 
        x1_bak = y1_bak = 0;    
    
        // 读取触摸屏输入,在相应位置上显示光标    
        while(1)
        {   // 读取新的触摸点 
            GetLCD_XY(&vx1, &vy1);      
                
            // 转换坐标值 
            x_1 = (vx1 - g_vx_min) * (229 - 10) / (g_vinx1 - g_vinx0);
            y_1 = (vy1 - g_vy_min) * (309 - 10) / (g_viny1 - g_viny0);
            if(x_1<0) x_1 = 0;
            if(y_1<0) y_1 = 0;        
            if(x_1>239) x_1 = 239;
            if(y_1>319) y_1 = 319;  
            
            // 判断是按钮命令
            if( (y_1>257) && (y_1<315) &&
                (x_1>4)   && (x_1<27)  )      // 参数保存
            {   //SaveChkData();  
                Beep();          
                Beep();                        
            }            
            if( (y_1>257) && (y_1<315) &&
                (x_1>40)  && (x_1<63)  )      // 重新校准
            {   Beep(); 
                break;                
            }
            
            // 不允许移动光标到屏幕上的按钮区(否则会破坏显示)
            // 保护矩形区域为(320-70-35,0) -- (319, 70+5)
            if((y_1>215) && (x_1<75)) continue;                        
        
            // 删除上一次的光标显示
            GUI_RectangleFill(x1_bak, y1_bak, x1_bak+32, y1_bak+32, BLACK);         
        
            // 显示光标        
            //GUI_LoadPic(x1, y1, (uint8 *)CUR_DATA, 32, 32);
            FillBoxWithBitmap(x_1, y_1, &s_tsp[1]);  
            x1_bak = x_1;
            y1_bak = y_1;        
        }  // end of while(1)...
    } // end of while(1)...
    
    return(0);
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -