ADC和觸摸屏硬件原理詳解及裸機編程

版權聲明:本文為小斑馬學習總結文章,技術來源于韋東山著作,轉載請注明出處!

一、ADC硬件原理

模數(shù)轉換器即A/D轉換器,或簡稱ADC,通常是指一個將模擬信號轉變?yōu)閿?shù)字信號的電子元件。
通常的模數(shù)轉換器是把經(jīng)過與標準量比較處理后的模擬量轉換成以二進制數(shù)值表示的離散信號的轉換器。
故任何一個模數(shù)轉換器都需要一個參考模擬量作為轉換的標準,比較常見的參考標準為最大的可轉換信號大小。而輸出的數(shù)字量則表示輸入信號相對于參考信號的大小。
如圖,是把可變電阻上的電壓值變換的模擬信號通過ADC轉換,輸出數(shù)字信號。

對于數(shù)字信號我們需要得到它的幾個屬性

  • 用多少位來存儲這個數(shù)據(jù)(假設10bit)。
  • 最大值0b111111111
    它對應的電壓是多少伏(模擬信號輸入的最大值是多少)我們就可以根據(jù)模擬信號(電壓)的最大值,來計算出對應的數(shù)值。
  • 采樣/轉換速度。

對于程序,不用關心ADC的內(nèi)部機制,只關心:

  • 怎么啟動ADC
  • 啟動之后怎么得到數(shù)據(jù)

總之:我們都是通過寄存器操作的。

從圖1-1-1可以看出ADC有8個多路選擇器,顯然,以后寫程序的時候,我們可以8個多路選擇之一
下面是編寫程序要做的步驟:

  • 確定是哪一路信號:設置8:1MUX,選擇要測量哪一個引腳,(看原理圖選擇要測量的引腳)
  • 設置工作時鐘(從工作室中,可以算出轉換一次,需要多長時間)
  • 啟動
  • 讀狀態(tài),判斷ADC轉換是否成功。
  • 讀數(shù)據(jù)

ADC寄存器介紹

1.ADC 控制寄存器(ADCCON)
ADCCON控制寄存器,用于標志轉換是否完成,控制是否使能預分頻器,輸入通道選擇,工作模式,ADC是否啟動。它的各位含義如下圖所示。


2.ADC 啟動延時寄存器(ADCDLY)
ADCDLY 啟動延時寄存器用于啟動或初始化延時寄存器。它的各位含義如下圖所示

3.ADC 轉換數(shù)據(jù)寄存器(ADCDAT0)
ADCDAT0轉換數(shù)據(jù)寄存器,本節(jié)中只用到該寄存器的前10位(用于保存轉換后的結果)。

二、ADC編程

編程步驟:

  • 初始化ADC
  • 讀數(shù)據(jù),
  • 在串口上顯示出來。

一.初始化ADC
下面的函數(shù)實現(xiàn)對ADC的初始化。

03  void adc_init(void)
04  {
05  /* [15] : ECFLG,  1 = End of A/D conversion
06      * [14] : PRSCEN, 1 = A/D converter prescaler enable
07      * [13:6]: PRSCVL, adc clk = PCLK / (PRSCVL + 1)
08      * [5:3] : SEL_MUX, 000 = AIN 0
09       * [2]   : STDBM
10      * [0]   : 1 = A/D conversion starts and this bit is cleared after the startup.
11      */
12      ADCCON = (1<<14) | (49<<6) | (0<<3);
13
14      ADCDLY = 0xff;  
15  }

第12行:配置ADCCON寄存器,使能A/D 轉換器預分頻器,設置A/D 轉換器預分頻值,上拉使能。
第14行:設置ADC 轉換啟動延時值。
二.讀數(shù)據(jù)
在這個讀函數(shù)中啟動ADC,并且等待ADC轉換成功。然后返回數(shù)據(jù),

17  int adc_read_ain0(void)
18  {
19          /* 啟動ADC */
20      ADCCON |= (1<<0);
21
22      while (!(ADCCON & (1<<15)));  /* 等待ADC結束 */
23
24      return ADCDAT0 & 0x3ff;
25  }

