網上有很多關于pos機觸摸屏幕壞了能修嗎,F7水星開發板資料連載第三十五章 觸摸屏實驗的知識,也有很多人為大家解答關于pos機觸摸屏幕壞了能修嗎的問題,今天pos機之家(www.www690aa.com)為大家整理了關于這方面的知識,讓我們一起來看下吧!
本文目錄一覽:
pos機觸摸屏幕壞了能修嗎
1)實驗平臺:正點原子水星 STM32F4/F7 開發板
2)摘自《STM32F7 開發指南(HAL 庫版)》關注官方微信號公眾號,獲取更多資料:正點原子
3)全套實驗源碼+手冊+視頻下載地址:http://www.openedv.com/thread-13912-1-1.html
第三十五章 觸摸屏實驗
本章,我們將介紹如何使用 STM32F767 來驅動觸摸屏,ALIENTEK 水星 STM32F767 開發
板本身并沒有觸摸屏控制器,但是它支持觸摸屏,可以通過外接帶觸摸屏的 LCD 模塊(比如
ALIENTEK LCD 模塊),來實現觸摸屏控制。在本章中,我們將向大家介紹 STM32 控制
ALIENTKE LCD 模塊(包括電阻觸摸與電容觸摸),實現觸摸屏驅動,最終實現一個手寫板的
功能。本章分為如下幾個部分:
35.1 電阻與電容觸摸屏簡介
35.2 硬件設計
35.3 軟件設計
35.4 下載驗證
35.1 觸摸屏簡介
目前最常用的觸摸屏有兩種:電阻式觸摸屏與電容式觸摸屏。下面,我們來分別介紹。
35.1.1 電阻式觸摸屏
在 Iphone 面世之前,幾乎清一色的都是使用電阻式觸摸屏,電阻式觸摸屏利用壓力感應進
行觸點檢測控制,需要直接應力接觸,通過檢測電阻來定位觸摸位置。
ALIENTEK 2.4/2.8/3.5 寸 LCD 模塊自帶的觸摸屏都屬于電阻式觸摸屏,下面簡單介紹下電
阻式觸摸屏的原理。
電阻觸摸屏的主要部分是一塊與顯示器表面非常配合的電阻薄膜屏,這是一種多層的復合
薄膜,它以一層玻璃或硬塑料平板作為基層,表面涂有一層透明氧化金屬(透明的導電電阻)
導電層,上面再蓋有一層外表面硬化處理、光滑防擦的塑料層、它的內表面也涂有一層涂層、
在他們之間有許多細小的(小于 1/1000 英寸)的透明隔離點把兩層導電層隔開絕緣。 當手指
觸摸屏幕時,兩層導電層在觸摸點位置就有了接觸,電阻發生變化,在 X 和 Y 兩個方向上產生
信號,然后送觸摸屏控制器。控制器偵測到這一接觸并計算出(X,Y)的位置,再根據獲得的
位置模擬鼠標的方式運作。這就是電阻技術觸摸屏的最基本的原理。
電阻觸摸屏的優點:精度高、價格便宜、抗干擾能力強、穩定性好。
電阻觸摸屏的缺點:容易被劃傷、透光性不太好、不支持多點觸摸。
從以上介紹可知,觸摸屏都需要一個 AD 轉換器,一般來說是需要一個控制器的。
ALIENTEK LCD 模塊選擇的是四線電阻式觸摸屏,這種觸摸屏的控制芯片有很多,包括:
ADS7843、ADS7846、TSC2046、XPT2046 和 AK4182 等。這幾款芯片的驅動基本上是一樣的,
也就是你只要寫出了 ADS7843 的驅動,這個驅動對其他幾個芯片也是有效的。而且封裝也有一
樣的,完全 PIN TO PIN 兼容。所以在替換起來,很方便。
ALIENTEK LCD 模塊自帶的觸摸屏控制芯片為 XPT2046。XPT2046 是一款 4 導線制觸摸
屏控制器,內含 12 位分辨率 125KHz 轉換速率逐步逼近型 A/D 轉換器。XPT2046 支持從 1.5V
到 5.25V 的低電壓 I/O 接口。XPT2046 能通過執行兩次 A/D 轉換查出被按的屏幕位置, 除此
之外,還可以測量加在觸摸屏上的壓力。內部自帶 2.5V 參考電壓可以作為輔助輸入、溫度測量
和電池監測模式之用,電池監測的電壓范圍可以從 0V 到 6V。XPT2046 片內集成有一個溫度傳
感器。在 2.7V 的典型工作狀態下,關閉參考電壓,功耗可小于 0.75mW。XPT2046 采用微小的
封裝形式:TSSOP-16,QFN-16(0.75mm 厚度)和 VFBGA-48。工作溫度范圍為-40℃~+85℃。
該芯片完全是兼容 ADS7843 和 ADS7846 的,關于這個芯片的詳細使用,可以參考這兩個芯片的 datasheet。
電阻式觸摸屏就介紹到這里。
35.1.2 電容式觸摸屏
現在幾乎所有智能手機,包括平板電腦都是采用電容屏作為觸摸屏,電容屏是利用人體感
應進行觸點檢測控制,不需要直接接觸或只需要輕微接觸,通過檢測感應電流來定位觸摸坐標。
ALIENTEK 4.3/7 寸 LCD 模塊自帶的觸摸屏采用的是電容式觸摸屏,下面簡單介紹下電容
式觸摸屏的原理。
電容式觸摸屏主要分為兩種:
1、 表面電容式電容觸摸屏。
表面電容式觸摸屏技術是利用 ITO(銦錫氧化物,是一種透明的導電材料)導電膜,通過電
場感應方式感測屏幕表面的觸摸行為進行。但是表面電容式觸摸屏有一些局限性,它只能識別
一個手指或者一次觸摸。
2、 投射式電容觸摸屏。
投射電容式觸摸屏是傳感器利用觸摸屏電極發射出靜電場線。一般用于投射電容傳感技術
的電容類型有兩種:自我電容和交互電容。
自我電容又稱絕對電容,是最廣為采用的一種方法,自我電容通常是指掃描電極與地構成
的電容。在玻璃表面有用 ITO 制成的橫向與縱向的掃描電極,這些電極和地之間就構成一個電
容的兩極。當用手或觸摸筆觸摸的時候就會并聯一個電容到電路中去,從而使在該條掃描線上
的總體的電容量有所改變。在掃描的時候,控制 IC 依次掃描縱向和橫向電極,并根據掃描前后
的電容變化來確定觸摸點坐標位置。筆記本電腦觸摸輸入板就是采用的這種方式,筆記本電腦
的輸入板采用 X*Y 的傳感電極陣列形成一個傳感格子,當手指靠近觸摸輸入板時,在手指和傳
感電極之間產生一個小量電荷。采用特定的運算法則處理來自行、列傳感器的信號來確定手指
的位置。
交互電容又叫做跨越電容,它是在玻璃表面的橫向和縱向的 ITO 電極的交叉處形成電容。
交互電容的掃描方式就是掃描每個交叉處的電容變化,來判定觸摸點的位置。當觸摸的時候就
會影響到相鄰電極的耦合,從而改變交叉處的電容量,交互電容的掃面方法可以偵測到每個交
叉點的電容值和觸摸后電容變化,因而它需要的掃描時間與自我電容的掃描方式相比要長一些,
需要掃描檢測 X*Y 根電極。目前智能手機/平板電腦等的觸摸屏,都是采用交互電容技術。
ALIENTEK 所選擇的電容觸摸屏,也是采用的是投射式電容屏(交互電容類型),所以后
面僅以投射式電容屏作為介紹。
透射式電容觸摸屏采用縱橫兩列電極組成感應矩陣,來感應觸摸。以兩個交叉的電極矩陣,
即: X 軸電極和 Y 軸電極,來檢測每一格感應單元的電容變化,如圖 35.1.2.1 所示:
圖 35.1.2.1 投射式電容屏電極矩陣示意圖
示意圖中的電極,實際是透明的,這里是為了方便大家理解。圖中,X、Y 軸的透明電極
電容屏的精度、分辨率與 X、Y 軸的通道數有關,通道數越多,精度越高。以上就是電容觸摸
屏的基本原理,接下來看看電容觸摸屏的優缺點:
電容觸摸屏的優點:手感好、無需校準、支持多點觸摸、透光性好。
電容觸摸屏的缺點:成本高、精度不高、抗干擾能力差。
這里特別提醒大家電容觸摸屏對工作環境的要求是比較高的,在潮濕、多塵、高低溫環境
下面,都是不適合使用電容屏的。
電容觸摸屏一般都需要一個驅動 IC 來檢測電容觸摸,且一般是通過 IIC 接口輸出觸摸數據
的。ALIENTEK 7’LCD 模塊的電容觸摸屏,使用 FT5206/FT5426 做為驅動 IC,采用的是 15*28
的驅動結構(15 個感應通道,28 個驅動通道)。ALIENTEK 4.3’LCD 模塊則使用
GT9147/OTT2001A 作為驅動 IC,采用 17*10 的驅動結構(10 個感應通道,17 個驅動通道)。
這兩個模塊都只支持最多 5 點觸摸,本例程除 CPLD 方案的 V1 版本 7 寸屏模塊不支持外,
其他所有 ALIENTEK 的 LCD 模塊都支持,電容觸摸驅動 IC,這里只介紹 GT9147 的驅動,
OTT2001A、FT5206 和 FT5426 的驅動同 GT9147 類似,大家可以參考著學習即可。
下面我們簡單介紹下 GT9147,該芯片是深圳匯頂科技研發的一顆電容觸摸屏驅動 IC,支
持 100Hz 觸點掃描頻率,支持 5 點觸摸,支持 18*10 個檢測通道,適合小于 4.5 寸的電容觸摸
屏使用。
GT9147 與 MCU 連接是通過 4 根線:SDA、SCL、RST 和 INT。其中:SDA 和 SCL 是 IIC
通信用的,RST 是復位腳(低電平有效),INT 是中斷輸出信號,關于 IIC 我們就不詳細介紹了,
請參考第二十九章。
GT9147 的 IIC 地址,可以是 0X14 或者 0X5D,當復位結束后的 5ms 內,如果 INT 是高電
平,則使用 0X14 作為地址,否則使用 0X5D 作為地址,具體的設置過程,請看:GT9147 數據
手冊.pdf 這個文檔。本章我們使用 0X14 作為器件地址(不含最低位,換算成讀寫命令則是讀:
0X29,寫:0X28),接下來,介紹一下 GT9147 的幾個重要的寄存器。
1,控制命令寄存器(0X8040)
該寄存器可以寫入不同值,實現不同的控制,我們一般使用 0 和 2 這兩個值,寫入 2,即
可軟復位 GT9147,在硬復位之后,一般要往該寄存器寫 2,實行軟復位。然后,寫入 0,即可
正常讀取坐標數據(并且會結束軟復位)。
2,配置寄存器組(0X8047~0X8100)
這里共 186 個寄存器,用于配置 GT9147 的各個參數,這些配置一般由廠家提供給我們(一
個數組),所以我們只需要將廠家給我們的配置,寫入到這些寄存器里面,即可完成 GT9147 的
配置。由于 GT9147可以保存配置信息(可寫入內部 FLASH,從而不需要每次上電都更新配置),
我們有幾點注意的地方提醒大家:1,0X8047 寄存器用于指示配置文件版本號,程序寫入的版
本號,必須大于等于 GT9147 本地保存的版本號,才可以更新配置。2,0X80FF 寄存器用于存
儲校驗和,使得 0X8047~0X80FF 之間所有數據之和為 0。3,0X8100 用于控制是否將配置保存
在本地,寫 0,則不保存配置,寫 1 則保存配置。
3,產品 ID 寄存器(0X8140~0X8143)
這里總共由 4 個寄存器組成,用于保存產品 ID,對于 GT9147,這 4 個寄存器讀出來就是:
9,1,4,7 四個字符(ASCII 碼格式)。因此,我們可以通過這 4 個寄存器的值,來判斷驅動
IC 的型號,從而判斷是 OTT2001A 還是 GT9147,以便執行不同的初始化。
4,狀態寄存器(0X814E)
該寄存器各位描述如表 35.1.2.1 所示:
表 35.1.2.1 狀態寄存器各位描述
這里,我們僅關心最高位和最低 4 位,最高位用于表示 buffer 狀態,如果有數據(坐標/
按鍵),buffer 就會是 1,最低 4 位用于表示有效觸點的個數,范圍是:0~5,0,表示沒有觸摸,
5 表示有 5 點觸摸。最后,該寄存器在每次讀取后,如果 bit7 有效,則必須寫 0,清除這個位,
否則不會輸出下一次數據!!這個要特別注意!!!
5,坐標數據寄存器(共 30 個)
這里共分成 5 組(5 個點),每組 6 個寄存器存儲數據,以觸點 1 的坐標數據寄存器組為例,
如表 35.1.2.2 所示:
表 35.1.2.2 觸點 1 坐標寄存器組描述
我們一般只用到觸點的 x,y 坐標,所以只需要讀取 0X8150~0X8153 的數據,組合即可得
到觸點坐標。其他 4 組分別是:0X8158、0X8160、0X8168 和 0X8170 等開頭的 16 個寄存器組
成,分別針對觸點 2~4 的坐標。GT9147 支持寄存器地址自增,我們只需要發送寄存器組的首
地址,然后連續讀取即可,GT9147 會自動地址自增,從而提高讀取速度。
GT9147 相關寄存器的介紹就介紹到這里,更詳細的資料,請參考:GT9147 編程指南.pdf
這個文檔。
GT9147 只需要經過簡單的初始化就可以正常使用了,初始化流程:硬復位→延時 10ms→
結束硬復位→設置 IIC 地址→延時 100ms→軟復位→更新配置(需要時)→結束軟復位。此時
GT9147 即可正常使用了。
然后,我們不停的查詢 0X814E 寄存器,判斷是否有有效觸點,如果有,則讀取坐標數據
寄存器,得到觸點坐標,特別注意,如果 0X814E 讀到的值最高位為 1,就必須對該位寫 0,否
則無法讀到下一次坐標數據。
特別說明:FT5206 和 FT5426 的驅動代碼完全一模一樣,他們只是版本號讀取的時候稍有差異,讀坐標數據和配置等操作完全是一模一樣的。所以,這兩個電容屏驅動 IC,可以共用
一個.c 文件(ft5206.c)。電容式觸摸屏部分,就介紹到這里。
35.2 硬件設計
本章實驗功能簡介:開機的時候先初始化 LCD,讀取 LCD ID,隨后,根據 LCD ID 判斷
是電阻觸摸屏還是電容觸摸屏,如果是電阻觸摸屏,則先讀取 24C02 的數據判斷觸摸屏是否已
經校準過,如果沒有校準,則執行校準程序,校準過后再進入電阻觸摸屏測試程序,如果已經
校準了,就直接進入電阻觸摸屏測試程序。
如果是 4.3 寸電容觸摸屏,則先讀取芯片 ID,判斷是不是 GT9147,如果是則執行 GT9147
的初始化代碼,如果不是,則執行 OTT2001A 的初始化代碼;如果是 7 寸電容觸摸屏(不支持
采用 CPLD 驅動的 7 寸 V1 屏),則執行 FT5206 的初始化代碼(兼容 FT5426),在初始化電
容觸摸屏完成后,進入電容觸摸屏測試程序(電容觸摸屏無需校準!!)。
電阻觸摸屏測試程序和電容觸摸屏測試程序基本一樣,只是電容觸摸屏支持最多 5 點同時
觸摸,電阻觸摸屏只支持一點觸摸,其他一模一樣。測試界面的右上角會有一個清空的操作區
域(RST),點擊這個地方就會將輸入全部清除,恢復白板狀態。使用電阻觸摸屏的時候,可
以通過按 KEY0 來實現強制觸摸屏校準,只要按下 KEY0 就會進入強制校準程序。
所要用到的硬件資源如下:
1) 指示燈 DS0
2) KEY0 按鍵
3) LCD 模塊(帶電阻/電容式觸摸屏)
4) 24C02
所有這些資源與 STM32F767 的連接圖,在前面都已經介紹了,這里我們只針對 LCD 模塊
與 STM32F767 的連接端口再說明一下,LCD 模塊的觸摸屏(電阻觸摸屏)總共有 5 跟線與
STM32F767 連接,連接電路圖如圖 35.2.1 所示:
圖 35.2.1 觸摸屏與 STM32F767 的連接圖
從圖中可以看出, T_MOSI、T_MISO、T_SCK、T_CS 和 T_PEN 分別連接在 STM32F767 的:PI3、
PG3、PH6、PI8 和 PH7 上。另外,水星 STM32F767 開發板有 2 種屏幕接口:RGB 屏和 MCU 屏,他
們共用觸摸屏接口(需分時復用)。
如果是電容式觸摸屏,我們的接口和電阻式觸摸屏一樣(上圖右側接口),只是沒有用到五根線了,而是四根線,分別是: T_PEN(CT_INT) 、 T_CS(CT_RST) 、 T_CLK(CT_SCL) 和
T_MOSI(CT_SDA)。其中:CT_INT、CT_RST、CT_SCL 和 CT_SDA 分別是 OTT2001A、GT9147、FT5206
和 FT5426 的:中斷輸出信號、復位信號,IIC 的 SCL 和 SDA 信號。這里,我們用查詢的方式讀
取數據,對于 OTT2001A/FT5206/FT5426 沒有用到中斷信號(CT_INT),所以同 STM32F767 的連
接,最少只需要 3 根線即可,不過 GT9147 還需要用到 CT_INT 做 IIC 地址設定,所以需要 4 根
線連接。
35.3 軟件設計
打開本章實驗工程目錄可以看到,我們在 HARDWARE 文件夾下新建了一個 TOUCH 文件
夾,然后新建了 touch.c、touch.h、ctiic.c、ctiic.h、ott2001a.c、ott2001a.h、gt9147.c、gt9147.h、
ft5206.c 和 ft5206.h 等十個文件用來存放觸摸屏相關的代碼。同時引入這些源文件到工程
HARDWARE 分組之下,并將 TOUCH 文件夾加入頭文件包含路徑。其中,touch.c 和 touch.h
是電阻觸摸屏部分的代碼,順帶兼電容觸摸屏的管理控制,其他則是電容觸摸屏部分的代碼。
打開 touch.c 文件,里面主要是與觸摸屏相關的代碼(主要是電阻觸摸屏的代碼),這里我
們也不全部貼出來了,僅介紹幾個重要的函數。
首先我們要介紹的是 TP_Read_XY2 這個函數,該函數專門用于從電阻式觸摸屏控制 IC 讀取
坐標的值(0~4095),TP_Read_XY2 的代碼如下:
//連續 2 次讀取觸摸屏 IC,且這兩次的偏差不能超過//ERR_RANGE,滿足條件,則認為讀數正確,否則讀數錯誤.//該函數能大大提高準確度//x,y:讀取到的坐標值//返回值:0,失敗;1,成功。#define ERR_RANGE 50 //誤差范圍u8 TP_Read_XY2(u16 *x,u16 *y){u16 x1,y1;u16 x2,y2;u8 flag; flag=TP_Read_XY(&x1,&y1); if(flag==0)return(0); flag=TP_Read_XY(&x2,&y2); if(flag==0)return(0); if(((x2<=x1&&x1<x2+ERR_RANGE)||(x1<=x2&&x2<x1+ERR_RANGE))//前后兩次采樣在+-50 內 &&((y2<=y1&&y1<y2+ERR_RANGE)||(y1<=y2&&y2<y1+ERR_RANGE))) { *x=(x1+x2)/2; *y=(y1+y2)/2; return 1; }else return 0;}
該函數采用了一個非常好的辦法來讀取屏幕坐標值,就是連續讀兩次,兩次讀取的值之差
不能超過一個特定的值(ERR_RANGE),通過這種方式,我們可以大大提高觸摸屏的準確度。另
外該函數調用的 TP_Read_XY 函數,用于單次讀取坐標值。TP_Read_XY 也采用了一些軟件濾波
算法,具體見光盤的源碼。接下來,我們介紹另外一個函數 TP_Adjust,該函數源碼如下:
//觸摸屏校準代碼//得到四個校準參數void TP_Adjust(void){u16 pos_temp[4][2];//坐標緩存值u8 cnt=0; u32 tem1,tem2;u16 d1,d2; u16 outtime=0;double fac;POINT_COLOR=BLUE;BACK_COLOR =WHITE;LCD_Clear(WHITE);//清屏POINT_COLOR=RED;//紅色LCD_Clear(WHITE);//清屏POINT_COLOR=BLACK;LCD_ShowString(40,40,160,100,16,(u8*)TP_REMIND_MSG_TBL);//顯示提示信息TP_Drow_Touch_Point(20,20,RED);//畫點 1tp_dev.sta=0;//消除觸發信號tp_dev.xfac=0;//xfac 用來標記是否校準過,所以校準之前必須清掉!以免錯誤while(1)//如果連續 10 秒鐘沒有按下,則自動退出{tp_dev.scan(1);//掃描物理坐標if((tp_dev.sta&0xc0)==TP_CATH_PRES) //按鍵按下了一次(此時按鍵松開了.){outtime=0;tp_dev.sta&=~(1<<6);//標記按鍵已經被處理過了.pos_temp[cnt][0]=tp_dev.x;pos_temp[cnt][1]=tp_dev.y;cnt++;switch(cnt){case 1:TP_Drow_Touch_Point(20,20,WHITE);//清除點 1TP_Drow_Touch_Point(lcddev.width="360px",height="auto" />
TP_Adjust 是此部分最核心的代碼,在這里,給大家介紹一下我們這里所使用的觸摸屏校
正原理:我們傳統的鼠標是一種相對定位系統,只和前一次鼠標的位置坐標有關。而觸摸屏則
是一種絕對坐標系統,要選哪就直接點哪,與相對定位系統有著本質的區別。絕對坐標系統的
特點是每一次定位坐標與上一次定位坐標沒有關系,每次觸摸的數據通過校準轉為屏幕上的坐
標,不管在什么情況下,觸摸屏這套坐標在同一點的輸出數據是穩定的。不過由于技術原理的
原因,并不能保證同一點觸摸每一次采樣數據相同,不能保證絕對坐標定位,點不準,這就是
觸摸屏最怕出現的問題:漂移。對于性能質量好的觸摸屏來說,漂移的情況出現并不是很嚴重。
所以很多應用觸摸屏的系統啟動后,進入應用程序前,先要執行校準程序。 通常應用程序中使
用的 LCD 坐標是以像素為單位的。比如說:左上角的坐標是一組非 0 的數值,比如(20,20),
而右下角的坐標為(220,300)。這些點的坐標都是以像素為單位的,而從觸摸屏中讀出的是點
的物理坐標,其坐標軸的方向、XY 值的比例因子、偏移量都與 LCD 坐標不同,所以,需要在
程序中把物理坐標首先轉換為像素坐標,然后再賦給 POS 結構,達到坐標轉換的目的。
校正思路:在了解了校正原理之后,我們可以得出下面的一個從物理坐標到像素坐標的轉
換關系式:
LCDx=xfac*Px+xoff;LCDy=yfac*Py+yoff;
其中(LCDx,LCDy)是在 LCD 上的像素坐標,(Px,Py)是從觸摸屏讀到的物理坐標。xfac,
yfac 分別是 X 軸方向和 Y 軸方向的比例因子,而 xoff 和 yoff 則是這兩個方向的偏移量。
這樣我們只要事先在屏幕上面顯示 4 個點(這四個點的坐標是已知的),分別按這四個點就
可以從觸摸屏讀到 4 個物理坐標,這樣就可以通過待定系數法求出 xfac、yfac、xoff、yoff 這四
個參數。我們保存好這四個參數,在以后的使用中,我們把所有得到的物理坐標都按照這個關
系式來計算,得到的就是準確的屏幕坐標。達到了觸摸屏校準的目的。
TP_Adjust 就 是根 據 上面 的 原理 設 計的 校準函 數 ,注 意 該函 數里面 多 次使 用 了
lcddev.width="360px",height="auto" />
接下來看看觸摸屏初始化函數:TP_Init,該函數根據 LCD 的 ID(即 lcddev.id)判別是電
阻屏還是電容屏,執行不同的初始化,該函數代碼如下:
//觸摸屏初始化//返回值:0,沒有進行校準// 1,進行過校準u8 TP_Init(void){ GPIO_InitTypeDef GPIO_Initure;if(lcddev.id==0X5510||lcddev.id==0X4342)//4.3 800*40MCU 電容觸摸屏或者 4.3 寸 480*272 RGB 屏{if(GT9147_Init()==0) //是 GT9147{tp_dev.scan=GT9147_Scan; //掃描函數指向 GT9147 觸摸屏掃描}else{OTT2001A_Init();tp_dev.scan=OTT2001A_Scan; //掃描函數指向 OTT2001A 觸摸屏掃描}tp_dev.touchtype|=0X80;//電容屏tp_dev.touchtype|=lcddev.dir&0X01;//橫屏還是豎屏return 0;}else if(lcddev.id==0X1963||lcddev.id==0X7084||lcddev.id==0X7016)//SSD1963 7 寸屏或者 7 寸 800*480/1024*600 RGB 屏{FT5206_Init();tp_dev.scan=FT5206_Scan;//掃描函數指向 GT9147 觸摸屏掃描tp_dev.touchtype|=0X80;//電容屏tp_dev.touchtype|=lcddev.dir&0X01;//橫屏還是豎屏return 0;}else{ __HAL_RCC_GPIOH_CLK_ENABLE(); //開啟 GPIOH 時鐘 __HAL_RCC_GPIOI_CLK_ENABLE(); //開啟 GPIOI 時鐘 __HAL_RCC_GPIOG_CLK_ENABLE(); //開啟 GPIOG 時鐘 //PH6 GPIO_Initure.Pin=GPIO_PIN_6; //PH6 GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽輸出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速HAL_GPIO_Init(GPIOH,&GPIO_Initure); //初始化 //PI3,8 GPIO_Initure.Pin=GPIO_PIN_3|GPIO_PIN_8; //PI3,8 HAL_GPIO_Init(GPIOI,&GPIO_Initure); //初始化 //PH7 GPIO_Initure.Pin=GPIO_PIN_7; //PH7 GPIO_Initure.Mode=GPIO_MODE_INPUT;//輸入 HAL_GPIO_Init(GPIOH,&GPIO_Initure); //初始化 //PG3 GPIO_Initure.Pin=GPIO_PIN_3; //PG3 HAL_GPIO_Init(GPIOG,&GPIO_Initure);//初始化TP_Read_XY(&tp_dev.x[0],&tp_dev.y[0]);//第一次讀取初始化AT24CXX_Init();//初始化 24CXXif(TP_Get_Adjdata())return 0;//已經校準else //未校準?{LCD_Clear(WHITE);//清屏TP_Adjust();//屏幕校準TP_Save_Adjdata();}TP_Get_Adjdata();}return 1;}
該函數比較簡單,重點說一下:tp_dev.scan,這個結構體函數指針,默認是指向 TP_Scan
的,如果是電阻屏則用默認的即可,如果是電容屏,則指向新的掃描函數 GT9147_Scan、
OTT2001A_Scan 或 FT5206_Scan(根據芯片 ID 判斷到底指向那個),執行電容觸摸屏的掃描函
數,這幾個函數在后續會介紹。
其他的函數我們這里就不多介紹了,接下來打開 touch.h 文件,代碼如下:
#define TP_PRES_DOWN 0x80 //觸屏被按下#define TP_CATH_PRES 0x40 //有按鍵按下了#define CT_MAX_TOUCH 5 //電容屏支持的點數,固定為 5 點//觸摸屏控制器typedef struct{u8 (*init)(void);//初始化觸摸屏控制器u8 (*scan)(u8);//掃描觸摸屏.0,屏幕掃描;1,物理坐標;void (*adjust)(void);//觸摸屏校準u16 x[CT_MAX_TOUCH];//當前坐標u16 y[CT_MAX_TOUCH]; //電容屏有最多 5 組坐標,電阻屏則用 x[0],y[0]代表//此次掃描時,觸屏的坐標,用 x[4],y[4]存儲第一次按下時的坐標.u8 sta; //筆的狀態 //b7:按下 1/松開 0; //b6:0,沒有按鍵按下;1,有按鍵按下. //b5:保留 //b4~b0:電容觸摸屏按下的點數(0,表示未按下,1 表示按下)/////////////////////觸摸屏校準參數(電容屏不需要校準)//////////////////////float xfac;float yfac;short xoff;short yoff;//新增的參數,當觸摸屏的左右上下完全顛倒時需要用到.//b0:0,豎屏(適合左右為 X 坐標,上下為 Y 坐標的 TP)// 1,橫屏(適合左右為 Y 坐標,上下為 X 坐標的 TP)//b1~6:保留.//b7:0,電阻屏// 1,電容屏u8 touchtype;}_m_tp_dev;extern _m_tp_dev tp_dev;//觸屏控制器在 touch.c 里面定義//電阻屏芯片連接引腳//電阻屏芯片連接引腳#define PEN HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_7) //T_PEN#define DOUT HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_3) //T_MISO#define TDIN(n) (n?HAL_GPIO_WritePin(GPIOI,GPIO_PIN_3,GPIO_PIN_SET): \\HAL_GPIO_WritePin(GPIOI,GPIO_PIN_3,GPIO_PIN_RESET))//T_MOSI#define TCLK(n) (n?HAL_GPIO_WritePin(GPIOH,GPIO_PIN_6,GPIO_PIN_SET): \\HAL_GPIO_WritePin(GPIOH,GPIO_PIN_6,GPIO_PIN_RESET))//T_SCK#define TCS(n) (n?HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_SET): \\HAL_GPIO_WritePin(GPIOI,GPIO_PIN_8,GPIO_PIN_RESET))//T_CS//電阻屏函數void TP_Write_Byte(u8 num);//向控制芯片寫入一個數據……//省略部分函數定義u8 TP_Init(void);//初始化#endif
上述代碼,我們重點看看_m_tp_dev 結構體,改結構體用于管理和記錄觸摸屏(包括電阻
觸摸屏與電容觸摸屏)相關信息。通過結構體,在使用的時候,我們一般直接調用 tp_dev 的相
關成員函數/變量屏即可達到需要的效果,這種設計簡化了接口,且方便管理和維護,大家可以效仿一下。
ctiic.c 和 ctiic.h 是電容觸摸屏的 IIC 接口部分代碼,與第二十九章的 myiic.c 和 myiic.h 基本
一樣,這里就不單獨介紹了。接下來看看文件 gt9147.c 代碼如下:
//GT9147 配置參數表//第一個字節為版本號(0X60),必須保證新的版本號大于等于 GT9147 內部//flash 原有版本號,才會更新配置.const u8 GT9147_CFG_TBL[]={0X60,0XE0,0X01,0X20,0X03,0X05,0X35,0X00,0X02,0X08,……//省略部分代碼0XFF,0XFF,0XFF,0XFF,};//發送 GT9147 配置參數//mode:0,參數不保存到 flash// 1,參數保存到 flashu8 GT9147_Send_Cfg(u8 mode){u8 buf[2];u8 i=0;buf[0]=0;buf[1]=mode; //是否寫入到 GT9147 FLASH? 即是否掉電保存for(i=0;i<sizeof(GT9147_CFG_TBL);i++)buf[0]+=GT9147_CFG_TBL[i];//計算校驗和 buf[0]=(~buf[0])+1;GT9147_WR_Reg(GT_CFGS_REG,(u8*)GT9147_CFG_TBL,sizeof(GT9147_CFG_TBL));//發送寄存器配置GT9147_WR_Reg(GT_CHECK_REG,buf,2);//寫入校驗和,和配置更新標記return 0;}//向 GT9147 寫入一次數據//reg:起始寄存器地址//buf:數據緩緩存區//len:寫數據長度//返回值:0,成功;1,失敗.u8 GT9147_WR_Reg(u16 reg,u8 *buf,u8 len){u8 i;u8 ret=0;CT_IIC_Start();CT_IIC_Send_Byte(GT_CMD_WR); //發送寫命令CT_IIC_Wait_Ack();CT_IIC_Send_Byte(reg>>8);//發送高 8 位地址CT_IIC_Wait_Ack();CT_IIC_Send_Byte(reg&0XFF);//發送低 8 位地址CT_IIC_Wait_Ack();for(i=0;i<len;i++){CT_IIC_Send_Byte(buf[i]);//發數據ret=CT_IIC_Wait_Ack();if(ret)break;} CT_IIC_Stop();//產生一個停止條件return ret;}//從 GT9147 讀出一次數據//reg:起始寄存器地址//buf:數據緩緩存區//len:讀數據長度void GT9147_RD_Reg(u16 reg,u8 *buf,u8 len){u8 i;CT_IIC_Start();CT_IIC_Send_Byte(GT_CMD_WR); //發送寫命令CT_IIC_Wait_Ack();CT_IIC_Send_Byte(reg>>8);//發送高 8 位地址CT_IIC_Wait_Ack();CT_IIC_Send_Byte(reg&0XFF); //發送低 8 位地址CT_IIC_Wait_Ack();CT_IIC_Start();CT_IIC_Send_Byte(GT_CMD_RD); //發送讀命令CT_IIC_Wait_Ack();for(i=0;i<len;i++){buf[i]=CT_IIC_Read_Byte(i==(len-1)?0:1); //發數據} CT_IIC_Stop();//產生一個停止條件}//初始化 GT9147 觸摸屏//返回值:0,初始化成功;1,初始化失敗u8 GT9147_Init(void){u8 temp[5]; GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOH_CLK_ENABLE(); //開啟 GPIOH 時鐘 __HAL_RCC_GPIOI_CLK_ENABLE();//開啟 GPIOI 時鐘//PH7 GPIO_Initure.Pin=GPIO_PIN_7; //PH7 GPIO_Initure.Mode=GPIO_MODE_INPUT;//輸入 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 HAL_GPIO_Init(GPIOH,&GPIO_Initure);//初始化 //PI8 GPIO_Initure.Pin=GPIO_PIN_8;//PI8 GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽輸出 HAL_GPIO_Init(GPIOI,&GPIO_Initure);//初始化CT_IIC_Init();//初始化電容屏的 I2C 總線GT_RST(0);//復位delay_ms(10);GT_RST(1);//釋放復位delay_ms(10); GPIO_Initure.Pin=GPIO_PIN_7; //PH7 GPIO_Initure.Mode=GPIO_MODE_INPUT; //輸入 GPIO_Initure.Pull=GPIO_NOPULL; //不帶上下拉,浮空輸入 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 HAL_GPIO_Init(GPIOH,&GPIO_Initure); //初始化delay_ms(100);GT9147_RD_Reg(GT_PID_REG,temp,4);//讀取產品 IDtemp[4]=0;printf("CTP ID:%s\\",temp);//打印 IDif(strcmp((char*)temp,"9147")==0)//ID==9147{temp[0]=0X02;GT9147_WR_Reg(GT_CTRL_REG,temp,1);//軟復位 GT9147GT9147_RD_Reg(GT_CFGS_REG,temp,1);//讀取 GT_CFGS_REG 寄存器if(temp[0]<0X60)//默認版本比較低,需要更新 flash 配置{printf("Default Ver:%d\\",temp[0]);if(lcddev.id==0X5510)GT9147_Send_Cfg(1);//更新并保存配置}delay_ms(10);temp[0]=0X00;GT9147_WR_Reg(GT_CTRL_REG,temp,1);//結束復位return 0;}return 1;}Const u16 GT9147_TPX_TBL[5]={GT_TP1_REG,GT_TP2_REG,GT_TP3_REG,GT_TP4_REG,GT_TP5_REG};//掃描觸摸屏(采用查詢方式)//mode:0,正常掃描.//返回值:當前觸屏狀態.//0,觸屏無觸摸;1,觸屏有觸摸u8 GT9147_Scan(u8 mode){u8 buf[4],i=0, res=0, temp, tempsta;static u8 t=0;//控制查詢間隔,從而降低 CPU 占用率t++;if((t)==0||t<10)//空閑時,每 10 次 CTP_Scan 函數才檢測 1 次,從而節省 CPU 使用率{GT9147_RD_Reg(GT_GSTID_REG,&mode,1); //讀取觸摸點的狀態if(mode&0X80&&((mode&0XF)<6)){temp=0;GT9147_WR_Reg(GT_GSTID_REG,&temp,1);//清標志}if((mode&0XF)&&((mode&0XF)<6)){temp=0XFF<<(mode&0XF); //將點的個數轉換為1 的位數,匹配 tp_dev.sta 定義tempsta=tp_dev.sta;//保存當前的 tp_dev.sta 值tp_dev.sta=(~temp)|TP_PRES_DOWN|TP_CATH_PRES;tp_dev.x[4]=tp_dev.x[0];//保存觸點 0 的數據tp_dev.y[4]=tp_dev.y[0];for(i=0;i<5;i++){if(tp_dev.sta&(1<<i)) //觸摸有效?{GT9147_RD_Reg(GT9147_TPX_TBL[i],buf,4); //讀取 XY 坐標值 if(lcddev.id==0X5510) //4.3 寸 800*480 MCU 屏 { if(tp_dev.touchtype&0X01)//橫屏 { tp_dev.y[i]=((u16)buf[1]<<8)+buf[0]; tp_dev.x[i]=800-(((u16)buf[3]<<8)+buf[2]); }else { tp_dev.x[i]=((u16)buf[1]<<8)+buf[0]; tp_dev.y[i]=((u16)buf[3]<<8)+buf[2]; } }else if(lcddev.id==0X4342) //4.3 寸 480*272 RGB 屏 {if(tp_dev.touchtype&0X01)//橫屏 { tp_dev.x[i]=(((u16)buf[1]<<8)+buf[0]); tp_dev.y[i]=(((u16)buf[3]<<8)+buf[2]); }else { tp_dev.y[i]=((u16)buf[1]<<8)+buf[0]; tp_dev.x[i]=272-(((u16)buf[3]<<8)+buf[2]); } }}}res=1;if(tp_dev.x[0]>lcddev.width="360px",height="auto" />
這里總共有 5 個函數:GT9147_Send_Cfg 函數用于發送 GT9147 的配置參數,在固件更新的
時候,需要用到;GT9147_WR_Reg 和 GT9147_RD_Reg 用于讀寫 GT9147 的寄存器;GT9147_Init
用于初始化 GT9147,該函數通過讀取 0X8140~0X8143 這 4 個寄存器,并判斷是否是:“9147”,
來確定是不是 GT9147 芯片,在讀取到正確的 ID 后,軟復位 GT9147,然后根據當前芯片版本號,
確定是否需要更新配置,通過 GT9147_Send_Cfg 函數,發送配置信息(一個數組),配置完后,
結束軟復位,即完成 GT9147 初始化;
最后,重點介紹:GT9147_Scan 函數,該函數用于掃描電容觸摸屏是否有按鍵下,由我們
是采用查詢的方式讀取數據,所以這里使了一個靜態變量(static)來提高效率當無觸摸時候
盡減少對 CPU 的占用,當有觸摸時候又保證能迅速檢測到。讀取數據時,先讀取狀態寄存器
(GT_GSTID_REG)的值,從而判斷觸摸點的個數(最多 5 個),然后依次讀取各觸摸點的坐
標數據,在讀取到數據后,還需要根據屏幕的分辨率和橫豎屏狀態進行坐標變換。另外,在遇
到非法數據的時候,需要對非法數據進行處理,以免干擾程序的正常運行。
對于文件 ott2001a.c、ft5206.c、ott2001a.h 和 ft5206.h 的代碼,我們就不再介紹了,
請大家參考光盤本例程源碼。需要注意的是:ft5206.c 同時支持 FT5206 和 FT5426 這兩顆觸
摸 IC,他們共用一個代碼。
最后我們打開 main.c,里面內容比較多,這里我們著重介紹三個主要函數:
//5 個觸控點的顏色(電容觸摸屏用)const u16 POINT_COLOR_TBL[5]={RED,GREEN,BLUE,BROWN,GRED};//電阻觸摸屏測試函數void rtp_test(void){u8 key;u8 i=0;while(1){key=KEY_Scan(0);tp_dev.scan(0);if(tp_dev.sta&TP_PRES_DOWN)//觸摸屏被按下{if(tp_dev.x[0]<lcddev.width="360px",height="auto" />
下面分別介紹一下這三個函數。
rtp_test,該函數用于電阻觸摸屏的測試,該函數代碼比較簡單,就是掃描按鍵和觸摸屏,
如果觸摸屏有按下,則在觸摸屏上面劃線,如果按中“RST”區域,則執行清屏。如果按鍵 KEY0
按下,則執行觸摸屏校準。
ctp_test,該函數用于電容觸摸屏的測試,由于我們采用 tp_dev.sta 來標記當前按下的觸摸
屏點數,所以判斷是否有電容觸摸屏按下,也就是判斷 tp_dev.sta 的最低 5 位,如果有數據,
則劃線,如果沒數據則忽略,且 5 個點劃線的顏色各不一樣,方便區分。另外,電容觸摸屏不
需要校準,所以沒有校準程序。
main 函數,則比較簡單,初始化相關外設,然后根據觸摸屏類型,去選擇執行 ctp_test 還
是 rtp_test。
軟件部分就介紹到這里,接下來看看下載驗證。
35.4 下載驗證
在代碼編譯成功之后,我們通過下載代碼到 ALIENTEK 水星 STM32 開發板上,電阻觸摸
屏測試如圖 35.4.1 所示界面:
圖 35.4.1 電阻觸摸屏測試程序運行效果
圖中我們在電阻屏上畫了一些內容,右上角的 RST 可以用來清屏,點擊該區域,即可清屏
重畫。另外,按 KEY0 可以進入校準模式,如果發現觸摸屏不準,則可以按 KEY0,進入校準,
重新校準一下,即可正常使用。
如果是電容觸摸屏,測試界面如圖 35.4.2 所示
圖 35.4.2 電容觸摸屏測試界面
圖中,同樣輸入了一些內容。電容屏支持多點觸摸,每個點的顏色都不一樣,圖中的波浪
線就是三點觸摸畫出來的,最多可以 5 點觸摸。注意:老款的 7 寸電容觸摸屏模塊(CPLD 方
案)本例程不支持!!
同樣,按右上角的 RST 標志,可以清屏。電容屏無需校準,所以按 KEY0 無效。KEY0 校
準僅對電阻屏有效。
以上就是關于pos機觸摸屏幕壞了能修嗎,F7水星開發板資料連載第三十五章 觸摸屏實驗的知識,后面我們會繼續為大家整理關于pos機觸摸屏幕壞了能修嗎的知識,希望能夠幫助到大家!
