新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM9S3C2440—ADC和觸摸屏控制詳解

        ARM9S3C2440—ADC和觸摸屏控制詳解

        作者: 時間:2016-11-26 來源:網絡 收藏
        S3C2440芯片內部共有8路A/D轉換通道,AIN0-AIN7,轉換器只有一個,轉換精度為10位,最大轉換率為2.5MHzA/D轉換器時鐘下的500KSPS。A/D轉換器支持片上采樣-保持功能和掉電模式的操作。在常見的設計中,一般AIN4,AIN5,AIN6,AIN7被用作四線電阻觸摸屏的YM、YP、XM、XP通道,剩余的AIN0~AIN3被引出,其中AI0外接一個可調電阻。

        ADC的配置流程如下:

        本文引用地址:http://www.104case.com/article/201611/321746.htm

        1、ADCDLY(P446)

        rADCDLY=50000;//Normalconversionmodedelayabout(1/3.6864M)*50000=13.56ms

        2、ADCCON(P444)的設置,選擇轉換通道和設置轉換頻率

        ADCCON[0],AD轉換開始有效,1轉換開始且該位在轉換開始后變為0,通過這個特點可以判斷是否開始轉換。什么意思呢,設為1只是認為地讓它轉換開始,但是未必開始轉換,還必須通過while循環查詢方式判斷該位是否變為0,變為0表示轉換開始。

        ADCCON[1],AD轉換通過讀取有效,1通過讀取操作有效;ADCCON[2],備用操作模式選擇,0普通操作模式,1,備用操作模式;

        ADCCON[5:3]:轉換通道選擇;

        000=AIN0

        001=AIN1

        010=AIN2

        011=AIN3

        100=YM

        101=YP

        110=XM

        111=XP

        ADCCON[13:6],AD轉換器預分頻器值0~255,ADC頻率應該小于PCLK的1/5;

        ADCCON[14],AD轉換器預分頻器使能,1使能;

        ADCCON[15],AD轉換結束標志,0:轉化過程中,1:轉換結束;

        ADC初始化程序示例如下:

        #defineADC_FREQ2500000//希望的ADC轉換頻率

        volatileU32preScaler;

        volatileU32adc_value=0;//在程序開始處聲明

        voidadc_init(void)

        {

        //選擇輸入通道,AIN0,對應開發板上W1可調電阻

        intchannel=0;

        preScaler=ADC_FREQ;

        preScaler=50000000/ADC_FREQ-1;//PCLK=50M

        rADCCON=(1<<14)"(preScaler<<6)|(channel<<3);//setupchannel

        delay(1000);

        }

        3、ADCDAT0(ADCDAT1)P447,讀取轉換值

        ADCDAT0[9:0],X坐標轉換結果值,包括普通模ADC轉換結果值;

        (ADCDAT1[9:0],Y坐標轉換結果;)

        ADC轉換程序示例,通過輪詢方式

        voidMain(void)

        {

        Set_Clk();

        adc_init();

        while(1)

        {

        adc_value=ReadAdc(0);

        delay(1000);

        }

        }

        intReadAdc(intchannel)

        {

        rADCCON|=0x01;//startADC

        while(rADCCON&0x1);//checkifEnable_startislow

        while(!(rADCCON&0x8000));//checkifEC(EndofConversion)flagishigh

        return((int)rADCDAT0&0x3ff);

        }

        ADC通過中斷方式讀取轉換值

        注意ADC的中斷有兩個子中斷,INT_ADC_S和INT_TC需要先處理一下子中斷INT_ADC_S,再處理INT_ADC。

        voidadc_init(void)

        {

        intchannel=0;/選擇輸入通道,AIN0,對應開發板上W1可調電阻

        preScaler=ADC_FREQ;//設置分頻時鐘

        preScaler=50000000/ADC_FREQ-1;//PCLK=50M

        rADCCON=(1<<14)|(preScaler<<6)|(channel<<3);

        ClearSubPending(BIT_SUB_ADC);//清子中斷處理寄存器ClearPending(BIT_ADC);//清中斷處理寄存器

        pISR_ADC=(U32)adc_ISR;

        EnableSubIrq(BIT_SUB_ADC);//開AD子中斷
        EnableIrq(BIT_ADC);//開AD中斷

        delay(1000);
        }

        void__irqadc_ISR(void)
        {
        intadc_value;//adc_value應該設為全局變量,這里放這里以便分析
        ClearSubPending(BIT_SUB_ADC);//清子中斷處理寄存器ClearPending(BIT_ADC);//清中斷處理寄存器

        adc_value=(int)rADCDAT0&0x3ff;
        }
        觸摸屏工作流程以及程序設計流程:

        一、觸摸屏初始化:
        1、ADCTSC設置(P445),

        [1:0]:11設置觸摸屏接口為中斷等待模式,等待觸摸筆按下

        [2]:0ADC普通轉換模式,1自動連續測量X坐標和Y坐標

        [3]:0XP上拉有效,1XP上拉無效


        2、ClearSubPending(BIT_SUB_ADC);//清子中斷處理寄存器ClearPending(BIT_ADC);//清中斷處理寄存器

        ClearSubPending(BIT_SUB_TC);

        清除源掛起寄存器(SRCPND)、中斷掛起寄存器(INTPND)、子源掛起寄存器(SUBSRCPND)。注意有兩個中斷,觸摸屏中斷:當觸摸筆按下或抬起產生的中斷,ADC中斷:觸摸屏坐標AD轉換結束產生的中斷。
        3、EnableSubIrq(BIT_SUB_ADC);//開AD子中斷
        EnableIrq(BIT_ADC);//開AD中斷

        EnableSubIrq(BIT_SUB_TC);//開AD子中斷TC

        關中斷屏蔽寄存器和子中斷屏蔽寄存器(INTMSK,INTSUBMSK)。4、pISR_ADC=(U32)AdcTsAuto;

        程序入口函數,中斷模式和中斷優先級默認即可。
        二、觸摸屏中斷服務子程序:
        一)觸摸筆按下中斷
        4、如果中斷發生,設置x,y坐標為自動轉換模式

        rADCTSC=(1<<3)|(1<<2);

        [2]:0ADC普通轉換模式,1自動連續測量X坐標和Y坐標

        [3]:0XP上拉有效,1XP上拉無效
        5、啟動AD轉換,然后檢測AD轉換是否啟動

        rADCCON|=0x1;//startADC

        while(rADCCON&0x1);//checkifEnable_startislow
        6、檢測AD轉換是否結束,若結束,獲取x,y坐標的值

        通過輪詢方式,也可以是中斷方式判斷轉換結束。

        while(!(rADCCON&0x8000));//checkifEC(EndofConversion)flagishigh,Thislineisnecessary~!!

        while(!(rSRCPND&0x80000000));//checkifADCisfinishedwithinterruptbit

        xdata=(rADCDAT0&0x3ff);

        ydata=(rADCDAT1&0x3ff);
        7、對幾個寄存器寫1清零,防止反復發生中斷(這里的中斷是筆尖按下中斷)
        ClearSubPending(BIT_SUB_TC);

        ClearPending(BIT_ADC);

        /rSRCPND=0x80000000;rINTPND=0x80000000;也可以

        8、再次允許中斷

        允許觸摸筆被彈起的中斷

        EnableSubIrq(BIT_SUB_TC);

        EnableIrq(BIT_ADC);//rINTMSK=0x7fffffff;

        二)觸摸筆抬起中斷
        9、設置觸摸屏即可為等待中斷模式,等待觸摸筆抬起(ADCTSC,關鍵是要設置觸摸筆抬起中斷信號)

        rADCTSC=0xd3;//Waitingforinterrupt

        rADCTSC=rADCTSC|(1<<8);//Detectstylusupinterruptsignal.
        10、如果發生中斷,不做任何操作,只打印出一句觸摸筆抬起中斷信息

        while(1)//tocheckPen-upstate

        {

        if(rSUBSRCPND&(BIT_SUB_TC))//checkifADCisfinishedwithinterruptbit

        {

        Uart_Printf("StylusUpInterrupt~!");

        break;//ifStylusisup(1)state

        }

        }

        Uart_Printf("count=dXP=d,YP=d",count++,xdata,ydata);
        11、觸摸筆抬起之后,把得到的x,y坐標值發送給PC機,顯示出具體數值
        三)再次設置觸摸屏為等待中斷模式,等待下次觸摸屏被按下

        rADCTSC=0xd3;//Waitingforinterrupt

        ClearSubPending(BIT_SUB_TC);

        ClearPending(BIT_ADC);

        EnableSubIrq(BIT_SUB_TC);

        EnableIrq(BIT_ADC);

        示例程序如下:

        #defineGLOBAL_CLK1

        #include

        #include

        #include"def.h"

        #include"option.h"

        #include"2440addr.h"

        #include"2440lib.h"

        #include"2440slib.h"

        #include"mmu.h"

        #include"profile.h"

        #include"memtest.h"

        #defineADC_FREQ2500000

        intcount=0;

        volatileU32preScaler;

        intxdata,ydata;

        voidTest_Touchpanel(void);

        staticvoid__irqAdcTsAuto(void);

        staticvoidcal_cpu_bus_clk(void);

        voidSet_Clk(void);

        voiddelay(inttimes)

        {

        inti,j;

        for(i=0;i

        for(j=0;j<400;j++);

        }

        intMain(void)

        {

        intScom=0;

        Set_Clk();

        Uart_Init(0,115200);

        Uart_Select(Scom);

        Test_Touchpanel();

        while(1);

        return0;

        }


        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 桃江县| 睢宁县| 保山市| 普兰县| 罗城| 芜湖县| 织金县| 阿拉善右旗| 吴桥县| 建宁县| 陆川县| 长顺县| 玛沁县| 阿瓦提县| 额济纳旗| 旌德县| 漳平市| 准格尔旗| 肥西县| 桃园市| 怀安县| 游戏| 蒙自县| 沅江市| 安平县| 扎囊县| 英山县| 柏乡县| 武胜县| 葫芦岛市| 工布江达县| 始兴县| 尚志市| 城固县| 东海县| 兴义市| 鄯善县| 手游| 孟连| 辽源市| 游戏|