第20行:啟動ADC。
第22行:等待A/D轉換結束(ADCCON第15位置1),
第24行:返回轉換的值。(ADCDAT0寄存器的前10位,是保存轉換后的值)。
三.ADC測試
函數(shù)代碼如下: 函數(shù)功能:在串口/LCD上打印ADC轉換后的結果。

04  void adc_test(void)
05  {
06      int val;
07      double vol;
08      int m; /* 整數(shù)部分 */
09      int n; /* 小數(shù)部分 */
10  
11      adc_init();
12
13      while (1)
14      {
15          val = adc_read_ain0();
16          vol = (double)val/1023*3.3;   /* 1023----3.3v */
17          m = (int)vol;   /* 3.01, m = 3 */
18          vol = vol - m;  /* 小數(shù)部分: 0.01 */
19          n = vol * 1000;  /* 10 */
20
21          /* 在串口上打印 */
22          printf("vol: %d.%03dv", m, n);  /* 3.010v */
23
24          /* 在LCD上打印 */
25          //fb_print_string();
26          }
27  }

第11行:初始化ADC.
第15行:把ADC轉換得到的值賦值給變量val.
第16行:把變量val的值轉化為電壓值。
第17行:取vol整數(shù)部分賦值給變量m。
第18行:取vol的小數(shù)部分賦值給vol。
測試:把生成的二進制文件燒錄到開發(fā)板上,接上SPI模塊,旋轉可變電阻就可以在串口上看到電壓值發(fā)生變化。

三、電阻觸摸屏硬件原理

電阻觸摸屏的硬件原理:假設有一個比較長的電阻,電阻是R 上面接3.3V電壓,下面接地

假設整個電阻的阻值是R某一個觸電它的阻值是R1
根據(jù)歐姆定律
3.3v/R = V/R1
V=3.3 *(R1/R)
假設R1是x坐標
R的長度是l
這個電阻非常的均勻,那么這個電壓就等于 3.3V * (x / l)
這個電壓和這個觸電的x坐標有一個線性關系
我使用ADC把這個電壓算出來,就可以間接得到這個觸電的x坐標
電阻觸摸屏就是使用歐姆定律使用電阻原理作出來的

可以上百度圖片搜索觸摸屏,就知道了觸摸屏的樣子,它是一個透明的薄膜,注意 LCD是LCD 觸摸屏是觸摸屏它是兩個設備,
我們只不過是把觸摸屏做的和LCD大小一樣,粘在LCD上面,
實際上觸摸屏是由兩層膜組成,他們靠的非常近。
上面這層右邊引出來,代表xp ,p代表正極

上面這層左邊引出來,代表xm, m代表負極

下面這層膜 前面這條邊引出來為yp,后面這層邊為ym

假設我們手指要點擊觸摸屏,那么上下就會粘貼在一起,我怎么算出這個 x y點的坐標呢?
測量觸電x坐標:
xp接3.3v,xm接GND

yp,ym不接電源
2 測yp電壓
上下膜連接在一起,我就可以通過yp測量這個觸電的電壓
這個yp就像探測一樣,從前面的原理我們可以知道,當這個觸電越靠近左邊這個電壓越小,越靠近右邊電壓越大
這個yp的電壓就可以認為是這個觸電的坐標(x坐標)

類似的我們怎么測量觸電y坐標
類似的xp xm不接電源,同樣yp接3.3v, ym接GND,這時候電流就從 yp這里流向ym,讓后我們就可以測量xp電壓
當按下屏幕時,上下兩層膜鏈接在一起,這個xp就像探針一樣,這個觸電越靠近yp電壓值越大,越靠近ym電壓值越小
yp接3.3V ym接GND,xp xm不接電源
測量xp電壓,就是y坐標

