使用的是RVDS4.0編譯的
大家主要是看看如何配置模式的
我之前一直使用自動X,Y采樣,但是讀取的都不準(zhǔn),最后采樣分離的,才可以,需要注意的是使能ADC讀開始后需要先讀轉(zhuǎn)換結(jié)果寄存器,但是此時讀取的是上一次的轉(zhuǎn)換結(jié)果,如果是連續(xù)讀取需要等待轉(zhuǎn)換完成,否則轉(zhuǎn)換結(jié)果不準(zhǔn).
?
adc.c
/************************************************************************************************************* ?*?文件名: ADC.c ?*?功能: S3C6410?ADC底層驅(qū)動函數(shù) ?*?作者: cp1300@139.com ?*?創(chuàng)建時間: 2012年3月12日21:05 ?*?最后修改時間:2012年3月12日 ?*?詳細(xì): 觸摸屏驅(qū)動以及相關(guān)ADC驅(qū)動 ?*?問題: 一直以來存在一個誤區(qū),一直以為使用了啟動開始讀操作,每次讀DAT寄存器后就可以讀取到轉(zhuǎn)換后的數(shù)據(jù),最終發(fā)現(xiàn)使用這個后讀到的是上一次的數(shù)據(jù), ?*? 還是需要等到轉(zhuǎn)換完成,否則連續(xù)轉(zhuǎn)換的時候數(shù)據(jù)會非常亂. ?*? 現(xiàn)在使用的是手動控制轉(zhuǎn)換開始 *************************************************************************************************************/ #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,此時PCLK?=?66MHZ,在2.5MHZ時鐘下轉(zhuǎn)換最快 #define?ADCCON_SEL_MUX (0 <<?3) //默認(rèn)選擇通道0 #define?ADCCON_STDBM (0 <<?2) //正常模式 #define?ADCCON_READ_START (0 <<?1) //關(guān)閉啟動開始讀操作 #define?ADCCON_ENABLE_START (0??<<?0) //如果READ_START?啟用,這個值是無效的。 //ADCDLY #define?ADCDLY_DELAY 500 //自動采樣延時時間, /************************************************************************************************************************* *函數(shù)????????: void?SetADC_Channel(u8?ch) *功能????????: 設(shè)置ADC輸入通道 *參數(shù)????????: ch:通道號,0-7 *返回????????: 無 *依賴????????:? 底層宏定義 *作者????????: cp1300@139.com *時間????????: 20120513 *最后修改時間: 20120513 *說明????????: ADC輸入通道選擇 *************************************************************************************************************************/ void?SetADC_Channel(u8?ch) { ADC->CON?&=?~(7?<<?3); //清除通道 ADC->CON?|=?ch?&?(0x07); //設(shè)置通道號 } /************************************************************************************************************************* *函數(shù)????????: void?ADC_Init(void) *功能????????: ADC初始始化 *參數(shù)????????: 無 *返回????????: 無 *依賴????????:? 底層宏定義 *作者????????: cp1300@139.com *時間????????: 20120312 *最后修改時間: 20120313 *說明????????: 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è)置自動間隔采樣時間 } /************************************************************************************************************************* *函數(shù)????????: void?ADC_SetMode(u8?Mode) *功能????????: 設(shè)置ADC模式 *參數(shù)????????: 無 *返回????????: 無 *依賴????????:? 底層宏定義 *作者????????: cp1300@139.com *時間????????: 20120313 *最后修改時間: 20120313 *說明????????: 設(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: //自動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ù)????????: 無 *返回????????: X坐標(biāo)原始坐標(biāo)值 *依賴????????:? 底層宏定義 *作者????????: cp1300@139.com *時間????????: 20121006 *最后修改時間: 20121006 *說明????????: 讀取的是ADC轉(zhuǎn)換寄存器0 *? 需要先設(shè)置ADC模式 *************************************************************************************************************************/ u16?ADC_ReadX(void) { ADC_Start(); //開始一次ADC轉(zhuǎn)換 ADC_Wait(); //等待轉(zhuǎn)換完成 return?ADC_ReadData0(); } /************************************************************************************************************************* *函數(shù)????????: u16?ADC_ReadY(void) *功能????????: 讀取Y坐標(biāo) *參數(shù)????????: 無 *返回????????: Y坐標(biāo)原始坐標(biāo)值 *依賴????????:? 底層宏定義 *作者????????: cp1300@139.com *時間????????: 20121006 *最后修改時間: 20121006 *說明????????: 讀取的是ADC轉(zhuǎn)換寄存器1 *? 需要先設(shè)置ADC模式 *************************************************************************************************************************/ u16?ADC_ReadY(void) { ADC_Start(); //開始一次ADC轉(zhuǎn)換 ADC_Wait(); //等待轉(zhuǎn)換完成 return?ADC_ReadData1(); } /************************************************************************************************************************* *函數(shù)????????: u8?Get_TouchState(void) *功能????????: 獲取觸摸狀態(tài) *參數(shù)????????: 無 *返回????????: 1:筆抬起;0:筆按下 *依賴????????:? 底層宏定義 *作者????????: cp1300@139.com *時間????????: 20120315 *最后修改時間: 20120315 *說明????????: 通過讀取ADCDAT1的BIT15來確定狀態(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ū)動函數(shù) ?*?作者: 陳鵬 ?*?創(chuàng)建時間: 2012年3月12日21:05 ?*?最后修改時間:2012年3月12日 ?*?詳細(xì): 觸摸屏驅(qū)動以及相關(guān)ADC驅(qū)動 *************************************************************************************************************/ #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 //自動的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無效,接HZ __inline?void?ADCTSC_YM_HZ(void) { ADC->TSC?&=?~BIT7; } //YM接GMD有效,接GND __inline?void?ADCTSC_YM_GND(void) { ADC->TSC?|=?BIT7; } //YP接VDD無效,接HZ __inline?void?ADCTSC_YP_HZ(void) { ADC->TSC?|=?BIT6; } //YP接VDD有效,接VDDA __inline?void?ADCTSC_YP_VDD(void) { ADC->TSC?&=?~BIT6; } //XM接GMD無效,接HZ __inline?void?ADCTSC_XM_HZ(void) { ADC->TSC?&=?~BIT5; } //XM接GMD有效,接GND __inline?void?ADCTSC_XM_GND(void) { ADC->TSC?|=?BIT5; } //XP接VDD無效,接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; } //自動X,Y轉(zhuǎn)換 __inline?void?AUTO_XYPosition(void) { ADC->TSC?&=?~(BIT0+BIT1); ADC->TSC?|=?BIT2; //自動X,Y轉(zhuǎn)換 } //X,Y手動測量模式,沒有運行模式 __inline?void?NO_OpeMode(void) { ADC->TSC?&=?~(BIT0+BIT1); } //X,Y手動測量模式,X坐標(biāo)轉(zhuǎn)換模式 __inline?void?X_PosMode(void) { NO_OpeMode(); //清除設(shè)置 ADC->TSC?|=?1; } //X,Y手動測量模式,Y坐標(biāo)轉(zhuǎn)換模式 __inline?void?Y_PosMode(void) { NO_OpeMode(); //清除設(shè)置 ADC->TSC?|=?2; } //X,Y手動測量模式,等待中斷模式 __inline?void?INT_WaitingMode(void) { NO_OpeMode(); //清除設(shè)置 ADC->TSC?|=?3; } //XP上拉啟動 __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)志 } //開始一次ADC轉(zhuǎn)換 __inline?void?ADC_Start(void) { ADC->CON?|=?BIT0; //開始ADC轉(zhuǎn)換 } //等待ADC轉(zhuǎn)換完成 __inline?void?ADC_Wait(void) { while(!(ADC->CON?&?BIT15)); } #endif
touch.c
/************************************************************************************************************* ?*?文件名: Touch.c ?*?功能: S3C6410?電阻觸摸屏驅(qū)動 ?*?作者: cp1300@139.com ?*?創(chuàng)建時間: 2012年10月6日17:31 ?*?最后修改時間:2012年10月6日 ?*?詳細(xì): 需要底層的ADC支持 *************************************************************************************************************/ #include?"system.h" #include?"adc.h" #include?"touch.h" Pen_Holder?Pen_Point;//定義筆實體 //開啟觸摸屏校準(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:筆中斷使能 *返回????????: 無 *依賴????????:? 底層宏定義 *作者????????: cp1300@139.com *時間????????: 20120313 *最后修改時間: 20121006 *說明????????: 觸摸屏初始始化 *************************************************************************************************************************/ 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) //開啟筆中斷 { //Set_IsrAddr(INT_PENDNUP,(u32)Isr_Touch); //設(shè)置中斷矢量入口 //Set_IntEnable(INT_PENDNUP,ENABLE); //開啟觸摸屏按下 } #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 *?時間 : 20121006 *?最后修改時間?:?20121006 *?說明 :? 連續(xù)讀取READ_TIMES次數(shù)據(jù),對這些數(shù)據(jù)升序排列, 然后去掉最低和最高LOST_VAL個數(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é)果無效 *?依賴 : XPT2046底層函數(shù) *?作者 : cp1300@139.com *?時間 : 20120914 *?最后修改時間?:?20120914 *?說明 :? 帶濾波的坐標(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é)果無效 *?依賴 : u8?Read_ADS(u16?*x,u16?*y) *?作者 : cp1300@139.com *?時間 : 20120914 *?最后修改時間?:?20120914 *?說明 :? 連續(xù)讀取2次有效的AD值,且這兩次的偏差不能超過ERR_RANGE 滿足條件,則認(rèn)為讀數(shù)正確,否則讀數(shù)錯誤. ??? 該函數(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ù) : 無 *?返回 : 1:轉(zhuǎn)換結(jié)果有效;0:轉(zhuǎn)換結(jié)果無效 *?依賴 : u8?Read_ADS2(u16?*x,u16?*y)? *?作者 : cp1300@139.com *?時間 : 20120914 *?最后修改時間?:?20120914 *?說明 :? 調(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)換有效,存儲結(jié)果 Pen_Point.y0?=?y; return?1; //返回成功 } } return?0; //返回失敗 } /************************************************************************************************************************* *?函數(shù) : void?TOUCH_ConvertPos(void) *?功能 : 采集并轉(zhuǎn)換觸摸坐標(biāo) *?參數(shù) : 無 *?返回 : 無 *?依賴 : LCD.C,觸摸屏ADC底層 *?作者 : cp1300@139.com *?時間 : 20120914 *?最后修改時間?:?20121006 *?說明 :? 根據(jù)觸摸屏的校準(zhǔn)參數(shù)來決定轉(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) *?功能 : 畫一個觸摸點,用于校準(zhǔn) *?參數(shù) : x,y:觸摸點中心位置 *?返回 : 無 *?依賴 : LCD.C *?作者 : cp1300@139.com *?時間 : 20120914 *?最后修改時間?:?20120914 *?說明 :? 會調(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ù) : 無 *?返回 : 無 *?依賴 : LCD.C,觸摸屏ADC底層 *?作者 : cp1300@139.com *?時間 : 20120914 *?最后修改時間?:?20120914 *?說明 :? 得到四個校準(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);//畫點1? //Pen_Point.xfac=0;//xfac用來標(biāo)記是否校準(zhǔn)過,所以校準(zhǔn)之前必須清掉!以免錯誤 ? 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);//畫點2 break; case?2: LCD_ClearScreen(0xffff);//清屏?? Drow_Touch_Point(20,LCD_YSIZE-20);//畫點3 break; case?3: LCD_ClearScreen(0xffff);//清屏? Drow_Touch_Point(LCD_XSIZE-20,LCD_YSIZE-20);//畫點4 break; case?4: ?//全部四個點已經(jīng)得到 ???? ????//對邊相等 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; }//正確了 ??? //對角線相等 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; }//正確了 //計算結(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(); //存儲校準(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ū)動 ?*?作者: cp1300@139.com ?*?創(chuàng)建時間: 2012年10月6日17:31 ?*?最后修改時間: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;//定義一個筆桿的結(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)換后的實際坐標(biāo) #endif?/*TOUCH_H_*/
主函數(shù)測試程序
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閃爍程序,在定時器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); //初始化定時器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開始延遲寄存器 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)