S3C6410裸機(jī)電阻屏驅(qū)動(dòng)程序
使用的是RVDS4.0編譯的
大家主要是看看如何配置模式的
我之前一直使用自動(dòng)X,Y采樣,但是讀取的都不準(zhǔn),最后采樣分離的,才可以,需要注意的是使能ADC讀開(kāi)始后需要先讀轉(zhuǎn)換結(jié)果寄存器,但是此時(shí)讀取的是上一次的轉(zhuǎn)換結(jié)果,如果是連續(xù)讀取需要等待轉(zhuǎn)換完成,否則轉(zhuǎn)換結(jié)果不準(zhǔn).
?
adc.c
/*************************************************************************************************************
?*?文件名: ADC.c
?*?功能: S3C6410?ADC底層驅(qū)動(dòng)函數(shù)
?*?作者: cp1300@139.com
?*?創(chuàng)建時(shí)間: 2012年3月12日21:05
?*?最后修改時(shí)間:2012年3月12日
?*?詳細(xì): 觸摸屏驅(qū)動(dòng)以及相關(guān)ADC驅(qū)動(dòng)
?*?問(wèn)題: 一直以來(lái)存在一個(gè)誤區(qū),一直以為使用了啟動(dòng)開(kāi)始讀操作,每次讀DAT寄存器后就可以讀取到轉(zhuǎn)換后的數(shù)據(jù),最終發(fā)現(xiàn)使用這個(gè)后讀到的是上一次的數(shù)據(jù),
?*? 還是需要等到轉(zhuǎn)換完成,否則連續(xù)轉(zhuǎn)換的時(shí)候數(shù)據(jù)會(huì)非常亂.
?*? 現(xiàn)在使用的是手動(dòng)控制轉(zhuǎn)換開(kāi)始
*************************************************************************************************************/
#include?"system.h"
#include?"ADC.h"
//ADC的控制寄存器?ADCCON
#define?ADCCON_RESSEL_12BIT (1?<<?16) //12bit模式
#define?ADCCON_ECFLG? (0?<<?15) //A/D轉(zhuǎn)換結(jié)束標(biāo)志只讀;
#define?ADCCON_PRSCEN (1?<<?14) //A/D轉(zhuǎn)換器預(yù)分頻器使能
#define?ADCCON_PRSCVL (32 <<?6) //預(yù)分頻值,1-255,分頻值+1,至少為PCLK的1/5,此時(shí)PCLK?=?66MHZ,在2.5MHZ時(shí)鐘下轉(zhuǎn)換最快
#define?ADCCON_SEL_MUX (0 <<?3) //默認(rèn)選擇通道0
#define?ADCCON_STDBM (0 <<?2) //正常模式
#define?ADCCON_READ_START (0 <<?1) //關(guān)閉啟動(dòng)開(kāi)始讀操作
#define?ADCCON_ENABLE_START (0??<<?0) //如果READ_START?啟用,這個(gè)值是無(wú)效的。
//ADCDLY
#define?ADCDLY_DELAY 500 //自動(dòng)采樣延時(shí)時(shí)間,
/*************************************************************************************************************************
*函數(shù)????????: void?SetADC_Channel(u8?ch)
*功能????????: 設(shè)置ADC輸入通道
*參數(shù)????????: ch:通道號(hào),0-7
*返回????????: 無(wú)
*依賴????????:? 底層宏定義
*作者????????: cp1300@139.com
*時(shí)間????????: 20120513
*最后修改時(shí)間: 20120513
*說(shuō)明????????: ADC輸入通道選擇
*************************************************************************************************************************/
void?SetADC_Channel(u8?ch)
{
ADC->CON?&=?~(7?<<?3); //清除通道
ADC->CON?|=?ch?&?(0x07); //設(shè)置通道號(hào)
}
/*************************************************************************************************************************
*函數(shù)????????: void?ADC_Init(void)
*功能????????: ADC初始始化
*參數(shù)????????: 無(wú)
*返回????????: 無(wú)
*依賴????????:? 底層宏定義
*作者????????: cp1300@139.com
*時(shí)間????????: 20120312
*最后修改時(shí)間: 20120313
*說(shuō)明????????: ADC初始始化
*************************************************************************************************************************/
void?ADC_Init(void)
{
//ADC的控制寄存器配置;12BIT模式
ADC->CON?=?ADCCON_RESSEL_12BIT?+?ADCCON_ECFLG?+?ADCCON_PRSCEN?+?ADCCON_PRSCVL?+?ADCCON_SEL_MUX?+?ADCCON_STDBM?+?ADCCON_READ_START?+?ADCCON_ENABLE_START;
ADC->DLY?=?ADCDLY_DELAY; //設(shè)置自動(dòng)間隔采樣時(shí)間
}
/*************************************************************************************************************************
*函數(shù)????????: void?ADC_SetMode(u8?Mode)
*功能????????: 設(shè)置ADC模式
*參數(shù)????????: 無(wú)
*返回????????: 無(wú)
*依賴????????:? 底層宏定義
*作者????????: cp1300@139.com
*時(shí)間????????: 20120313
*最后修改時(shí)間: 20120313
*說(shuō)明????????: 設(shè)置ADC模式
*************************************************************************************************************************/
void?ADC_SetMode(u8?Mode)
{
ADC->TSC?&=?(1?<<?8); //清除原先設(shè)置
ADC->CON?&=?~BIT2; //退出待機(jī)模式
XP_UP_DISABLE(); //XP上拉禁止
Normal_ADC_Mode(); //普通ADC模式
switch(Mode)
{
case?COMMON_AD_MODER: //普通ADC模式
Normal_ADC_Mode();break;
case?ASUNDER_X_MODER: //分離的X掃描模式
{
ADCTSC_XP_VDD();
ADCTSC_XM_GND();
ADCTSC_YP_HZ();
ADCTSC_YM_HZ();
X_PosMode();
}break; //XP=外部電源,XM=GND,YP=AIN5,YM=高阻
case?ASUNDER_Y_MODER: //分離的Y掃描模式
{
ADCTSC_XP_HZ();
ADCTSC_XM_HZ();
ADCTSC_YP_VDD();
ADCTSC_YM_GND();
Y_PosMode();
}break; //XP=AIN7,XM=高阻,YP=外部電源,YM=GND
case?AUTO_XY_MODER: //自動(dòng)XY掃描模式
{
AUTO_XYPosition();
}break;
case?INT_AD_MODER: //等待中斷模式
{
ADCTSC_XP_HZ();
ADCTSC_XM_HZ();
ADCTSC_YP_HZ();
ADCTSC_YM_GND();
XP_UP_ENABLE(); //XP上拉使能
INT_WaitingMode();
}break;//XP上拉,XM=高阻,YP=AIN5,YM=GND
case?STANDBY_AD_MODER: //掉電模式
StandbyMode();break;
default:break;
}
}
/*************************************************************************************************************************
*函數(shù)????????: u16?ADC_ReadX(void)
*功能????????: 讀取X坐標(biāo)
*參數(shù)????????: 無(wú)
*返回????????: X坐標(biāo)原始坐標(biāo)值
*依賴????????:? 底層宏定義
*作者????????: cp1300@139.com
*時(shí)間????????: 20121006
*最后修改時(shí)間: 20121006
*說(shuō)明????????: 讀取的是ADC轉(zhuǎn)換寄存器0
*? 需要先設(shè)置ADC模式
*************************************************************************************************************************/
u16?ADC_ReadX(void)
{
ADC_Start(); //開(kāi)始一次ADC轉(zhuǎn)換
ADC_Wait(); //等待轉(zhuǎn)換完成
return?ADC_ReadData0();
}
/*************************************************************************************************************************
*函數(shù)????????: u16?ADC_ReadY(void)
*功能????????: 讀取Y坐標(biāo)
*參數(shù)????????: 無(wú)
*返回????????: Y坐標(biāo)原始坐標(biāo)值
*依賴????????:? 底層宏定義
*作者????????: cp1300@139.com
*時(shí)間????????: 20121006
*最后修改時(shí)間: 20121006
*說(shuō)明????????: 讀取的是ADC轉(zhuǎn)換寄存器1
*? 需要先設(shè)置ADC模式
*************************************************************************************************************************/
u16?ADC_ReadY(void)
{
ADC_Start(); //開(kāi)始一次ADC轉(zhuǎn)換
ADC_Wait(); //等待轉(zhuǎn)換完成
return?ADC_ReadData1();
}
/*************************************************************************************************************************
*函數(shù)????????: u8?Get_TouchState(void)
*功能????????: 獲取觸摸狀態(tài)
*參數(shù)????????: 無(wú)
*返回????????: 1:筆抬起;0:筆按下
*依賴????????:? 底層宏定義
*作者????????: cp1300@139.com
*時(shí)間????????: 20120315
*最后修改時(shí)間: 20120315
*說(shuō)明????????: 通過(guò)讀取ADCDAT1的BIT15來(lái)確定狀態(tài)
*************************************************************************************************************************/
u8?Get_TouchState(void)
{
return((ADC->DAT1?&?BIT15)???TOUCH_UP?:?TOUCH_DOWN);
}
//觸摸屏中斷服務(wù)函數(shù)
void?__irq?Isr_Touch(void)
{
TOUCH_ClearInt(); //清除觸摸屏中斷標(biāo)志
VICInterruptEnd(); //中斷結(jié)束
}
adc.h
/*************************************************************************************************************
?*?文件名: ADC.h
?*?功能: S3C6410?觸摸屏ADC底層驅(qū)動(dòng)函數(shù)
?*?作者: 陳鵬
?*?創(chuàng)建時(shí)間: 2012年3月12日21:05
?*?最后修改時(shí)間:2012年3月12日
?*?詳細(xì): 觸摸屏驅(qū)動(dòng)以及相關(guān)ADC驅(qū)動(dòng)
*************************************************************************************************************/
#ifndef _ADC_H_
#define?_ADC_H_
//按鍵狀態(tài) ?
#define?TOUCH_DOWN?0
#define?TOUCH_UP???1
#define?TOUCH_Posedge?0x01//筆抬起事件
#define?TOUCH_Negedge?0x02//筆按下事件
//ADC采樣模式
#define?COMMON_AD_MODER 0 //普通的AD轉(zhuǎn)換模式
#define?ASUNDER_X_MODER 1 //分離的X采樣模式
#define?ASUNDER_Y_MODER 2 //分離的Y采樣模式
#define?AUTO_XY_MODER 3 //自動(dòng)的X,Y采樣模式//不知道為何不準(zhǔn),只能用分離的X,Y掃描模式
#define?INT_AD_MODER 4 //等待中斷的采樣模式
#define?STANDBY_AD_MODER 5 //掉電模式
//ADC通道選擇
#define?ADC_CH_AIN0 0
#define?ADC_CH_AIN1 1
#define?ADC_CH_AIN2 2
#define?ADC_CH_AIN3 3
#define?ADC_CH_YM 4
#define?ADC_CH_YP 5
#define?ADC_CH_XM 6
#define?ADC_CH_XP 7
//讀取轉(zhuǎn)換寄存器0
#define?ADC_ReadData0() (ADC->DAT0&0xfff)
#define?ADC_ReadData1() (ADC->DAT1&0xfff)
//相關(guān)函數(shù)
void?ADC_Init(void); //初始化ADC
void?SetADC_Channel(u8?ch); //ADC通道選擇
void?ADC_SetMode(u8?Mode); //ADC工作模式設(shè)置
u8?Get_TouchState(void); //獲取觸摸筆狀態(tài)
u16?ADC_ReadX(void); //讀取X坐標(biāo)
u16?ADC_ReadY(void); //讀取Y坐標(biāo)
//使能筆抬起中斷
__inline?void?ADCTSC_UD_SEN?(u8?EN)
{
ADC->TSC?&=?~BIT8; //筆向下中斷
if(EN?==?ENABLE)
ADC->TSC?|=?BIT8;
}
//YM接GMD無(wú)效,接HZ
__inline?void?ADCTSC_YM_HZ(void)
{
ADC->TSC?&=?~BIT7;
}
//YM接GMD有效,接GND
__inline?void?ADCTSC_YM_GND(void)
{
ADC->TSC?|=?BIT7;
}
//YP接VDD無(wú)效,接HZ
__inline?void?ADCTSC_YP_HZ(void)
{
ADC->TSC?|=?BIT6;
}
//YP接VDD有效,接VDDA
__inline?void?ADCTSC_YP_VDD(void)
{
ADC->TSC?&=?~BIT6;
}
//XM接GMD無(wú)效,接HZ
__inline?void?ADCTSC_XM_HZ(void)
{
ADC->TSC?&=?~BIT5;
}
//XM接GMD有效,接GND
__inline?void?ADCTSC_XM_GND(void)
{
ADC->TSC?|=?BIT5;
}
//XP接VDD無(wú)效,接HZ
__inline?void?ADCTSC_XP_HZ(void)
{
ADC->TSC?|=?BIT4;
}
//XP接VDD有效,接VDDA
__inline?void?ADCTSC_XP_VDD(void)
{
ADC->TSC?&=?~BIT4;
}
//正常ADC轉(zhuǎn)換模式
__inline?void?Normal_ADC_Mode(void)
{
ADC->TSC?&=?~BIT2; //正常的ADC轉(zhuǎn)換
}
//待機(jī)模式
__inline?void?StandbyMode(void)
{
ADC->CON?|=?BIT2;
}
//自動(dòng)X,Y轉(zhuǎn)換
__inline?void?AUTO_XYPosition(void)
{
ADC->TSC?&=?~(BIT0+BIT1);
ADC->TSC?|=?BIT2; //自動(dòng)X,Y轉(zhuǎn)換
}
//X,Y手動(dòng)測(cè)量模式,沒(méi)有運(yùn)行模式
__inline?void?NO_OpeMode(void)
{
ADC->TSC?&=?~(BIT0+BIT1);
}
//X,Y手動(dòng)測(cè)量模式,X坐標(biāo)轉(zhuǎn)換模式
__inline?void?X_PosMode(void)
{
NO_OpeMode(); //清除設(shè)置
ADC->TSC?|=?1;
}
//X,Y手動(dòng)測(cè)量模式,Y坐標(biāo)轉(zhuǎn)換模式
__inline?void?Y_PosMode(void)
{
NO_OpeMode(); //清除設(shè)置
ADC->TSC?|=?2;
}
//X,Y手動(dòng)測(cè)量模式,等待中斷模式
__inline?void?INT_WaitingMode(void)
{
NO_OpeMode(); //清除設(shè)置
ADC->TSC?|=?3;
}
//XP上拉啟動(dòng)
__inline?void?XP_UP_ENABLE(void)
{
ADC->TSC?&=?~BIT3;
}
//XP上拉禁止
__inline?void?XP_UP_DISABLE(void)
{
ADC->TSC?|=?BIT3;
}
//清除ADC喚醒中斷
__inline?void?ADC_ClearInt(void)
{
ADC->CLRINT?=?0xffffffff; //寫入任何值清除中斷標(biāo)志
}
//清除觸摸屏中斷中斷
__inline?void?TOUCH_ClearInt(void)
{
ADC->UPDN?=?0; //清除ADC的觸摸屏UP-DOWN寄存器
ADC->CLRINTPNDNUP?=?0xffffffff; //寫入任何值清除中斷標(biāo)志
}
//開(kāi)始一次ADC轉(zhuǎn)換
__inline?void?ADC_Start(void)
{
ADC->CON?|=?BIT0; //開(kāi)始ADC轉(zhuǎn)換
}
//等待ADC轉(zhuǎn)換完成
__inline?void?ADC_Wait(void)
{
while(!(ADC->CON?&?BIT15));
}
#endif
touch.c
/*************************************************************************************************************
?*?文件名: Touch.c
?*?功能: S3C6410?電阻觸摸屏驅(qū)動(dòng)
?*?作者: cp1300@139.com
?*?創(chuàng)建時(shí)間: 2012年10月6日17:31
?*?最后修改時(shí)間:2012年10月6日
?*?詳細(xì): 需要底層的ADC支持
*************************************************************************************************************/
#include?"system.h"
#include?"adc.h"
#include?"touch.h"
Pen_Holder?Pen_Point;//定義筆實(shí)體
//開(kāi)啟觸摸屏校準(zhǔn),需要其它支持
#define?_TOUCH_ADJUST?1
#if?_TOUCH_ADJUST
void?TOUCH_Adjust(void); //觸摸屏校準(zhǔn)
#endif?//_TOUCH_ADJUST
/*************************************************************************************************************************
*函數(shù)????????: void?TOUCH_Init(FunctionalState?EnableInt)
*功能????????: 觸摸屏初始始化
*參數(shù)????????: EnableInt:筆中斷使能
*返回????????: 無(wú)
*依賴????????:? 底層宏定義
*作者????????: cp1300@139.com
*時(shí)間????????: 20120313
*最后修改時(shí)間: 20121006
*說(shuō)明????????: 觸摸屏初始始化
*************************************************************************************************************************/
void?TOUCH_Init(FunctionalState?EnableInt)
{
ADC_Init(); //初始化ADC
TOUCH_ClearInt(); //清除觸摸屏中斷標(biāo)志
ADC_ClearInt(); //清除ADC中斷
ADC_SetMode(INT_AD_MODER); //等待中斷模式
ADCTSC_UD_SEN(DISABLE); //設(shè)置為按下中斷
if(EnableInt?==?ENABLE) //開(kāi)啟筆中斷
{
//Set_IsrAddr(INT_PENDNUP,(u32)Isr_Touch); //設(shè)置中斷矢量入口
//Set_IntEnable(INT_PENDNUP,ENABLE); //開(kāi)啟觸摸屏按下
}
#if?_TOUCH_ADJUST
TOUCH_Adjust(); //觸摸屏校準(zhǔn)
#endif?//_TOUCH_ADJUST
}
/*************************************************************************************************************************
*?函數(shù) : u16?ADS_Read_XY(u16(*ADC_ReadXY)(void))
*?功能 : 使用冒泡法讀取一次坐標(biāo)
*?參數(shù) : ADC_ReadXY:X或Y坐標(biāo)讀取函數(shù)
*?返回 : 轉(zhuǎn)換結(jié)果
*?依賴 : ADC
*?作者 : cp1300@139.com
*?時(shí)間 : 20121006
*?最后修改時(shí)間?:?20121006
*?說(shuō)明 :? 連續(xù)讀取READ_TIMES次數(shù)據(jù),對(duì)這些數(shù)據(jù)升序排列,
然后去掉最低和最高LOST_VAL個(gè)數(shù),取平均值?
*************************************************************************************************************************/
#define?READ_TIMES?15?//讀取次數(shù)
#define?LOST_VAL?5 ??//丟棄值
u16?ADS_Read_XY(u16(*ADC_ReadXY)(void))
{
u16?i,?j;
u16?buff[READ_TIMES];
u16?sum=0;
u16?temp;
for(i?=?0;i?<?READ_TIMES;i?++)
{ ?
buff[i]?=?ADC_ReadXY(); ????
} ????
for(i?=?0;i?<?READ_TIMES?-?1;i?++)//排序
{
for(j?=?i?+?1;j?<?READ_TIMES;j?++)
{
if(buff[i]?>?buff[j])//升序排列
{
temp?=?buff[i];
buff[i]?=?buff[j];
buff[j]?=?temp;
}
}
} ??
sum?=?0;
for(i?=?LOST_VAL;i?<?READ_TIMES?-?LOST_VAL;i?++)
sum?+=?buff[i];
temp?=?sum?/?(READ_TIMES?-?2?*?LOST_VAL);
return?temp;???
}?
/*************************************************************************************************************************
*?函數(shù) : u8?Read_ADS(u16?*x,u16?*y)
*?功能 : 帶濾波的讀取X,Y坐標(biāo)
*?參數(shù) : X,Y坐標(biāo)值緩沖區(qū)指針
*?返回 : 1:轉(zhuǎn)換結(jié)果有效;0:轉(zhuǎn)換結(jié)果無(wú)效
*?依賴 : XPT2046底層函數(shù)
*?作者 : cp1300@139.com
*?時(shí)間 : 20120914
*?最后修改時(shí)間?:?20120914
*?說(shuō)明 :? 帶濾波的坐標(biāo)讀取
最小值不能少于MINI_ADC_DATA.
*************************************************************************************************************************/
#define?MINI_ADC_DATA 100
u8?Read_ADS(u16?*x,u16?*y)
{
u16?xtemp,?ytemp;
ADC_SetMode(ASUNDER_X_MODER); //設(shè)置ADC為分離的X采樣模式
xtemp?=?ADS_Read_XY(ADC_ReadX); //讀取X坐標(biāo)
ADC_SetMode(ASUNDER_Y_MODER); //設(shè)置ADC為分離的Y采樣模式
ytemp?=?ADS_Read_XY(ADC_ReadY); //讀取Y坐標(biāo)
ADC_SetMode(INT_AD_MODER); //設(shè)置ADC為等待中斷模式
if(xtemp?<?MINI_ADC_DATA?||?ytemp?<?MINI_ADC_DATA)
return?0;//讀數(shù)失敗
*x?=?xtemp;
*y?=?ytemp;
return?1;//讀數(shù)成功
}
/*************************************************************************************************************************
*?函數(shù) : u8?Read_ADS2(u16?*x,u16?*y)?
*?功能 : 連續(xù)讀取2次有效的AD值
*?參數(shù) : X,Y坐標(biāo)值緩沖區(qū)指針
*?返回 : 1:轉(zhuǎn)換結(jié)果有效;0:轉(zhuǎn)換結(jié)果無(wú)效
*?依賴 : u8?Read_ADS(u16?*x,u16?*y)
*?作者 : cp1300@139.com
*?時(shí)間 : 20120914
*?最后修改時(shí)間?:?20120914
*?說(shuō)明 :? 連續(xù)讀取2次有效的AD值,且這兩次的偏差不能超過(guò)ERR_RANGE
滿足條件,則認(rèn)為讀數(shù)正確,否則讀數(shù)錯(cuò)誤. ???
該函數(shù)能大大提高準(zhǔn)確度
*************************************************************************************************************************/
#define?ERR_RANGE?50? //誤差范圍?
u8?Read_ADS2(u16?*x,u16?*y)?
{
u16?x1,y1;
? u16?x2,y2;
? u8?flag;?
???
????flag?=?Read_ADS(&x1,&y1);???
????if(flag?==?0)
return(0);
????flag?=?Read_ADS(&x2,&y2); ???
????if(flag?==?0)
return(0);???
????if(((x2?<=?x1?&&?x1?<?x2?+?ERR_RANGE)?||?(x1?<=?x2?&&?x2?<?x1?+?ERR_RANGE))
??? ?&&?((y2?<=?y1?&&?y1?<?y2?+?ERR_RANGE)?||?(y1?<=?y2?&&?y2?<?y1?+?ERR_RANGE))) //前后兩次采樣在+-ERR_RANGE內(nèi)
????{
????????*x?=?(x1?+?x2)?/?2;
????????*y?=?(y1?+?y2)?/?2;
????????return?1;
????}
else?
return?0; ??
}
/*************************************************************************************************************************
*?函數(shù) : u8?TOUCH_ReadOneTP(void)
*?功能 : 讀取一次原始坐標(biāo)
*?參數(shù) : 無(wú)
*?返回 : 1:轉(zhuǎn)換結(jié)果有效;0:轉(zhuǎn)換結(jié)果無(wú)效
*?依賴 : u8?Read_ADS2(u16?*x,u16?*y)?
*?作者 : cp1300@139.com
*?時(shí)間 : 20120914
*?最后修改時(shí)間?:?20120914
*?說(shuō)明 :? 調(diào)用Read_ADS2函數(shù)進(jìn)行讀取,如果Read_ADS2讀取失敗,重復(fù)讀取,最多讀取MAX_READ_ADS次
如果失敗,將返回0,注意返回1代表結(jié)果有效
轉(zhuǎn)換的結(jié)果存放在結(jié)構(gòu)體Pen_Holder,的x0,y0中
*************************************************************************************************************************/
#define??MAX_READ_ADS 5 //最大重試次數(shù)
u8?TOUCH_ReadOneTP(void)
{
? u8?i;
u16?x,y;
for(i?=?MAX_READ_ADS;i?!=?0;i?--)
{
? if(Read_ADS2(&x,&y))
{
? Pen_Point.x0?=?x;? //轉(zhuǎn)換有效,存儲(chǔ)結(jié)果
Pen_Point.y0?=?y;
return?1; //返回成功
}
}
return?0; //返回失敗
}
/*************************************************************************************************************************
*?函數(shù) : void?TOUCH_ConvertPos(void)
*?功能 : 采集并轉(zhuǎn)換觸摸坐標(biāo)
*?參數(shù) : 無(wú)
*?返回 : 無(wú)
*?依賴 : LCD.C,觸摸屏ADC底層
*?作者 : cp1300@139.com
*?時(shí)間 : 20120914
*?最后修改時(shí)間?:?20121006
*?說(shuō)明 :? 根據(jù)觸摸屏的校準(zhǔn)參數(shù)來(lái)決定轉(zhuǎn)換后的結(jié)果,保存在x,y中
*? 需要先進(jìn)行觸摸校準(zhǔn)
*************************************************************************************************************************/
void?TOUCH_ConvertPos(void)
{ ? ??
if(TOUCH_ReadOneTP())
{
Pen_Point.x?=?Pen_Point.xfac?*?Pen_Point.x0?+?Pen_Point.xoff;
Pen_Point.y?=?Pen_Point.yfac?*?Pen_Point.y0?+?Pen_Point.yoff;??
}
}
//觸摸屏校準(zhǔn)相關(guān)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if?_TOUCH_ADJUST
#include?"TFT_LCD.h"
#include?"stdlib.h"
#include?"math.h"
#include?"delay.h"
/*************************************************************************************************************************
*?函數(shù) : void?Drow_Touch_Point(u16?x,u16?y)
*?功能 : 畫一個(gè)觸摸點(diǎn),用于校準(zhǔn)
*?參數(shù) : x,y:觸摸點(diǎn)中心位置
*?返回 : 無(wú)
*?依賴 : LCD.C
*?作者 : cp1300@139.com
*?時(shí)間 : 20120914
*?最后修改時(shí)間?:?20120914
*?說(shuō)明 :? 會(huì)調(diào)用LCD.C中的畫圓,畫線,畫矩形等函數(shù)
*************************************************************************************************************************/
void?Drow_Touch_Point(u16?x,u16?y)
{
Draw_Circle(x,y,10,0xf0f0);//畫圓
Draw_Circle(x,y,3,0xf0f0);//畫圓
LCD_DrawLine(x?-?15,?y,?x?+?15,?y,0xf0f0);//畫線
LCD_DrawLine(x,?y?-?15,?x,?y?+?15,0xf0f0);//畫線
LCD_DrawRectangle(x?-?10,y?-?10,x?+?10,y?+?10,0xf0f0);//畫矩形
}
/*************************************************************************************************************************
*?函數(shù) : void?TOUCH_Adjust(void)
*?功能 : 進(jìn)行觸摸屏校準(zhǔn)
*?參數(shù) : 無(wú)
*?返回 : 無(wú)
*?依賴 : LCD.C,觸摸屏ADC底層
*?作者 : cp1300@139.com
*?時(shí)間 : 20120914
*?最后修改時(shí)間?:?20120914
*?說(shuō)明 :? 得到四個(gè)校準(zhǔn)值
*? (20,20) (LCD_XSIZE-20,20)
*?
*?
*? (20,LCD_YSIZE-20) (LCD_XSIZE-20,LCD_YSIZE-20)
*************************************************************************************************************************/
void?TOUCH_Adjust(void)
{ ?
u16?pos_temp[4][2];//坐標(biāo)緩存值
u8??cnt=0;
u16?d1,d2;
u32?tem1,tem2;
float?fac;? ???
cnt=0;
LCD_ClearScreen(0xffff);//清屏???
Drow_Touch_Point(20,20);//畫點(diǎn)1?
//Pen_Point.xfac=0;//xfac用來(lái)標(biāo)記是否校準(zhǔn)過(guò),所以校準(zhǔn)之前必須清掉!以免錯(cuò)誤 ?
while(1)
{
if(GetPenStartus()?==?TOUCH_DOWN)//按鍵按下了
{
if(TOUCH_ReadOneTP())//得到單次按鍵值
{?? ???
pos_temp[cnt][0]=Pen_Point.x0;
pos_temp[cnt][1]=Pen_Point.y0;
cnt++;
}
while(GetPenStartus()?==?TOUCH_DOWN); //等待按鍵抬起 ?
switch(cnt)
{ ???
case?1:
LCD_ClearScreen(0xffff);//清屏??
Drow_Touch_Point(LCD_XSIZE-20,20);//畫點(diǎn)2
break;
case?2:
LCD_ClearScreen(0xffff);//清屏??
Drow_Touch_Point(20,LCD_YSIZE-20);//畫點(diǎn)3
break;
case?3:
LCD_ClearScreen(0xffff);//清屏?
Drow_Touch_Point(LCD_XSIZE-20,LCD_YSIZE-20);//畫點(diǎn)4
break;
case?4: ?//全部四個(gè)點(diǎn)已經(jīng)得到
???? ????//對(duì)邊相等
tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2
tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2
tem1*=tem1;
tem2*=tem2;
d1=sqrt(tem1+tem2);//得到1,2的距離
tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4
tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4
tem1*=tem1;
tem2*=tem2;
d2=sqrt(tem1+tem2);//得到3,4的距離
fac=(float)d1/d2;
if(fac1.05||d1==0||d2==0)//不合格
{
cnt=0;
LCD_ClearScreen(0xffff);//清屏??
Drow_Touch_Point(20,20);
continue;
}
tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3
tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3
tem1*=tem1;
tem2*=tem2;
d1=sqrt(tem1+tem2);//得到1,3的距離
tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4
tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4
tem1*=tem1;
tem2*=tem2;
d2=sqrt(tem1+tem2);//得到2,4的距離
fac=(float)d1/d2;
if(fac1.05)//不合格
{
cnt=0;
LCD_ClearScreen(0xffff);//清屏??
Drow_Touch_Point(20,20);
continue;
}//正確了
???
//對(duì)角線相等
tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3
tem2=abs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3
tem1*=tem1;
tem2*=tem2;
d1=sqrt(tem1+tem2);//得到1,4的距離
tem1=abs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4
tem2=abs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4
tem1*=tem1;
tem2*=tem2;
d2=sqrt(tem1+tem2);//得到2,3的距離
fac=(float)d1/d2;
if(fac1.05)//不合格
{
cnt=0;
LCD_ClearScreen(0xffff);//清屏??
Drow_Touch_Point(20,20);
continue;
}//正確了
//計(jì)算結(jié)果
Pen_Point.xfac=(float)(LCD_XSIZE-40)/(pos_temp[1][0]-pos_temp[0][0]);//得到xfac ?
Pen_Point.xoff=(LCD_XSIZE-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;//得到xoff
??
Pen_Point.yfac=(float)(LCD_YSIZE-40)/(pos_temp[2][1]-pos_temp[0][1]);//得到y(tǒng)fac
Pen_Point.yoff=(LCD_YSIZE-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到y(tǒng)off??
//Wire_Touch(); //存儲(chǔ)校準(zhǔn)結(jié)果
LCD_ClearScreen(0xffff);//清屏?
Show_Char(35,LCD_YSIZE/2,"Touch?Screen?Adjust?OK!",0xf800,0xffff,0x80);
Delay_MS(1000);
LCD_ClearScreen(0xffff);//清屏????
return;//校正完成 ?
}
}
}?
}
#endif?//_TOUCH_ADJUST
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
touch.h
/*************************************************************************************************************
?*?文件名: Touch.h
?*?功能: S3C6410?電阻觸摸屏驅(qū)動(dòng)
?*?作者: cp1300@139.com
?*?創(chuàng)建時(shí)間: 2012年10月6日17:31
?*?最后修改時(shí)間:2012年10月6日
?*?詳細(xì): 需要底層的ADC支持
*************************************************************************************************************/
#ifndef?TOUCH_H_
#define?TOUCH_H_
#include?"adc.h"
#ifndef?TOUCH_DOWN
#define?TOUCH_DOWN?0
#endif?//TOUCH_DOWN
#ifndef?TOUCH_UP
#define?TOUCH_UP?1
#endif?//TOUCH_UP
//筆桿結(jié)構(gòu)體
typedef?struct?
{
u16?x0;//原始坐標(biāo)
u16?y0;
u16?x;?//最終/暫存坐標(biāo)
u16?y; ??? ????
u8??Touch_Sta;//筆的狀態(tài) ??
//觸摸屏校準(zhǔn)參數(shù)
float?xfac;
float?yfac;
short?xoff;
short?yoff;
}Pen_Holder; ??????
extern?Pen_Holder?Pen_Point;//定義一個(gè)筆桿的結(jié)構(gòu)變量
void?TOUCH_Init(FunctionalState?EnableInt); //觸摸屏初始化函數(shù)
u8?TOUCH_ReadOneTP(void); //讀取一次坐標(biāo)
#define?GetPenStartus() Get_TouchState() //獲取觸摸筆狀態(tài)
void?TOUCH_ConvertPos(void); //獲取轉(zhuǎn)換后的實(shí)際坐標(biāo)
#endif?/*TOUCH_H_*/
主函數(shù)測(cè)試程序
main.c
#include?"system.h"
#include?"uart.h"
#include?"tft_lcd.h"
#include?"other.h"
#include?"delay.h"
#include?"timer.h"
#include?"touch.h"
//LED1閃爍程序,在定時(shí)器0中斷服務(wù)程序中閃爍,周期400MS
void?LED1_flash(void)
{
LED1_FLASH();
}
int?main(void)
{
LCD_Init(); //初始化LCD
UART0_Init(DISABLE,115200); //初始化串口,失能中斷接收,波特率115200
LED_Init(); //初始化LED
Timer1_Init(400000-1,ENABLE,LED1_flash); //初始化定時(shí)器0,周期400ms
TOUCH_Init(DISABLE); //初始化觸摸屏
lcd_printf("Get_FCLK?:?%d?Hzn",Get_FCLK());
lcd_printf("Get_PCLK?:?%d?Hzn",Get_PCLK());
while(1)
{
//LED2_FLASH(); //LED2閃爍
//Delay_US(600000);
if(GetPenStartus()?==?TOUCH_DOWN) //筆按下
{
TOUCH_ConvertPos();
//lcd_printf("X:%d;?Y:%dn",Pen_Point.x,Pen_Point.y);
Draw_Big_Point(Pen_Point.x,Pen_Point.y,0xf800);
Delay_MS(1);
}
}
}//補(bǔ)充ADC相關(guān)寄存器結(jié)構(gòu)
#define?ADC_BASE 0x7E00B000
//ADC?寄存器
typedef?struct
{
vu32 CON; //ADC控制寄存器?
vu32 TSC; //觸摸屏控制寄存器
vu32 DLY; //ADC開(kāi)始延遲寄存器
vu32 DAT0; //ADC數(shù)據(jù)寄存器0
vu32 DAT1; //ADC數(shù)據(jù)寄存器1
vu32 UPDN; //觸摸屏UP-DOWN寄存器
vu32 CLRINT; //ADC中斷清除寄存器
u32 Reserved;
vu32 CLRINTPNDNUP; //觸摸屏筆中斷寄存器
}ADC_TypeDef;
#define?ADC ((ADC_TypeDef*)ADC_BASE)