注意 x y坐標都是電壓值,不是屏幕上480 * 272 這些值,我們需要把電壓值轉換為坐標值,這需要經(jīng)過一些轉換
我們測量xp yp可以得到觸點的兩個方向的電壓值,這些電壓值和坐標是線性關系
現(xiàn)在總結下使用觸摸屏的流程

  • <1>按下觸摸屏 按下觸摸屏時,對于一個高效的系統(tǒng),產(chǎn)生中斷,這是觸摸屏中斷
  • <2>在觸摸中斷程序中 啟動ADC,(獲得數(shù)據(jù),xy坐標)啟動ADC就開始模數(shù)轉換,不可能瞬間完成,
  • <3>ADC完成, 產(chǎn)生中斷
  • <4>ADC中斷中讀取x y坐標,我們來想想,在這個流程里,啟動觸摸屏的源頭是按下觸摸屏,那如果長按觸摸屏,我按下之后一直不松開 滑動手指呢
    那么誰來觸發(fā)后續(xù)的多次ADC轉換呢 不可能只啟動一次吧,
    為了支持 長按 滑動操作,我們需要啟用定時器.
  • <5> 啟動定時器
  • <6> 定時器中斷發(fā)生,判斷觸摸屏是否仍被按下,如果按下就循環(huán)上述過程
    <6.1>在觸摸中斷程序中 啟動ADC,(獲得數(shù)據(jù),xy坐標)啟動ADC就開始模數(shù)轉換,不可能瞬間完成
    <6.2>ADC完成, 產(chǎn)生中斷
    <6.3>ADC中斷中讀取x y坐標,)
  • <7> 松開結束一個流程

這就是整個觸摸屏的使用流程
在14章里講解了觸摸屏,他抽象了幾張圖

平時的時候上下兩層膜并不連接,我們按下觸摸屏的時候就會產(chǎn)生中斷,那么你怎么知道產(chǎn)生中斷,肯定是由某個引腳的電平發(fā)生變化,平時 Y_ADC/xp是高電平,按下之后Y_ADC就接地了,就是被拉低了,就產(chǎn)生了低電平

產(chǎn)生低電平后就知道觸摸屏被按下了,這個時候就需要測量電壓值讀取x坐標,XP XM通電我就測量YP的電壓,這不就是 x 點的坐標

讀取Y坐標
YP YM 通電,按下后XP通電,這不就是y點的坐標么

四、S3C2440觸摸屏接口

回顧上節(jié)觸摸屏使用原理

在不使用觸摸屏的時候,必須要把 S1 S2 S3斷開,S4 S5閉合,只有這樣當我按下觸摸屏,上面的電平才能從高變低,會產(chǎn)生一個中斷信號,而當我去讀取X坐標的值時

必須讓S1 S3閉合,這樣電流才可以通過,同時讓S2 S4 S5斷開,這時候YP這層膜就相當于探針一樣去測量電壓

當我讀取y坐標值

必須讓S2 S4閉合,這樣電流才可以流 下來,同時S1 S3 S5斷開,這個時候XP這層膜就相當于探針一樣,我可以來測量這里的電壓,從而得到Y坐標的電壓值

在測量x y坐標時,這個S5上拉電阻都要斷開,
我們需要控制這幾個開關,實際上2440就提供了這幾個開關的控制方法,
打開2440的芯片手冊看觸摸屏時怎么操作的,
我們看有一個8:1 MUX的多路選擇器,以及XP YP


442頁觸摸屏接口模式
正常模式,在上節(jié)視頻中我們有講解過
正常模式 上篇文章詳寫過

x y分離轉換模式

看看我們的X Y坐標原理圖,可以單獨轉換X坐標 單獨轉換Y坐標

換句話說就是逐個去測量X Y坐標,

他首先會啟動X坐標的ADC轉換,轉換成功后數(shù)據(jù)會保存在ADCDAT0里,同時會產(chǎn)生一個中斷,在這個中斷服務程序里,就可以把X坐標讀取出來,讓后可以啟動Y坐標的轉換,轉換成功后數(shù)據(jù)會保存在ADCDAT,同時會產(chǎn)生一個中斷,進入這個中斷把Y坐標讀取出來。測量一次會產(chǎn)生2個中斷,一個時X坐標中斷,一個是Y坐標中斷

自動的或連續(xù)的X/Y坐標轉換模式

也就是說不需要單獨控制,不需要單獨去讀取X坐標Y坐標,可以設置寄存器,讓它一次性的測量X坐標測量Y坐標,X坐標保存在ADCDAT0 Y坐標保存在ADCDAT1,最后產(chǎn)生一個中斷,也就是讀取X/Y坐標只需要產(chǎn)生一次中斷

