×
模拟电路设计 > 详情

ARM开发步步深入之掌握ADC和触摸屏

发布时间:2020-06-29 发布时间:
|

实验目的:通过串口显示输入的电压值及采集按下触摸屏的(x,y)坐标值借此掌握S3C2410的ADC和触摸屏的使用。

实验环境及说明:恒颐S3C2410开发板H2410。H24X0E扩展板上AIN0~AIN1输出悬空,通过外接可变电阻电路采样电压值;外接的触摸屏接口实现扩展触摸屏完成相应操作本实验基于夏普3.5英寸LQ035Q7DB02。

实验思路:开发板上电启动后,自动将NandFlash开始的4K数据复制到SRAM中,然后跳转到0地址开始执行。关闭看门狗、初始化SDRAM及NandFlash控制器、设置MPLL来改变FCLK、HCLK、PCLK的值,设置堆栈,复制4KB后的16KB数据到SDRAM,之后进入main函数中进行ADC及触摸屏的测试。

知识掌握:ADC(模数转换器)和TouchScreen(触摸屏)。

★S3C2410ADC和TouchScreen概述:S3C2410内置1个8信道的10bit模数转换器,该ADC能以500KSPS的采样速率将外部的模拟信号转换为10位的二进制数字量。同时ADC部分能与CPU的触摸屏控制器协同工作,完成对触摸屏绝对地址的测量。ADC和TouchScreen共用一个A/D转换器,ADC可同时采样8路模拟输入信号,使用触摸屏时,AIN[7]、AIN[5]被用来测量XP/YP的电平,剩余的六个引脚可用来做一般ADC输入。2410ADC和触摸屏功能框图如下:

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

●ADC普通转换模式(NormalConversonMode)---普通转换模式(AUTO_PST=0,XY_PST=0)是用来进行一般的ADC转换之用的,例如通过ADC测量电池电压等等。

●独立X/Y轴坐标转换模式(SeparateX/YPositionConversionMode)---独立X/Y轴坐标转换模式其实包含了X轴模式和Y轴模式2种模式。首先进行X轴的坐标转换(AUTO_PST=0,XY_PST=1),X轴的转换资料会写到ADCDAT0寄存器的XPDAT中,等待转换完成后,触摸屏控制器会产生相应的中断。然后进行Y轴的坐标转换(AUTO_PST=0,XY_PST=2),Y轴的转换资料会写到ADCDAT1寄存器的YPDAT中,等待转换完成后,触摸屏控制器会产生相应的中断。

●自动X/Y轴坐标转换模式(AutoX/YPositionConversionMode)---自动X/Y轴坐标转换模式(AUTO_PST=1,XY_PST=0)将会自动地进行X轴和Y轴的转换操作,随后产生相应的中断。

●中断等待模式(WaitforInterruptMode)---在系统等待"PenDown",即触摸屏按下的时候,其实是处于中断等待模式。一旦被按下,实时产生"INT_TC"中断信号。每次发生此中断都,X轴和Y轴坐标转换资料都可以从相应的资料寄存器中读出。

●闲置模式(StandbyMode)---在该模式下转换资料寄存器中的值都被保留为上次转换时的资料。

★ADC两种启动方式:以手工启动和读结果时就自动地启动下一次转换;以查询状态位和发中断方式获知转换是否结束。ADC的操作只涉及3个寄存器:

●ADCCON---设置ADCCON寄存器,选择输入信号通道,设置A/D转换器的时钟(A/D时钟=PCLK/(PRSCVL+1))。A/D时钟最大为2.5MHz,且应小于PCLK的1/5;设置ADCCON寄存器,启动转换(设置READ_START位则读转换数据(读ADCDAT0寄存器)时即启动下一次转换;否则可通过设置ENABLE_START位来启动A/D转换);ADCCON各位含义(ENABLE_START---置1启动ADC转换,置0无操作;RESR_START---置1允许读操作启动ADC转换,置0禁止读操作启动ADC转换;STDBM---置1将ADC置为闲置状态(模式),置0将ADC置为正常操作状态;SEL_MUX---选择需要进行转换的ADC信道;PRSCV---ADC转换时钟预分频参数;PRSCEN---ADC转换时钟使能;ECFLG---ADC转换完成标志位(只读)。为1ADC转换结束,为0ADC转换进行中)。

●ADCTSC---设置ADCTSC寄存器,使用设为普通转换模式,不使用触摸屏功能;ADCTSC各位含义(XY_PST---对X/Y轴手动测量模式进行选择;AUTO_PST---X/Y轴的自动转换模式使能位;PULL_UP---XP端的上拉电阻使能位;XP_SEN---设置nXPON输出状态;XM_SEN---设置XMON输出状态;YP_SEN---设置nYPON输出状态;YM_SEN---设置YMON输出状态)。

●ADCDAT0---完成ADC转换后,读取ADCDAT0寄存器获得数值(如果使用查询方式,则可不断读取ADCCON寄存器的ECFLG位来确定是否转换结束;否则可以使用INT_ADC中断,发生INT_ADC中断时表示转换结束);ADCDAT0各位含义(XPDATA---X轴转换资料寄存器;XY_PST---选择X/Y轴自动转换模式;AUTO_PST---X/Y轴自动转换使能位;UPDOWN---选择中断等待模式的类型。为0按下产生中断,为1释放产生中断)。

★触摸屏操作还涉及到以下两个寄存器:

●ADCDLY---ADC转换周期等待定时器。

●ADCDAT1---同ADCDAT0。

