?
一、環(huán)境介紹
編程語(yǔ)言: C語(yǔ)言
編程風(fēng)格: 寄存器開(kāi)發(fā).
目標(biāo)芯片: XPT2046---標(biāo)準(zhǔn)SPI接口時(shí)序
二、XPT2046芯片介紹
2.1 功能
XPT2046是一顆12位的ADC芯片,可以當(dāng)做普通的ADC芯片使用,但是一般都是用在電阻觸摸屏上,方便定位觸摸屏坐標(biāo)。
?
圖1: XPT2046內(nèi)部原理圖
?
圖2:電阻觸摸屏---引出的4條線就接在XPT2046的YNXNYPXP上
(XPT2046支持筆中斷輸出--低電平有效,這個(gè)引腳可以配置到單片機(jī)的中斷腳上,或者輪詢判斷這個(gè)引腳狀態(tài),判斷觸摸屏是否已經(jīng)按下)
可以單獨(dú)買一個(gè)觸摸屏+一個(gè)XPT2046就可以自己做手畫(huà)板、觸摸按鍵(自己用一張紙?jiān)谙旅娈?huà)個(gè)模型就行)、等等很多小玩意。
?
圖3:采用的電阻觸摸屏的LCD屏(上面蓋的哪一層薄膜就是觸摸用的)
?
2.2 特性
1. 工作電壓范圍為 2.2V~5.25V
2. 支持 1.5V~5.25V 的數(shù)字 I/O 口
3. 內(nèi)建 2.5V 參考電壓源
4. 電源電壓測(cè)量(0V~6)
5. 內(nèi)建溫度測(cè)量功能
6. 觸摸壓力測(cè)量
7. 采用 SPI 3線控制通信接口
8. 具有自動(dòng) power-down 功能
9. 封裝:QFN-16、 TSSOP-16 和 VFBGA-48與 TSC2046、 AK4182A 完全兼容
10. XPT2046 在 125KHz 轉(zhuǎn)換速率和 2.7V 電壓下的功耗僅為750 μW。 XPT2046 11. 以其低功耗和高速率等特性,被廣泛應(yīng)用在采用電池供電的小型手持設(shè)備上,比如 PDA、手機(jī)等。
12. XPT2046 有 TSSOP-16、 QFN-16 和 VFBGA 三種封裝形
式,溫度范圍是 - 40 ~ + 85℃ 。
2.3工作原理
XPT2046 是一種典型的逐次逼近型模數(shù)轉(zhuǎn)換器(SAR ADC),包含了采樣/保持、模數(shù)轉(zhuǎn)換、串口數(shù)據(jù)輸出等功能。同時(shí)芯片集成有一個(gè) 2.5V的內(nèi)部參考電壓源、溫度檢測(cè)電路,工作時(shí)使用外部時(shí)鐘。 XPT2046 可以單電源供電,電源電壓范圍為 2.7V~5.5V。參考電壓值直接決定ADC的輸入范圍,參考電壓可以使用內(nèi)部參考電壓,也可以從外部直接輸入1V~VCC范圍內(nèi)的參考電壓(要求外部參考電壓源輸出阻抗低)。 X、 Y、 Z、 VBAT、 Temp和AUX模擬信號(hào)經(jīng)過(guò)片內(nèi)的
控制寄存器選擇后進(jìn)入ADC, ADC可以配置為單端或差分模式。選擇VBAT、 Temp和AUX時(shí)可以配置為單端模式;作為觸摸屏應(yīng)用時(shí),可以配置為差分模式,這可有效消除由于驅(qū)動(dòng)開(kāi)關(guān)的寄生電阻及外部的干擾帶來(lái)的測(cè)量誤差,提高轉(zhuǎn)換準(zhǔn)確度。
典型的應(yīng)用:
?
單端工作模式
SER/DFR置為高電平時(shí), XPT2046 工作在為單端模式,單端工作模式的應(yīng)用原理如下圖所示。
單端模式簡(jiǎn)單,在采樣過(guò)程完成后,轉(zhuǎn)換過(guò)程中可以關(guān)閉驅(qū)動(dòng)開(kāi)關(guān),降低功耗。但這種模式的缺點(diǎn)是精度直接受參考電壓源的精度限制,同時(shí)由于內(nèi)部驅(qū)動(dòng)開(kāi)關(guān)的導(dǎo)通電阻存在,導(dǎo)通電阻與觸摸屏電阻的分壓作用,也會(huì)帶來(lái)測(cè)量誤差。
(圖片里的A2 A1 A0 ,還有上面說(shuō)的SER/DFR就是XPT2046的配置命令,具體使用方法在后面會(huì)講到)
?
差分工作模式
SER/DFR置為低電平時(shí), XPT2046 為差分工作模式.
差分模式的優(yōu)點(diǎn)是: +REF 和-REF 的輸入分別直接接到 YP、 YN 上,可消除由于驅(qū)動(dòng)開(kāi)關(guān)的導(dǎo)通電阻引入的坐標(biāo)測(cè)量誤差。
缺點(diǎn)是:無(wú)論是采樣還是轉(zhuǎn)換過(guò)程中,驅(qū)動(dòng)開(kāi)關(guān)都需要接通,相對(duì)單端模式而言,功耗增加了。
如果不考慮功耗的話,當(dāng)前就選擇差分工作模式了。
(圖片里的A2 A1 A0 ,還有上面說(shuō)的SER/DFR就是XPT2046的配置命令,具體使用方法在后面會(huì)講到)
?
2.3 XPT2046采集并轉(zhuǎn)換一次數(shù)據(jù)的時(shí)序介紹
XPT2046 數(shù)據(jù)接口是串行接口,處理器和轉(zhuǎn)換器之間的通信需要 8 個(gè)時(shí)鐘周期,可采用 SPI、 SSI 和 Microwire 等同步串行接口。一次完整的轉(zhuǎn)換需要 24 個(gè)串行同步時(shí)鐘(DCLK)來(lái)完成。
前 8 個(gè)時(shí)鐘用來(lái)通過(guò)DIN引腳輸入控制字節(jié)。當(dāng)轉(zhuǎn)換器獲取有關(guān)下一次轉(zhuǎn)換的足夠信息后,接著根據(jù)獲得的信息設(shè)置輸入多路選擇器和參考源輸入,并進(jìn)入采樣模式,如果需要,將啟動(dòng)觸摸面板驅(qū)動(dòng)器。 3 個(gè)多時(shí)鐘周期后,控制字節(jié)設(shè)置完成,轉(zhuǎn)換器進(jìn)入轉(zhuǎn)換狀態(tài)。這時(shí),輸入采樣-保持器進(jìn)入保持狀態(tài),觸摸面板驅(qū)動(dòng)器停止工作(單端工作模式)。
接著的12 個(gè)時(shí)鐘周期將完成真正的模數(shù)轉(zhuǎn)換。如果是度量比率轉(zhuǎn)換方式(SER/DFR ——=0),驅(qū)動(dòng)器在轉(zhuǎn)換過(guò)程中將一直工作,第13 個(gè)時(shí)鐘將輸出轉(zhuǎn)換結(jié)果的最后一位。剩下的 3 個(gè)多時(shí)鐘周期將用來(lái)完成被轉(zhuǎn)換器忽略的最后字節(jié)(DOUT置低)。
時(shí)序圖如下:
?
時(shí)序圖里的控制命令字節(jié):
位 7(MSB) | 位 6 | 位 5 | 位 4 | 位 3 | 位 2 | 位 1 | 位 0(LSB) |
S | A2 | A1 | A0 | MODE | SER/DFR | PD1 | PD0 |
控制字節(jié)每個(gè)位的含義如下:
位 | 名稱 | 功能描述 |
7 | S | 開(kāi)始位。為 1 表示一個(gè)新的控制字節(jié)到來(lái),為 0 則忽略 PIN 引腳上數(shù)據(jù) |
6-4 | A2-A0 | 通道選擇位。這個(gè)在上面已經(jīng)介紹過(guò)了 |
3 | MODE | 12 位/8 位轉(zhuǎn)換分辨率選擇位。為 1 選擇 8 位為轉(zhuǎn)換分辨率,為 0 選擇 12 位分辨率 |
2 | SER/DFR | 單端輸入方式/ 差分輸入方式選擇位。為 1 是單端輸入方式,為 0 是差分輸入方式 |
1-0 | PD1-PD0 |
低功率模式選擇位。若為11,器件總處于供電狀態(tài);若為00,器件在變換之間處于低 功率模式 |
注意: 差分模式僅用于 X 坐標(biāo)、 Y 坐標(biāo)和觸摸壓力的測(cè)量,其它測(cè)量要求采用單端模式。
根據(jù)上面表格的介紹,可以得到在差分模式下,選擇12位分辨率,測(cè)量X和Y坐標(biāo)的兩個(gè)命令:0xD0 和 0x90
XPT2046還有其他模式,可以測(cè)量溫度,筆中斷的開(kāi)關(guān)(默認(rèn)是開(kāi)著的),16時(shí)鐘周期轉(zhuǎn)換,15時(shí)鐘周期轉(zhuǎn)換,這些就不再介紹。 根據(jù)前面的介紹用在觸摸屏上測(cè)量XY坐標(biāo)的功能已經(jīng)滿足了。
2.4 SPI時(shí)序介紹
這里的XPT2046支持標(biāo)準(zhǔn)3線SPI接口,關(guān)于SPI時(shí)序的介紹,在前面文章里有介紹過(guò)。
參考這里:STM32入門開(kāi)發(fā): 介紹SPI總線、讀寫(xiě)W25Q64(FLASH)(硬件+模擬時(shí)序)_DS小龍哥的專欄-CSDN博客_w25q64
2.5 物理坐標(biāo)與屏幕坐標(biāo)的轉(zhuǎn)換
正常在LCD屏上使用觸摸屏,肯定是需要將采集的原始X、Y值轉(zhuǎn)為L(zhǎng)CD屏的屏幕坐標(biāo)才好使用。
轉(zhuǎn)換的方法有很多,這里采用最簡(jiǎn)單的角系數(shù)計(jì)算方法轉(zhuǎn)換。
比如,我使用的LCD屏是3.5寸的,分辨率是320*480。
1. 得到觸摸屏左上角和右下角的坐標(biāo)XY極限值
x=3831,y=3934
x=155,y=168
2. 轉(zhuǎn)換坐標(biāo)值
x坐標(biāo):3831~155 --> 3676~0
y坐標(biāo):3934~168 --> 3766~0
3. 計(jì)算斜率
x坐標(biāo)的斜率: 3676/320=11.4875
y坐標(biāo)的斜率: 3766/480=7.84583
4. 得到實(shí)際的像素坐標(biāo)
x坐標(biāo): 320-(實(shí)時(shí)采集的當(dāng)前X模擬量-155)/11.4875
y坐標(biāo): 480-(實(shí)時(shí)采集的當(dāng)前Y模擬量-168)/7.84583
這里相減的原因: 因?yàn)槲覝y(cè)試用的觸摸屏采集出來(lái)的X、Y值大小和LCD屏的屏幕坐標(biāo)值大小是反過(guò)來(lái)的。
三、示例代碼
采用SPI模擬時(shí)序驅(qū)動(dòng),其他平臺(tái)都可以移植。
3.1 xpt2046.c
#include "xpt2046_touch.h"
struct XPT2046_TOUCH xpt2046_touch;
/*
函數(shù)功能: 初始化
硬件連接:
T_MOSI--PF9
T_MISO--PB2
T_SCK---PB1
T_PEN---PF10
T_CS----PF11
*/
void XPT2046_TouchInit(void)
{
/*1. 時(shí)鐘初始化*/
RCC->APB2ENR|=1<<3; //PB
RCC->APB2ENR|=1<<7; //PF
/*2. 初始化GPIO口*/
GPIOB->CRL&=0xFFFFF00F;
GPIOB->CRL|=0x00000830;
GPIOF->CRH&=0xFFFF000F;
GPIOF->CRH|=0x00003830;
/*3. 上拉*/
GPIOB->ODR|=0x3<<1;
GPIOF->ODR|=0x7<<9;
}
/*
函數(shù)功能: SPI底層寫(xiě)一個(gè)字節(jié)
*/
void XPT2046_SPI_WriteOneByte(u8 cmd)
{
u8 i;
for(i=0;i<8;i++)
{
XPT2046_SCK=0; //低電平寫(xiě)
if(cmd&0x80)XPT2046_MOSI=1;
else XPT2046_MOSI=0;
cmd<<=1;
XPT2046_SCK=1; //高電平讀,保證數(shù)據(jù)線穩(wěn)定
}
}
/*
函數(shù)功能: 讀2個(gè)字節(jié)
說(shuō)明: 讀取16位數(shù)據(jù),最低4位數(shù)據(jù)無(wú)效,有效數(shù)據(jù)是高12位
*/
u16 XPT2046_ReadData(u8 cmd)
{
u16 data;
u8 i;
XPT2046_CS=0; //選中XPT2046
XPT2046_MOSI=0;
XPT2046_SCK=0;
XPT2046_SPI_WriteOneByte(cmd);
DelayUs(8); //0.008ms ,等待XPT2046轉(zhuǎn)換完成。
//消除忙信號(hào)
XPT2046_SCK=0;
DelayUs(1);
XPT2046_SCK=1;
//連續(xù)讀取16位的數(shù)據(jù)
for(i=0;i<16;i++)
{
XPT2046_SCK=0; //通知XPT2046,主機(jī)需要數(shù)據(jù)
XPT2046_SCK=1;
data<<=1;
if(XPT2046_MISO)data|=0x01;
}
data>>=4; //丟棄最低4位
XPT2046_CS=1; //取消選中
return data;
}
/*
XPT2046的命令:
10010000 :測(cè)試Y的坐標(biāo) 0x90
11010000 :測(cè)試X的坐標(biāo) 0xD0
返回值: 0表示沒(méi)有讀取到坐標(biāo),1表示讀取到當(dāng)前坐標(biāo)
//1. 得到左上角和右下角的坐標(biāo)XY極限值
x=3831,y=3934
x=155,y=168
//2. 轉(zhuǎn)換坐標(biāo)值
x坐標(biāo):3831~155 --> 3676~0
y坐標(biāo):3934~168 --> 3766~0
//3. 計(jì)算斜率
x坐標(biāo)的斜率: 3676/320=11.4875
y坐標(biāo)的斜率: 3766/480=7.84583
//4. 得到實(shí)際的像素坐標(biāo)
x坐標(biāo): 320-(模擬量-155)/11.4875
y坐標(biāo): 480-(模擬量-168)/7.84583
*/
u8 XPT2046_ReadXY(void)
{
if(XPT2046_PEN==0) //判斷觸摸屏是否按下
{
/*1. 得到物理坐標(biāo)*/
xpt2046_touch.x0=XPT2046_ReadData(0xD0);
xpt2046_touch.y0=XPT2046_ReadData(0x90);
/*2. 得到像素坐標(biāo)*/
xpt2046_touch.x=320-(xpt2046_touch.x0-155)/11.4875;
xpt2046_touch.y=480-(xpt2046_touch.y0-168)/7.84583;
return 1;
}
return 0;
}
3.2 xpt2046.h
#ifndef XPT2046_TOUCH_H
#define XPT2046_TOUCH_H
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
//觸摸屏引腳定義
#define XPT2046_MOSI PFout(9)
#define XPT2046_MISO PBin(2)
#define XPT2046_SCK PBout(1)
#define XPT2046_CS PFout(11)
#define XPT2046_PEN PFin(10)
//函數(shù)聲明
void XPT2046_TouchInit(void);
void XPT2046_SPI_WriteOneByte(u8 cmd);
u8 XPT2046_ReadXY(void);
//存放觸摸屏信息的結(jié)構(gòu)體
struct XPT2046_TOUCH
{
u16 x0; //物理坐標(biāo)x
u16 y0; //物理坐標(biāo)y
u16 x; //像素坐標(biāo)x
u16 y; //像素坐標(biāo)y
};
extern struct XPT2046_TOUCH xpt2046_touch;
#endif
?
-
觸摸屏
+關(guān)注
關(guān)注
42文章
2290瀏覽量
115999 -
STM32
+關(guān)注
關(guān)注
2266文章
10873瀏覽量
354832 -
SPI
+關(guān)注
關(guān)注
17文章
1701瀏覽量
91331 -
電阻觸摸屏
+關(guān)注
關(guān)注
0文章
18瀏覽量
12048 -
XPT2046
+關(guān)注
關(guān)注
0文章
18瀏覽量
18249
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論