等待中斷模式
所謂等待中斷模式,就是等待按下或者等待松開

對于下面這幅圖,我按下的時候XP從高電平變?yōu)榈碗娖?,松開時,XP從低電平變?yōu)楦唠娖剑@就是按下松開都可以檢測到

我們要等待按下或者松開時 需要設置rADCTSC =0xd3這個值

443頁編程要點

AD轉換數(shù)據(jù)時可以通過中斷或者查詢模式來得到數(shù)據(jù),使用中斷模式時,從AD轉換開始,到得到數(shù)據(jù)可能會有些延遲,因為中斷服務程序的進入和退出需要一定的時間,(也就是說,如果你對數(shù)據(jù)轉換的速度要求的非常高,就可以使用查詢方式),可以查詢ADCCON[15]來判斷是否轉換結束

444頁

剩下就是寄存器操作
ECFLG狀態(tài)位 AD轉換是否結束

PRSCEN 使能ADC轉換
PRSCVL 設置A/D轉換預分頻值
SEL_MUX選擇輸入通道,后面我們使用自動轉換XY坐標,所以這里不需要設置
ENABLE_START 啟動轉換

ADCTSC這個寄存器是重要的
UD_SEN Bit8是用來判斷觸摸屏是被按下還是被松開
0表明被按下,1表明被松開
YM_SEN Bit7 YM開關使能控制S4

0表示斷開 1閉合

YP_SEN Bit6 YP開關
0表示閉合 1 表示斷開

*寄存器位的含義不同
XM_SEN Bit5 XM開關
0 斷開 1 閉合

XP_SEN Bit4 XP開關
0 閉合 1 斷開

PULL_UP Bit3 控制S5開關
0 上拉(閉合)
1 斷開

AUTO_PST Bit2 自動連續(xù)轉換X坐標Y坐標

設置是 0 正常的ADC轉換

如果需要連續(xù)轉換ADC坐標的話,需要設置為1 ,如果需要手動轉換ADC坐標的話,需要設置為0

XY_PST Bit[1:0]
對于手動轉換X Y坐標我們需要手動設置XY_PST 里面的位,是測量X坐標還是測量Y坐標,
也可以設置這兩位等于11 讓其等于等待模式,
也就是等待觸摸屏被按下或者被松開.

如果設置自動連續(xù)轉換的話,Bit2 AUTO_PST設置為1
XY_PST設置為00

如果使用手動轉換的話設置AUTO_PST為0
XY_PST設置為01 手動轉換X坐標模式
或者設置為10 Y坐標轉換模式
447頁ADCDATA0 ADC數(shù)據(jù)寄存器

UPDOWN Bit15 可以讀取這一位去判斷觸摸屏是按下還是松開
AUTO_PST Bit14 自動測量
XY_PST Bit[13:12] 和上面ADCTSC寄存器中 AUTO_PST Bit2   XY_PST 
Bit[1:0]原理相同
 XPDATA Bit[9:0]最低10位用來保存ADC的值

448頁'ADCDAT1寄存器 和ADCDAT0功能一樣的,只不過保存的數(shù)據(jù)不同

這個的低10位是用來保存 Y坐標的值

接下來是ADCUPDN觸摸屏按下或者松開檢查寄存器
TST_UP Bit1 觸摸屏松開中斷產(chǎn)生
TST_DN Bit0 觸摸屏按下中斷產(chǎn)生
手冊看完了,涉及到中斷,我們看下這個圖

它會涉及兩個中斷,按下或者松開,觸摸筆的狀態(tài)中斷,另外一個啟動ADC以后,ADC結束時也會產(chǎn)生一個中斷,但是這個手冊里沒有看到中斷的是能寄存器。
那我們猜測一下,ADC模塊或者觸摸屏模塊一定會發(fā)出中斷

首先是ADC或者觸摸屏產(chǎn)生中斷,通過中斷控制器發(fā)送中斷給CPU

肯定有寄存器禁止/使能ADC或者觸摸屏中斷
看看中斷控制器芯片手冊中都需要設置什么
ADC中斷源
ADC結束中斷或者觸摸屏中斷,看來他們合起來用一個中斷
既然合并必然還會有一個寄存器來分辨到底是ADC還是觸摸屏發(fā)生的中斷變化
SRCPND寄存器
31位為ADC中斷


