您的位置 首页 主动

ARM9 S3C2440—ADC和触摸屏操控详解

S3C2440芯片内部共有8路AD转换通道,AIN0-AIN7,转换器只有一个,转换精度为10位,最大转换率为25MHzAD转换器时钟下的500KSPS。AD转换

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的装备流程如下:

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_FREQ1;//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_FREQ1;//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++);

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/zhudong/255765.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部