一、基本介紹
XPT2046是一種四線SPI接口、集成了複位電路和充電電路的電容式觸摸屏芯片,廣泛應用於各種移動智能終端、嵌入式系統和工業控制設備中。
XPT2046可以支持多種觸摸模式,包括電容式單點觸摸、電容式多點觸摸和壓力觸摸,支持多種傳輸模式和數據格式。
作為一個外圍設備,XPT2046並不會通過SPI主機發送請求,而是在XPT2046內部集成了一個循環掃描控制器,自主進行掃描以獲得觸摸數據,並將觸摸數據通過SPI接口發送到主機。
二、連接電路
XPT2046可以使用4條SPI線來與主控芯片通訊,包括SCK、MISO、MOSI和CS(Chip Select)。其中,SCK是時鐘線,MISO是主機的數據輸入線,MOSI是主機的數據輸出線,CS是片選線用於選中XPT2046芯片。
除了四根SPI線,XPT2046還需要一個複位電路和一個充電電路。複位電路可以使用一個複位IC或一個RC電路實現,充電電路可以使用一個限流二極管和一個電容器實現。
// 假設連接方式如下:
// CS - GPIO33
// SCK - GPIO32
// MISO - GPIO35
// MOSI - GPIO34
// INT - GPIO26
// RST - GPIO27
#include
#define CS_PIN 33
#define SCK_PIN 32
#define MISO_PIN 35
#define MOSI_PIN 34
#define INT_PIN 26
#define RST_PIN 27
void setup() {
pinMode(CS_PIN, OUTPUT); // 設置CS為輸出模式
digitalWrite(CS_PIN, HIGH); // 默認禁止片選
SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN); // 初始化SPI
SPI.setFrequency(4000000); // 設置SPI時鐘頻率為4MHz
pinMode(INT_PIN, INPUT_PULLUP); // 設置INT為上拉輸入,便於檢測觸摸事件
pinMode(RST_PIN, OUTPUT); // 設置RST為輸出模式
digitalWrite(RST_PIN, HIGH); // 默認複位禁止
}
void loop() {
// 待實現的代碼
}
三、讀取觸摸數據
XPT2046芯片內部集成了一個寄存器數組,用於記錄當前觸摸狀態、掃描計數、觸摸坐標等信息。在讀取觸摸數據之前,需要向XPT2046芯片發送一個0x80指令,表示讀取一個事件。XPT2046會自主掃描觸摸屏,並將觸摸數據通過SPI接口發送到主機。
在讀取觸摸數據時,需要注意到XPT2046可能會傳輸多個命令,因此需要不斷地接收數據並解析,直到讀取到一個有效的觸摸事件。一旦讀取到有效的觸摸事件,就可以從XPT2046芯片內部的寄存器數組中讀取觸摸坐標。
#define CMD_READ 0x80 // 讀取一個事件
#define CMD_X 0x90 // 讀取X坐標值
#define CMD_Y 0xd0 // 讀取Y坐標值
int readTouchX() {
int xRaw = 0;
digitalWrite(CS_PIN, LOW);
SPI.transfer(CMD_X);
xRaw = SPI.transfer16(0) >> 3;
digitalWrite(CS_PIN, HIGH);
return xRaw;
}
int readTouchY() {
int yRaw = 0;
digitalWrite(CS_PIN, LOW);
SPI.transfer(CMD_Y);
yRaw = SPI.transfer16(0) >>3;
digitalWrite(CS_PIN, HIGH);
return yRaw;
}
bool readTouchPoint(int &x, int &y) {
if (digitalRead(INT_PIN) == LOW) { // 檢測觸摸事件
digitalWrite(RST_PIN, LOW); // 啟用複位
digitalWrite(CS_PIN, LOW); // 允許片選
SPI.transfer(CMD_READ); // 發送讀取事件指令
x = readTouchX(); // 讀取X坐標
y = readTouchY(); // 讀取Y坐標
digitalWrite(CS_PIN, HIGH); // 禁止片選
digitalWrite(RST_PIN, HIGH); // 禁用複位
return true;
} else {
return false;
}
}
四、觸摸坐標轉換
由於觸摸屏的尺寸和分辨率各異,因此需要將XPT2046芯片讀取出來的原始觸摸坐標轉換為實際屏幕坐標。觸摸坐標轉換可以通過一組公式實現。
其中,觸摸坐標Xc和Yc是從XPT2046芯片內部寄存器中讀取到的原始坐標,觸摸屏尺寸為W和H,觸摸坐標X和Y是實際屏幕坐標:
X = ((Xc * a + Yc * b + c) / d) * W
Y = ((Xc * e + Yc * f + g) / h) * H
其中,a、b、c、d、e、f、g和h均是校準係數,根據實際觸摸屏進行調整。校準係數可以通過在不同位置嘗試觸摸,記錄下相應的觸摸坐標和實際屏幕坐標,然後通過線性方程組求解得到。
#define TOUCH_WIDTH 240
#define TOUCH_HEIGHT 320
float calA = 0.012367262544294;
float calB = -0.001709139042816;
float calC = -19.316064986921131;
float calD = 1.838251825135559;
float calE = -0.000992525359333;
float calF = 0.195498693029731;
float calG = -46.090023031789299;
float calH = 2.038698937062327;
bool readTouchPoint(int &x, int &y) {
if (digitalRead(INT_PIN) == LOW) { // 檢測觸摸事件
digitalWrite(RST_PIN, LOW); // 啟用複位
digitalWrite(CS_PIN, LOW); // 允許片選
SPI.transfer(CMD_READ); // 發送讀取事件指令
int xRaw = readTouchX(); // 讀取X坐標
int yRaw = readTouchY(); // 讀取Y坐標
digitalWrite(CS_PIN, HIGH); // 禁止片選
digitalWrite(RST_PIN, HIGH); // 禁用複位
x = ((xRaw * calA + yRaw * calB + calC) / calD) * TOUCH_WIDTH;
y = ((xRaw * calE + yRaw * calF + calG) / calH) * TOUCH_HEIGHT;
return true;
} else {
return false;
}
}
五、觸摸應用示例
XPT2046可以廣泛應用於各種移動智能終端、嵌入式系統和工業控制設備中。下面是一個簡單的觸摸應用示例,通過讀取觸摸數據,控制LED的亮滅。
在這個示例中,將在屏幕上劃分出四個區域,分別對應四個LED。當用戶觸摸到各個區域時,相應的LED會亮起或熄滅。
int LED_1 = 12;
int LED_2 = 13;
int LED_3 = 14;
int LED_4 = 15;
void setup() {
// 初始化IO
pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
pinMode(LED_3, OUTPUT);
pinMode(LED_4, OUTPUT);
}
void loop() {
int x, y;
if (readTouchPoint(x, y)) {
if (x < 120 && y = 120 && y < 160) {
digitalWrite(LED_2, HIGH);
} else {
digitalWrite(LED_2, LOW);
}
if (x = 160) {
digitalWrite(LED_3, HIGH);
} else {
digitalWrite(LED_3, LOW);
}
if (x >= 120 && y >= 160) {
digitalWrite(LED_4, HIGH);
} else {
digitalWrite(LED_4, LOW);
}
}
}
六、總結
XPT2046是一款成熟的電容式觸摸芯片,具有靈敏度高、讀取精度高等優點,可以廣泛應用於各種移動智能終端、嵌入式系統和工業控制設備中。使用XPT2046需要注意到連接電路、讀取觸摸數據、觸摸坐標轉換等問題,並可以使用校準係數來調整觸摸坐標的精度。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/236767.html
微信掃一掃
支付寶掃一掃