設置Bit[31]
INTMOD寄存器
來決定是普通中斷還是快中斷模式
設置Bit[31]
INTMSK寄存器
用來表示是否屏蔽這個中斷
設置Bit[31]
優(yōu)先級我們不需要設置
INTPND
設置Bit[31]表示中斷是否正在處理
INTOFFSET
設置Bit[31]
到底是ADC中斷還是觸摸屏中斷,肯定有其他寄存器可以設置

SUBSOURCE PENDING寄存器
INT_ADC_S Bit[10]表示ADC中斷
INT_TC Bit[9]表示觸摸屏中斷

INTSUBMSK
應該也是同樣的位
INT_ADC_S Bit[10]表示ADC中斷激活/屏蔽
INT_TC Bit[9]表示觸摸屏中斷激活/屏蔽
可以通過INTSUBMSK來屏蔽ADC中斷或者TouchScreen中斷
當然也可以是能某個中斷
可以通過SUBSRCPND來分辨到底產(chǎn)生那個中斷
INTSUBMSK 和SUBSOURCPND這兩個寄存器都會匯集到一起
變成一個叫做INT_ADC的中斷來發(fā)送給CPU

框圖就是這樣

程序設計?
寫出一個框架

  • 1 初始化ADC/TouchScreen接口ADCCON時鐘接口
  • 2 一開始觸摸屏是沒有被按下的,設置TS處于等待中斷模式
  • 3 設置中斷
    INTSUBMSK使能ADC中斷和觸摸屏中斷,還有INTMSK設置這個寄存器使能ANT_ADC讓他能夠發(fā)給CPU
  • 4 按下觸摸屏,進入TS中斷
    4.1 進入自動采集模式(自動轉換XY坐標)
    4.2 啟動ADC
  • 5.轉換完之后產(chǎn)生ADC中斷
    5.1 讀數(shù)據(jù)
    5.2 再次進入 “'等待中斷”'模式
    5.3 啟動定時器,處理長按或者滑動
  • 6 定時器中斷
    6.1 判斷是否松開,若松開結束
    6.2 若按下重新執(zhí)行 4.2啟動ADC步驟

五、觸摸屏編程_按下松開檢測

開始觸摸屏編程,關于觸摸屏編程大概會分為3個小節(jié)
第006節(jié)觸摸屏編程ADC中斷
第007節(jié)
觸摸屏編程
定時器程序優(yōu)化
參考《嵌入式Linux應用開發(fā)完全手冊》第14章 ADC和觸摸屏接口
可以參考下面這張圖

看懂這張圖的關鍵點在于
里面有個中斷程序 AdcTsIntHandle
它是總的中斷,這里面要分辨

if,
如果是ADC中斷 那么就調(diào)用Isr_adc來處理中段
else if,
如果是觸摸屏中斷,那么就調(diào)用Isr_tc中斷,

我們看看是怎么做的

這些都是總中斷具體的中斷. 一開始設置中斷
初始化觸摸屏控制器,進入等待中斷模式
這個時候如果按下觸摸屏就會進入Pen Down中斷
就會進入AdcTsIntHandle這個總中斷函數(shù)
這里面分辨是按下觸摸屏
進入自動(連續(xù)) X/Y軸坐標轉換模式,啟動ADC,
ADC結束之后會產(chǎn)生一個ADC中斷
又再次進入這個AdcTsIntHandle總中斷
這里面分辨是ADC中斷,這里面調(diào)用Isr_Adc
我可以讀出這里面的數(shù)據(jù),再次設置寄存器
進入等待Pen UP中斷模式
松開觸摸筆會再次產(chǎn)生一個中斷
進入總中斷AdcTsIntHandle這里面分辨,原來是松開了觸摸筆,再次調(diào)用Isr_tc
 這里面又會設置進入等待Pen Down中斷模式

程序設計:
002_touchscreen_018_005/adc_touchscreen
我們在adc_touchscreen目錄下添加幾個文件
touchscreen_test.c
touchscreen.c

我們打開touchscreen.c文件

