<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 模擬技術(shù) > 設(shè)計(jì)應(yīng)用 > ARM開發(fā)步步深入之掌握ADC和觸摸屏

          ARM開發(fā)步步深入之掌握ADC和觸摸屏

          作者: 時(shí)間:2016-12-09 來源:網(wǎng)絡(luò) 收藏

            實(shí)驗(yàn)?zāi)康模和ㄟ^串口顯示輸入的電壓值及采集按下觸摸屏的(x,y)坐標(biāo)值借此掌握S3C2410的和觸摸屏的使用。

          本文引用地址:http://www.ex-cimer.com/article/201612/341376.htm

            實(shí)驗(yàn)環(huán)境及說明:恒頤S3C2410開發(fā)板H2410。H24X0E擴(kuò)展板上AIN0~AIN1輸出懸空,通過外接可變電阻電路采樣電壓值;外接的觸摸屏接口實(shí)現(xiàn)擴(kuò)展觸摸屏完成相應(yīng)操作本實(shí)驗(yàn)基于夏普3.5英寸LQ035Q7DB02。

            實(shí) 驗(yàn)思路:開發(fā)板上電啟動(dòng)后,自動(dòng)將NandFlash開始的4K數(shù)據(jù)復(fù)制到SRAM中,然后跳轉(zhuǎn)到0地址開始執(zhí)行。關(guān)閉看門狗、初始化SDRAM及 NandFlash控制器、設(shè)置MPLL來改變FCLK、HCLK、PCLK的值,設(shè)置堆棧,復(fù)制4KB后的16KB數(shù)據(jù)到SDRAM,之后進(jìn)入main 函數(shù)中進(jìn)行及觸摸屏的測(cè)試。

            知識(shí)掌握:(模數(shù)轉(zhuǎn)換器)和Touch Screen(觸摸屏)。

            ★S3C2410 ADC和TouchScreen概述:S3C2410內(nèi)置1個(gè)8信道的10bit模數(shù)轉(zhuǎn)換器,該ADC能以500KSPS的采樣速率將外部的模擬信號(hào)轉(zhuǎn)換 為10位的二進(jìn)制數(shù)字量。同時(shí)ADC部分能與CPU的觸摸屏控制器協(xié)同工作,完成對(duì)觸摸屏絕對(duì)地址的測(cè)量。ADC和TouchScreen共用一個(gè)A/D 轉(zhuǎn)換器,ADC可同時(shí)采樣8路模擬輸入信號(hào),使用觸摸屏?xí)r,AIN[7]、AIN[5]被用來測(cè)量XP/YP的電平,剩余的六個(gè)引腳可用來做一般ADC輸 入。2410ADC和觸摸屏功能框圖如下:

            ★ADC和TouchScreen控制器的工作模式:

            ●ADC普通轉(zhuǎn)換模式(Normal Converson Mode)---普通轉(zhuǎn)換模式(AUTO_PST=0,XY_PST=0)是用來進(jìn)行一般的ADC轉(zhuǎn)換之用的,例如通過ADC測(cè)量電池電壓等等。

            ● 獨(dú)立X/Y軸坐標(biāo)轉(zhuǎn)換模式(Separate X/Y Position Conversion Mode)---獨(dú)立X/Y軸坐標(biāo)轉(zhuǎn)換模式其實(shí)包含了X軸模式和Y軸模式2種模式。 首先進(jìn)行X軸的坐標(biāo)轉(zhuǎn)換(AUTO_PST=0,XY_PST=1),X軸的轉(zhuǎn)換資料會(huì)寫到ADCDAT0寄存器的XPDAT中,等待轉(zhuǎn)換完成后,觸摸屏 控制器會(huì)產(chǎn)生相應(yīng)的中斷。 然后進(jìn)行Y軸的坐標(biāo)轉(zhuǎn)換(AUTO_PST=0,XY_PST=2),Y軸的轉(zhuǎn)換資料會(huì)寫到ADCDAT1寄存器的YPDAT中,等待轉(zhuǎn)換完成后,觸摸屏 控制器會(huì)產(chǎn)生相應(yīng)的中斷。

            ●自動(dòng)X/Y軸坐標(biāo)轉(zhuǎn)換模式(Auto X/Y Position Conversion Mode)---自動(dòng)X/Y軸坐標(biāo)轉(zhuǎn)換模式(AUTO_PST=1,XY_PST=0)將會(huì)自動(dòng)地進(jìn)行X軸和Y軸的轉(zhuǎn)換操作,隨后產(chǎn)生相應(yīng)的中斷。

            ● 中斷等待模式(Wait for InterruptMode)---在系統(tǒng)等待"Pen Down",即觸摸屏按下的時(shí)候,其實(shí)是處于中斷等待模式。一旦被按下,實(shí)時(shí)產(chǎn)生"INT_TC"中斷信號(hào)。每次發(fā)生此中斷都,X軸和Y軸坐標(biāo)轉(zhuǎn)換資料都 可以從相應(yīng)的資料寄存器中讀出。

            ●閑置模式(Standby Mode)---在該模式下轉(zhuǎn)換資料寄存器中的值都被保留為上次轉(zhuǎn)換時(shí)的資料。

            ★ADC兩種啟動(dòng)方式:以手工啟動(dòng)和讀結(jié)果時(shí)就自動(dòng)地啟動(dòng)下一次轉(zhuǎn)換;以查詢狀態(tài)位和發(fā)中斷方式獲知轉(zhuǎn)換是否結(jié)束。ADC的操作只涉及3個(gè)寄存器:

            ●ADCCON--- 設(shè)置ADCCON寄存器,選擇輸入信號(hào)通道,設(shè)置A/D轉(zhuǎn)換器的時(shí)鐘(A/D時(shí)鐘=PCLK/(PRSCVL+1))。A/D時(shí)鐘最大為2.5MHz,且 應(yīng)小于PCLK的1/5;設(shè)置ADCCON寄存器,啟動(dòng)轉(zhuǎn)換(設(shè)置READ_START位則讀轉(zhuǎn)換數(shù)據(jù)(讀ADCDAT0寄存器)時(shí)即啟動(dòng)下一次轉(zhuǎn)換;否 則可通過設(shè)置ENABLE_START位來啟動(dòng)A/D轉(zhuǎn)換);ADCCON各位含義(ENABLE_START---置1啟動(dòng)ADC轉(zhuǎn)換,置0無操作; RESR_START---置1允許讀操作啟動(dòng)ADC轉(zhuǎn)換,置0禁止讀操作啟動(dòng)ADC轉(zhuǎn)換; STDBM---置1將ADC置為閑置狀態(tài)(模式),置0將ADC置為正常操作狀態(tài);SEL_MUX---選擇需要進(jìn)行轉(zhuǎn)換的ADC信道; PRSCV---ADC轉(zhuǎn)換時(shí)鐘預(yù)分頻參數(shù);PRSCEN---ADC轉(zhuǎn)換時(shí)鐘使能; ECFLG---ADC轉(zhuǎn)換完成標(biāo)志位(只讀)。為1ADC轉(zhuǎn)換結(jié)束,為0ADC轉(zhuǎn)換進(jìn)行中)。

            ●ADCTSC---設(shè)置ADCTSC寄存器,使 用設(shè)為普通轉(zhuǎn)換模式,不使用觸摸屏功能;ADCTSC各位含義(XY_PST---對(duì)X/Y軸手動(dòng)測(cè)量模式進(jìn)行選擇;AUTO_PST---X/Y軸的自 動(dòng)轉(zhuǎn)換模式使能位;PULL_UP---XP端的上拉電阻使能位;XP_SEN---設(shè)置nXPON輸出狀態(tài);XM_SEN---設(shè)置XMON輸出狀 態(tài);YP_SEN---設(shè)置nYPON輸出狀態(tài);YM_SEN---設(shè)置YMON輸出狀態(tài))。

            ●ADCDAT0---完成ADC轉(zhuǎn)換后,讀取 ADCDAT0寄存器獲得數(shù)值(如果使用查詢方式,則可不斷讀取ADCCON寄存器的ECFLG位來確定是否轉(zhuǎn)換結(jié)束;否則可以使用INT_ADC中斷, 發(fā)生INT_ADC中斷時(shí)表示轉(zhuǎn)換結(jié)束);ADCDAT0各位含義(XPDATA---X軸轉(zhuǎn)換資料寄存器;XY_PST---選擇X/Y軸自動(dòng)轉(zhuǎn)換模 式;AUTO_PST---X/Y軸自動(dòng)轉(zhuǎn)換使能位;UPDOWN---選擇中斷等待模式的類型。為0按下產(chǎn)生中斷,為1釋放產(chǎn)生中斷)。

            ★觸摸屏操作還涉及到以下兩個(gè)寄存器:

            ●ADCDLY---ADC轉(zhuǎn)換周期等待定時(shí)器。

            ●ADCDAT1---同ADCDAT0。

            關(guān)鍵代碼解析:

            ★head.S頭文件來初始化,設(shè)置SDRAM,將程序復(fù)制到SDRAM,然后跳到SDRAM繼續(xù)執(zhí)行

            .equ MEM_CTL_BASE, 0x48000000

            .text

            .global _start

            _start:

            @中斷向量表處理函數(shù),只給出復(fù)位和普通中斷模式的處理函數(shù),其它異常未使用

            b Reset

            ...

            b HandleIRQ

            @0x1c: 快中斷模式的向量地址

            HandleFIQ:

            b HandleFIQ

            Reset: @復(fù)位處理

            bl disable_watch_dog @關(guān)門喂狗

            bl mem_control_setup @設(shè)置存儲(chǔ)控制器

            ldr sp, =4096 @設(shè)置棧指針,以下C函數(shù)調(diào)用前需要設(shè)好棧

            bl init_clock @設(shè)置MPLL,改變FCLK、HCLK、PCLK

            bl init_nand @初始化NandFlash

            @將NandFlash中地址4096開始的代碼復(fù)制到SDRAM中

            ldr r0, =0x30000000 @目標(biāo)地址=0x30000000,SDRAM起始地址

            mov r1, #4096 @源地址=4096,連接時(shí)代碼在4096開始處

            mov r2, #16*1024 @復(fù)制長(zhǎng)度=16K,對(duì)于本實(shí)驗(yàn)足夠

            bl read_nand @調(diào)用C函數(shù)read_nand

            bl clean_bss @清除bss段

            msr cpsr_c, #0xd2 @進(jìn)入中斷模式

            ldr sp, =0x31000000 @設(shè)置中斷模式棧指針

            msr cpsr_c, #0xdf @進(jìn)入系統(tǒng)模式

            ldr sp, =0x34000000 @設(shè)置系統(tǒng)模式棧指針

            ldr lr, =ret_initirq @設(shè)置返回地址

            ldr pc, =init_irq @初始化中斷

            ret_initirq:

            msr cpsr_c, #0x5f @設(shè)置I-bit=0,開IRQ中斷

            ldr lr, =halt_loop @設(shè)置返回地址

            ldr pc, =main @調(diào)用main函數(shù)

            halt_loop:

            b halt_loop

            ★main.c文件實(shí)現(xiàn)實(shí)現(xiàn)串口選擇ADC和TouchScreen操作,主要代碼:

            #include

            #include

            #include 

            int main()

            {

            char c;

            init_uart0(); //波特率115200,8N1(8個(gè)數(shù)據(jù)位,無校驗(yàn)位,1個(gè)停止位)

            while (1)

            {

            printf("rn~~~~~~ Test ADC and Touch Screem ~~~~~~rn");

            printf("[A] Test ADCnr");

            printf("[T] Test Touch Screemnr");

            printf("Enter your selection: ");

            c = getc();

            putc(c);

            switch (c)

            {

            case 'a':

            case 'A':

            {

            Test_Adc();//操作ADC

            break;

            }

            case 't':

            case 'T':

            {

            Test_Ts();//操作TouchScreen

            break;

            ...

            }

            ★adc_ts.c ADC和觸摸屏的測(cè)試函數(shù),主要代碼:

            ...

            /*

            * 使用查詢方式讀取A/D轉(zhuǎn)換值。

            * 輸入?yún)?shù)ch: 模擬信號(hào)通道,取值為0~7

            */

            static int ReadAdc(int ch)

            {

            //選擇模擬通道,使能預(yù)分頻功能,設(shè)置A/D轉(zhuǎn)換器的時(shí)鐘 = PCLK/(49+1)

            ADCCON = PRESCALE_EN | PRSCVL(49) | ADC_INPUT(ch);

            //清除位[2],設(shè)為普通轉(zhuǎn)換模式

            ADCTSC &= ~(1<<2);

            //設(shè)置位[0]為1,啟動(dòng)A/D轉(zhuǎn)換

            ADCCON |= ADC_START;

            //當(dāng)A/D轉(zhuǎn)換真正開始時(shí),位[0]會(huì)自動(dòng)清0

            while (ADCCON & ADC_START);

            //檢測(cè)位[15],當(dāng)它為1時(shí)表示轉(zhuǎn)換結(jié)束

            while (!(ADCCON & ADC_ENDCVT));

            //讀取數(shù)據(jù)

            return (ADCDAT0 & 0x3ff);

            }

            /*

            * 測(cè)試ADC。通過A/D轉(zhuǎn)換,測(cè)量可變電阻器的電壓值

            */

            void Test_Adc(void)

            {

            int vol0, vol1;

            printf("Measuring the voltage of AIN0 and AIN1, press any key to exitnr");

            while (!awaitkey(0)) // 串口無輸入,則不斷測(cè)試

            {

            vol0 = (ReadAdc(0)*3)/1024; // 計(jì)算電壓值

            vol1 = (ReadAdc(1)*3)/1024; // 計(jì)算電壓值

            printf("AIN0 = %d AIN1 = %dr", vol0,vol1);

            }

            printf("n");

            }

            static void Isr_Tc(void)

            {

            if (ADCDAT0 & 0x8000) //ADCDAT0[15]為1表示觸摸屏被松開

            {

            printf("rnStylus Up!!nr");

            //wait_down_int(); //進(jìn)入"等待中斷模式",等待觸摸屏被按下

            }

            else

            {

            printf("rnStylus Down: ");

            mode_auto_xy(); //進(jìn)入自動(dòng)(連續(xù))X/Y軸坐標(biāo)轉(zhuǎn)換模式

            ADCCON |= ADC_START; //設(shè)置位[0]為1,啟動(dòng)A/D轉(zhuǎn)換

            }

            // 清INT_TC中斷

            ...

            }

            static void Isr_Adc(void)

            {

            printf("xdata = %4d, ydata = %4drn",(int)(ADCDAT0 & 0x3ff),(int)(ADCDAT1 & 0x3ff));

            //wait_down_int(); //進(jìn)入"等待中斷模式",等待觸摸屏被松開

            //清INT_ADC中斷

            ...

            }

            void AdcTsIntHandle(void)

            {

            if (SUBSRCPND & BIT_SUB_TC)

            Isr_Tc();

            if (SUBSRCPND & BIT_SUB_ADC)

            Isr_Adc();

            }

            /*

            *測(cè)試觸摸屏,打印觸點(diǎn)坐標(biāo)

            */

            void Test_Ts(void)

            {

            isr_handle_array[ISR_ADC_OFT] = AdcTsIntHandle; // 設(shè)置ADC中斷服務(wù)程序

            INTMSK &= ~BIT_ADC; //開啟ADC總中斷

            INTSUBMSK &= ~BIT_SUB_TC; //開啟INT_TC中斷,即觸摸屏被按下或松開時(shí)產(chǎn)生中斷

            INTSUBMSK &= ~BIT_SUB_ADC; //開啟INT_ADC中斷,即A/D轉(zhuǎn)換結(jié)束時(shí)產(chǎn)生中斷

            //使能預(yù)分頻功能,設(shè)置A/D轉(zhuǎn)換器的時(shí)鐘 = PCLK/(49+1)

            ADCCON = PRESCALE_EN | PRSCVL(49);

            /*

            *采樣延時(shí)時(shí)間 = (1/3.6864M)*50000 = 13.56ms

            *即按下觸摸屏后,再過13.56ms才采樣

            */

            ADCDLY = 50000;

            wait_down_int();/*進(jìn)入“等待中斷模式”,等待觸摸屏被按下*/

            printf("Touch the screem to test, press any key to exit!nr");

            getc();

            // 屏蔽ADC中斷

            ...

            }



          關(guān)鍵詞: ARM ADC

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();