关键代码解析:

★head.S头文件来初始化,设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行

.equMEM_CTL_BASE,0x48000000

.text

.global_start

_start:

@中断向量表处理函数,只给出复位和普通中断模式的处理函数,其它异常未使用

bReset

...

bHandleIRQ

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

HandleFIQ:

bHandleFIQ

Reset:@复位处理

bldisable_watch_dog@关门喂狗

blmem_control_setup@设置存储控制器

ldrsp,=4096@设置栈指针,以下C函数调用前需要设好栈

blinit_clock@设置MPLL,改变FCLK、HCLK、PCLK

blinit_nand@初始化NandFlash

@将NandFlash中地址4096开始的代码复制到SDRAM中

ldrr0,=0x30000000@目标地址=0x30000000,SDRAM起始地址

movr1,#4096@源地址=4096,连接时代码在4096开始处

movr2,#16*1024@复制长度=16K,对于本实验足够

blread_nand@调用C函数read_nand

blclean_bss@清除bss段

msrcpsr_c,#0xd2@进入中断模式

ldrsp,=0x31000000@设置中断模式栈指针

msrcpsr_c,#0xdf@进入系统模式

ldrsp,=0x34000000@设置系统模式栈指针

ldrlr,=ret_initirq@设置返回地址

ldrpc,=init_irq@初始化中断

ret_initirq:

msrcpsr_c,#0x5f@设置I-bit=0,开IRQ中断

ldrlr,=halt_loop@设置返回地址

ldrpc,=main@调用main函数

halt_loop:

bhalt_loop

★main.c文件实现实现串口选择ADC和TouchScreen操作,主要代码:

#include

#include

#include

intmain()

{

charc;

init_uart0();//波特率115200,8N1(8个数据位,无校验位,1个停止位)

while(1)

{

printf("\r\n~~~~~~TestADCandTouchScreem~~~~~~\r\n");

printf("[A]TestADC\n\r");

printf("[T]TestTouchScreem\n\r");

printf("Enteryourselection:");

c=getc();

putc(c);

switch(c)

{

case'a':

case'A':

{

Test_Adc();//操作ADC

break;

}

case't':

case'T':

{

Test_Ts();//操作TouchScreen

break;

...

}

★adc_ts.cADC和触摸屏的测试函数,主要代码:

...

/*

*使用查询方式读取A/D转换值。

*输入参数ch:模拟信号通道,取值为0~7

*/

staticintReadAdc(intch)

{

//选择模拟通道,使能预分频功能,设置A/D转换器的时钟=PCLK/(49+1)

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

//清除位[2],设为普通转换模式

ADCTSC&=~(1<<2);

//设置位[0]为1,启动A/D转换

ADCCON|=ADC_START;

//当A/D转换真正开始时,位[0]会自动清0

while(ADCCON&ADC_START);

//检测位[15],当它为1时表示转换结束

while(!(ADCCON&ADC_ENDCVT));

//读取数据

return(ADCDAT0&0x3ff);

}

/*

*测试ADC。通过A/D转换,测量可变电阻器的电压值

*/

voidTest_Adc(void)

{

intvol0,vol1;

printf("MeasuringthevoltageofAIN0andAIN1,pressanykeytoexit\n\r");

while(!awaitkey(0))//串口无输入,则不断测试

{

vol0=(ReadAdc(0)*3)/1024;//计算电压值

vol1=(ReadAdc(1)*3)/1024;//计算电压值

printf("AIN0=%dAIN1=%d\r",vol0,vol1);

}

printf("\n");

}

staticvoidIsr_Tc(void)

{

if(ADCDAT0&0x8000)//ADCDAT0[15]为1表示触摸屏被松开

{

printf("\r\nStylusUp!!\n\r");

//wait_down_int();//进入"等待中断模式",等待触摸屏被按下

}

else

{

printf("\r\nStylusDown:");

mode_auto_xy();//进入自动(连续)X/Y轴坐标转换模式

ADCCON|=ADC_START;//设置位[0]为1,启动A/D转换

}

//清INT_TC中断

...

}

staticvoidIsr_Adc(void)

{

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

//wait_down_int();//进入"等待中断模式",等待触摸屏被松开

//清INT_ADC中断

...

}

voidAdcTsIntHandle(void)

{

if(SUBSRCPND&BIT_SUB_TC)

Isr_Tc();

if(SUBSRCPND&BIT_SUB_ADC)

Isr_Adc();

}

/*

*测试触摸屏,打印触点坐标

*/

voidTest_Ts(void)

{

isr_handle_array[ISR_ADC_OFT]=AdcTsIntHandle;//设置ADC中断服务程序

INTMSK&=~BIT_ADC;//开启ADC总中断

INTSUBMSK&=~BIT_SUB_TC;//开启INT_TC中断,即触摸屏被按下或松开时产生中断

INTSUBMSK&=~BIT_SUB_ADC;//开启INT_ADC中断,即A/D转换结束时产生中断

//使能预分频功能,设置A/D转换器的时钟=PCLK/(49+1)

ADCCON=PRESCALE_EN|PRSCVL(49);

/*

*采样延时时间=(1/3.6864M)*50000=13.56ms

*即按下触摸屏后,再过13.56ms才采样

*/

ADCDLY=50000;

wait_down_int();/*进入“等待中断模式”,等待触摸屏被按下*/

printf("Touchthescreemtotest,pressanykeytoexit!\n\r");

getc();

//屏蔽ADC中断

...

}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
晶体管的工作状态判断和工作条件