void touchscreen_init(void)
{
    看看上面流程圖
    /*1設置觸摸屏接口:也就是寄存器 */

    /*2 設置中斷我們需要提供中斷處理函數(shù) */

    /*3 讓觸摸屏控制器進入"等待中斷模式" */

}

我們設置中斷處理函數(shù)
void AdcTsIntHandle(void)
{
}
看一下之前我們是怎么寫中斷的,看一下interrupt.c文件
void key_eint_irq(int irq)
有個中斷號

那么我們也定義個int irq參數(shù)
void AdcTsIntHandle(int irq)
我們在這個里面分辨一下
if (SUBSRCPND & (1<<TC_INT_BIT))  /* 如果是觸摸屏中斷 */
/*調(diào)用*/  
Isr_Tc();

else if //如果是ADC中斷
 //調(diào)用
Isr_Adc();
我們等會實現(xiàn)這兩個函數(shù)

 我們繼續(xù)寫代碼
void touchscreen_init(void)
{
看看上面流程圖

/*1 設置中斷我們需要提供中斷處理函數(shù) */
adc_ts_int_init();

/*2 設置觸摸屏接口:也就是寄存器 */
adc_ts_reg_init();

/*3 讓觸摸屏控制器進入"等待中斷模式" */
enter_wait_pen_down_mode();

}


//我們先來實現(xiàn) adc_ts_int_init

void adc_ts_int_init(void)
{
/*注冊中斷處理函數(shù)*/
//怎么注冊看之前的代碼
register_irq(irq, irq_handle);  

中斷號是多少?

打開芯片手冊,找到中斷控制器


我們是31號中斷
register_irq(31, AdcTsIntHandle);
怎么使能中斷?

我們需要把 INTSUBMISK寄存器的Bit9 Bit10設置為0
宏定義

#define ADC_INT_BIT (10)
#define TC_INT_BIT  (9)

使能中斷,清零
INTSUBMSK &= ~((1<<ADC_INT_BIT) | (1<<TC_INT_BIT));
還有INTMSK我們也需要把Bit31清零

#define INT_ADC_TC (31)

Bit31位清零操作

INTMSK &= ~(1<<INT_ADC_TC);

這句可以不用設置,因為register_irq已經(jīng)設置

假設產(chǎn)生中斷就會進入AdcTsIntHandle函數(shù)中
分辨是觸摸屏終端還是ADC中斷

void AdcTsIntHandle(int irq)
{
if   /* 如果是觸摸屏中斷 */
    Isr_Tc();

if  /* ADC中斷 */
    Isr_Adc();

}

如何進行分辨
if (SUBSRCPND & (1<<TC_INT_BIT))  /* 如果是觸摸屏中斷 */
Isr_Tc();
if (SUBSRCPND & (1<<ADC_INT_BIT))  /* ADC中斷 */
Isr_Adc();

//我們要引用寄存器地址頭文件
#include "../s3c2440_soc.h"
#define ADC_INT_BIT (10)
#define TC_INT_BIT  (9)
#define INT_ADC_TC   (31)
/* ADCTSC's bits */
#define WAIT_PEN_DOWN    (0<<8)
#define WAIT_PEN_UP      (1<<8)
#define YM_ENABLE        (1<<7)
#define YM_DISABLE       (0<<7)
#define YP_ENABLE        (0<<6)
#define YP_DISABLE       (1<<6)

#define XM_ENABLE        (1<<5)
#define XM_DISABLE       (0<<5)

#define XP_ENABLE        (0<<4)
#define XP_DISABLE       (1<<4)

#define PULLUP_ENABLE    (0<<3)
#define PULLUP_DISABLE   (1<<3)

#define AUTO_PST         (1<<2)

#define WAIT_INT_MODE    (3)
#define NO_OPR_MODE      (0)

void enter_wait_pen_down_mode(void)
{
    ADCTSC = WAIT_PEN_DOWN | PULLUP_ENABLE | YM_ENABLE | YP_DISABLE | XP_DISABLE | XM_DISABLE | WAIT_INT_MODE;
}

void enter_wait_pen_up_mode(void)
{
   ADCTSC = WAIT_PEN_UP | PULLUP_ENABLE | YM_ENABLE | YP_DISABLE | XP_DISABLE | XM_DISABLE | WAIT_INT_MODE;
}

讀一下寄存器,找到觸摸屏的寄存器觸摸筆,按下松開狀態(tài)寄存器

我們可以讀它 Bit1表示up Bit0表示down

void Isr_Tc(void)
{
printf("ADCUPDN = 0x%x, ADCDAT0 = 0x%x, ADCDAT1 = 0x%x, ADCTSC = 0x%x\n\r", ADCUPDN, ADCDAT0, ADCDAT1, ADCTSC);

if (ADCDAT0 & (1<<15))
{
    printf("pen up\n\r");
    enter_wait_pen_down_mode();
}
else    
{
    printf("pen down\n\r");

    /* 進入"等待觸摸筆松開的模式" */
    enter_wait_pen_up_mode();
 }
}

void AdcTsIntHandle(int irq)
{
if (SUBSRCPND & (1<<TC_INT_BIT))  /* 如果是觸摸屏中斷 */
    Isr_Tc();

//  if (SUBSRCPND & (1<<ADC_INT_BIT))  /* ADC中斷 */
//      Isr_Adc();
SUBSRCPND = (1<<TC_INT_BIT) | (1<<ADC_INT_BIT);
}

void adc_ts_int_init(void)
{
SUBSRCPND = (1<<TC_INT_BIT) | (1<<ADC_INT_BIT);

/* 注冊中斷處理函數(shù) */
register_irq(31, AdcTsIntHandle);   

/* 使能中斷 */
INTSUBMSK &= ~((1<<ADC_INT_BIT) | (1<<TC_INT_BIT));
//INTMSK    &= ~(1<<INT_ADC_TC);
}


void adc_ts_reg_init(void)
{
/* [15] : ECFLG,  1 = End of A/D conversion
 * [14] : PRSCEN, 1 = A/D converter prescaler enable
 * [13:6]: PRSCVL, adc clk = PCLK / (PRSCVL + 1)
 * [5:3] : SEL_MUX, 000 = AIN 0
 * [2]   : STDBM
 * [0]   : 1 = A/D conversion starts and this bit is cleared after the startup.
 */
ADCCON = (1<<14) | (49<<6) | (0<<3);

ADCDLY = 0xff;  
}


void touchscreen_init(void)
{
/* 設置觸摸屏接口:寄存器 */
adc_ts_reg_init();

printf("ADCUPDN = 0x%x, SUBSRCPND = 0x%x, SRCPND = 0x%x\n\r", ADCUPDN, SUBSRCPND, SRCPND);

/* 設置中斷 */
adc_ts_int_init();

/* 讓觸摸屏控制器進入"等待中斷模式" */
enter_wait_pen_down_mode();
}

六、觸摸屏編程_ADC中斷

加上ADC中斷把觸點的xy坐標讀出來
查看touchscreen.c

寫出這個自動測量的函數(shù)
void enter_auto_measure_mode(void)
{
  //現(xiàn)在是自動測量,我們沒有機會分別設置這些開關

  設置AUTO_PST =1
  XY_PST = 00

ADCTSC = AUTO_PST | NO_OPR_MODE;

}

現(xiàn)在是自動測量,我們沒有機會分別設置這些開關

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 專業(yè)考題類型管理運行工作負責人一般作業(yè)考題內(nèi)容選項A選項B選項C選項D選項E選項F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 10,461評論 0 13
  • 選擇題部分 1.(),只有在發(fā)生短路事故時或者在負荷電流較大時,變流器中才會有足夠的二次電流作為繼電保護跳閘之用。...
    skystarwuwei閱讀 14,328評論 0 7
  • 1. 下列敘述錯誤的是()。 (2.0 分) A. 質量管理包括QA和QC一切活動的全部過程 B. 影像質量是指對...
    我們村我最帥閱讀 4,374評論 0 8
  • 轉載自:http://www.geek-workshop.com/forum.php?mod=viewthread...
    尾枯枝閱讀 1,686評論 0 7
  • 我們無法選擇自己的出生,卻可以改變自己的生活,我們可能沒有一張明星的臉,但以下這些肌膚問題,可能會在你的身上發(fā)生,...
    五谷君閱讀 288評論 0 1

友情鏈接更多精彩內(nèi)容